blob: 0687decc374d11da0182e654988b2b5c4bf7d16c [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Abhishek Singhb3e376c2017-01-04 15:27:13 +05302 * Copyright (c) 2012-2017 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"
Sushant Kaushik084f6592015-09-10 13:11:56 +053098#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +053099#include "wlan_logging_sock_svc.h"
Agrawal Ashishcfe83282016-09-29 13:03:45 +0530100#include "wlan_hdd_misc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530101
Jeff Johnson295189b2012-06-20 16:38:30 -0700102
103#define g_mode_rates_size (12)
104#define a_mode_rates_size (8)
105#define FREQ_BASE_80211G (2407)
106#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700107#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530108#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800110 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700111
112#define HDD2GHZCHAN(freq, chan, flag) { \
113 .band = IEEE80211_BAND_2GHZ, \
114 .center_freq = (freq), \
115 .hw_value = (chan),\
116 .flags = (flag), \
117 .max_antenna_gain = 0 ,\
118 .max_power = 30, \
119}
120
121#define HDD5GHZCHAN(freq, chan, flag) { \
122 .band = IEEE80211_BAND_5GHZ, \
123 .center_freq = (freq), \
124 .hw_value = (chan),\
125 .flags = (flag), \
126 .max_antenna_gain = 0 ,\
127 .max_power = 30, \
128}
129
130#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
131{\
132 .bitrate = rate, \
133 .hw_value = rate_id, \
134 .flags = flag, \
135}
136
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530137#ifdef WLAN_FEATURE_VOWIFI_11R
138#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
139#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
140#endif
141
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530142#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530143#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530144
Sunil Duttc69bccb2014-05-26 21:30:20 +0530145#ifdef WLAN_FEATURE_LINK_LAYER_STATS
146/*
147 * Used to allocate the size of 4096 for the link layer stats.
148 * The size of 4096 is considered assuming that all data per
149 * respective event fit with in the limit.Please take a call
150 * on the limit based on the data requirements on link layer
151 * statistics.
152 */
153#define LL_STATS_EVENT_BUF_SIZE 4096
154#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530155#ifdef WLAN_FEATURE_EXTSCAN
156/*
157 * Used to allocate the size of 4096 for the EXTScan NL data.
158 * The size of 4096 is considered assuming that all data per
159 * respective event fit with in the limit.Please take a call
160 * on the limit based on the data requirements.
161 */
162
163#define EXTSCAN_EVENT_BUF_SIZE 4096
164#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
165#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530166
Atul Mittal115287b2014-07-08 13:26:33 +0530167/*EXT TDLS*/
168/*
169 * Used to allocate the size of 4096 for the TDLS.
170 * The size of 4096 is considered assuming that all data per
171 * respective event fit with in the limit.Please take a call
172 * on the limit based on the data requirements on link layer
173 * statistics.
174 */
175#define EXTTDLS_EVENT_BUF_SIZE 4096
176
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530177/*
178 * Values for Mac spoofing feature
179 *
180 */
181#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
182#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
183#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530184#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
185
Anurag Chouhan343af7e2016-12-16 13:11:19 +0530186/*
187 * max_sched_scan_plans defined to 10
188 */
189#define MAX_SCHED_SCAN_PLANS 10
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530190
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530191static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700192{
193 WLAN_CIPHER_SUITE_WEP40,
194 WLAN_CIPHER_SUITE_WEP104,
195 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800196#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700197#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
198 WLAN_CIPHER_SUITE_KRK,
199 WLAN_CIPHER_SUITE_CCMP,
200#else
201 WLAN_CIPHER_SUITE_CCMP,
202#endif
203#ifdef FEATURE_WLAN_WAPI
204 WLAN_CIPHER_SUITE_SMS4,
205#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700206#ifdef WLAN_FEATURE_11W
207 WLAN_CIPHER_SUITE_AES_CMAC,
208#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700209};
210
211static inline int is_broadcast_ether_addr(const u8 *addr)
212{
213 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
214 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
215}
216
Agrawal Ashish97dec502015-11-26 20:20:58 +0530217const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530218{
Jeff Johnson295189b2012-06-20 16:38:30 -0700219 HDD2GHZCHAN(2412, 1, 0) ,
220 HDD2GHZCHAN(2417, 2, 0) ,
221 HDD2GHZCHAN(2422, 3, 0) ,
222 HDD2GHZCHAN(2427, 4, 0) ,
223 HDD2GHZCHAN(2432, 5, 0) ,
224 HDD2GHZCHAN(2437, 6, 0) ,
225 HDD2GHZCHAN(2442, 7, 0) ,
226 HDD2GHZCHAN(2447, 8, 0) ,
227 HDD2GHZCHAN(2452, 9, 0) ,
228 HDD2GHZCHAN(2457, 10, 0) ,
229 HDD2GHZCHAN(2462, 11, 0) ,
230 HDD2GHZCHAN(2467, 12, 0) ,
231 HDD2GHZCHAN(2472, 13, 0) ,
232 HDD2GHZCHAN(2484, 14, 0) ,
233};
234
Agrawal Ashish97dec502015-11-26 20:20:58 +0530235const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700236{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700237 HDD5GHZCHAN(4920, 240, 0) ,
238 HDD5GHZCHAN(4940, 244, 0) ,
239 HDD5GHZCHAN(4960, 248, 0) ,
240 HDD5GHZCHAN(4980, 252, 0) ,
241 HDD5GHZCHAN(5040, 208, 0) ,
242 HDD5GHZCHAN(5060, 212, 0) ,
243 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700244 HDD5GHZCHAN(5180, 36, 0) ,
245 HDD5GHZCHAN(5200, 40, 0) ,
246 HDD5GHZCHAN(5220, 44, 0) ,
247 HDD5GHZCHAN(5240, 48, 0) ,
248 HDD5GHZCHAN(5260, 52, 0) ,
249 HDD5GHZCHAN(5280, 56, 0) ,
250 HDD5GHZCHAN(5300, 60, 0) ,
251 HDD5GHZCHAN(5320, 64, 0) ,
252 HDD5GHZCHAN(5500,100, 0) ,
253 HDD5GHZCHAN(5520,104, 0) ,
254 HDD5GHZCHAN(5540,108, 0) ,
255 HDD5GHZCHAN(5560,112, 0) ,
256 HDD5GHZCHAN(5580,116, 0) ,
257 HDD5GHZCHAN(5600,120, 0) ,
258 HDD5GHZCHAN(5620,124, 0) ,
259 HDD5GHZCHAN(5640,128, 0) ,
260 HDD5GHZCHAN(5660,132, 0) ,
261 HDD5GHZCHAN(5680,136, 0) ,
262 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800263#ifdef FEATURE_WLAN_CH144
264 HDD5GHZCHAN(5720,144, 0) ,
265#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700266 HDD5GHZCHAN(5745,149, 0) ,
267 HDD5GHZCHAN(5765,153, 0) ,
268 HDD5GHZCHAN(5785,157, 0) ,
269 HDD5GHZCHAN(5805,161, 0) ,
270 HDD5GHZCHAN(5825,165, 0) ,
271};
272
273static struct ieee80211_rate g_mode_rates[] =
274{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530275 HDD_G_MODE_RATETAB(10, 0x1, 0),
276 HDD_G_MODE_RATETAB(20, 0x2, 0),
277 HDD_G_MODE_RATETAB(55, 0x4, 0),
278 HDD_G_MODE_RATETAB(110, 0x8, 0),
279 HDD_G_MODE_RATETAB(60, 0x10, 0),
280 HDD_G_MODE_RATETAB(90, 0x20, 0),
281 HDD_G_MODE_RATETAB(120, 0x40, 0),
282 HDD_G_MODE_RATETAB(180, 0x80, 0),
283 HDD_G_MODE_RATETAB(240, 0x100, 0),
284 HDD_G_MODE_RATETAB(360, 0x200, 0),
285 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700286 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530287};
Jeff Johnson295189b2012-06-20 16:38:30 -0700288
289static struct ieee80211_rate a_mode_rates[] =
290{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530291 HDD_G_MODE_RATETAB(60, 0x10, 0),
292 HDD_G_MODE_RATETAB(90, 0x20, 0),
293 HDD_G_MODE_RATETAB(120, 0x40, 0),
294 HDD_G_MODE_RATETAB(180, 0x80, 0),
295 HDD_G_MODE_RATETAB(240, 0x100, 0),
296 HDD_G_MODE_RATETAB(360, 0x200, 0),
297 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 HDD_G_MODE_RATETAB(540, 0x800, 0),
299};
300
301static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
302{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530303 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700304 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
305 .band = IEEE80211_BAND_2GHZ,
306 .bitrates = g_mode_rates,
307 .n_bitrates = g_mode_rates_size,
308 .ht_cap.ht_supported = 1,
309 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
310 | IEEE80211_HT_CAP_GRN_FLD
311 | IEEE80211_HT_CAP_DSSSCCK40
312 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
313 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
314 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
315 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
316 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
317 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
318};
319
Jeff Johnson295189b2012-06-20 16:38:30 -0700320static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
321{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530322 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
324 .band = IEEE80211_BAND_5GHZ,
325 .bitrates = a_mode_rates,
326 .n_bitrates = a_mode_rates_size,
327 .ht_cap.ht_supported = 1,
328 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
329 | IEEE80211_HT_CAP_GRN_FLD
330 | IEEE80211_HT_CAP_DSSSCCK40
331 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
332 | IEEE80211_HT_CAP_SGI_40
333 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
334 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
335 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
336 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
337 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
338 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
339};
340
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530341/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700342 TX/RX direction for each kind of interface */
343static const struct ieee80211_txrx_stypes
344wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
345 [NL80211_IFTYPE_STATION] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ACTION) |
348 BIT(SIR_MAC_MGMT_PROBE_REQ),
349 },
350 [NL80211_IFTYPE_AP] = {
351 .tx = 0xffff,
352 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
353 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
354 BIT(SIR_MAC_MGMT_PROBE_REQ) |
355 BIT(SIR_MAC_MGMT_DISASSOC) |
356 BIT(SIR_MAC_MGMT_AUTH) |
357 BIT(SIR_MAC_MGMT_DEAUTH) |
358 BIT(SIR_MAC_MGMT_ACTION),
359 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700360 [NL80211_IFTYPE_ADHOC] = {
361 .tx = 0xffff,
362 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
363 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
364 BIT(SIR_MAC_MGMT_PROBE_REQ) |
365 BIT(SIR_MAC_MGMT_DISASSOC) |
366 BIT(SIR_MAC_MGMT_AUTH) |
367 BIT(SIR_MAC_MGMT_DEAUTH) |
368 BIT(SIR_MAC_MGMT_ACTION),
369 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700370 [NL80211_IFTYPE_P2P_CLIENT] = {
371 .tx = 0xffff,
372 .rx = BIT(SIR_MAC_MGMT_ACTION) |
373 BIT(SIR_MAC_MGMT_PROBE_REQ),
374 },
375 [NL80211_IFTYPE_P2P_GO] = {
376 /* This is also same as for SoftAP */
377 .tx = 0xffff,
378 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
379 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
380 BIT(SIR_MAC_MGMT_PROBE_REQ) |
381 BIT(SIR_MAC_MGMT_DISASSOC) |
382 BIT(SIR_MAC_MGMT_AUTH) |
383 BIT(SIR_MAC_MGMT_DEAUTH) |
384 BIT(SIR_MAC_MGMT_ACTION),
385 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700386};
387
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800388#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800389static const struct ieee80211_iface_limit
390wlan_hdd_iface_limit[] = {
391 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800392 /* max = 3 ; Our driver create two interfaces during driver init
393 * wlan0 and p2p0 interfaces. p2p0 is considered as station
394 * interface until a group is formed. In JB architecture, once the
395 * group is formed, interface type of p2p0 is changed to P2P GO or
396 * Client.
397 * When supplicant remove the group, it first issue a set interface
398 * cmd to change the mode back to Station. In JB this works fine as
399 * we advertize two station type interface during driver init.
400 * Some vendors create separate interface for P2P GO/Client,
401 * after group formation(Third one). But while group remove
402 * supplicant first tries to change the mode(3rd interface) to STATION
403 * But as we advertized only two sta type interfaces nl80211 was
404 * returning error for the third one which was leading to failure in
405 * delete interface. Ideally while removing the group, supplicant
406 * should not try to change the 3rd interface mode to Station type.
407 * Till we get a fix in wpa_supplicant, we advertize max STA
408 * interface type to 3
409 */
410 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 .types = BIT(NL80211_IFTYPE_STATION),
412 },
413 {
414 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700415 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800416 },
417 {
418 .max = 1,
419 .types = BIT(NL80211_IFTYPE_P2P_GO) |
420 BIT(NL80211_IFTYPE_P2P_CLIENT),
421 },
422};
423
424/* By default, only single channel concurrency is allowed */
425static struct ieee80211_iface_combination
426wlan_hdd_iface_combination = {
427 .limits = wlan_hdd_iface_limit,
428 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800429 /*
430 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
431 * and p2p0 interfaces during driver init
432 * Some vendors create separate interface for P2P operations.
433 * wlan0: STA interface
434 * p2p0: P2P Device interface, action frames goes
435 * through this interface.
436 * p2p-xx: P2P interface, After GO negotiation this interface is
437 * created for p2p operations(GO/CLIENT interface).
438 */
439 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800440 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
441 .beacon_int_infra_match = false,
442};
443#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800444
Jeff Johnson295189b2012-06-20 16:38:30 -0700445static struct cfg80211_ops wlan_hdd_cfg80211_ops;
446
447/* Data rate 100KBPS based on IE Index */
448struct index_data_rate_type
449{
450 v_U8_t beacon_rate_index;
451 v_U16_t supported_rate[4];
452};
453
454/* 11B, 11G Rate table include Basic rate and Extended rate
455 The IDX field is the rate index
456 The HI field is the rate when RSSI is strong or being ignored
457 (in this case we report actual rate)
458 The MID field is the rate when RSSI is moderate
459 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
460 The LO field is the rate when RSSI is low
461 (in this case we don't report rates, actual current rate used)
462 */
463static const struct
464{
465 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700466 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700467} supported_data_rate[] =
468{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700469/* IDX HI HM LM LO (RSSI-based index */
470 {2, { 10, 10, 10, 0}},
471 {4, { 20, 20, 10, 0}},
472 {11, { 55, 20, 10, 0}},
473 {12, { 60, 55, 20, 0}},
474 {18, { 90, 55, 20, 0}},
475 {22, {110, 55, 20, 0}},
476 {24, {120, 90, 60, 0}},
477 {36, {180, 120, 60, 0}},
478 {44, {220, 180, 60, 0}},
479 {48, {240, 180, 90, 0}},
480 {66, {330, 180, 90, 0}},
481 {72, {360, 240, 90, 0}},
482 {96, {480, 240, 120, 0}},
483 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700484};
485
486/* MCS Based rate table */
487static struct index_data_rate_type supported_mcs_rate[] =
488{
489/* MCS L20 L40 S20 S40 */
490 {0, {65, 135, 72, 150}},
491 {1, {130, 270, 144, 300}},
492 {2, {195, 405, 217, 450}},
493 {3, {260, 540, 289, 600}},
494 {4, {390, 810, 433, 900}},
495 {5, {520, 1080, 578, 1200}},
496 {6, {585, 1215, 650, 1350}},
497 {7, {650, 1350, 722, 1500}}
498};
499
Leo Chang6f8870f2013-03-26 18:11:36 -0700500#ifdef WLAN_FEATURE_11AC
501
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530502#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700503
504struct index_vht_data_rate_type
505{
506 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530507 v_U16_t supported_VHT80_rate[2];
508 v_U16_t supported_VHT40_rate[2];
509 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700510};
511
512typedef enum
513{
514 DATA_RATE_11AC_MAX_MCS_7,
515 DATA_RATE_11AC_MAX_MCS_8,
516 DATA_RATE_11AC_MAX_MCS_9,
517 DATA_RATE_11AC_MAX_MCS_NA
518} eDataRate11ACMaxMcs;
519
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530520/* SSID broadcast type */
521typedef enum eSSIDBcastType
522{
523 eBCAST_UNKNOWN = 0,
524 eBCAST_NORMAL = 1,
525 eBCAST_HIDDEN = 2,
526} tSSIDBcastType;
527
Leo Chang6f8870f2013-03-26 18:11:36 -0700528/* MCS Based VHT rate table */
529static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
530{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530531/* MCS L80 S80 L40 S40 L20 S40*/
532 {0, {293, 325}, {135, 150}, {65, 72}},
533 {1, {585, 650}, {270, 300}, {130, 144}},
534 {2, {878, 975}, {405, 450}, {195, 217}},
535 {3, {1170, 1300}, {540, 600}, {260, 289}},
536 {4, {1755, 1950}, {810, 900}, {390, 433}},
537 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
538 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
539 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
540 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
541 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700542};
543#endif /* WLAN_FEATURE_11AC */
544
c_hpothu79aab322014-07-14 21:11:01 +0530545/*array index points to MCS and array value points respective rssi*/
546static int rssiMcsTbl[][10] =
547{
548/*MCS 0 1 2 3 4 5 6 7 8 9*/
549 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
550 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
551 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
552};
553
Jeff Johnson295189b2012-06-20 16:38:30 -0700554extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530555#ifdef FEATURE_WLAN_SCAN_PNO
556static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
557#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700558
Leo Chang9056f462013-08-01 19:21:11 -0700559#ifdef WLAN_NL80211_TESTMODE
560enum wlan_hdd_tm_attr
561{
562 WLAN_HDD_TM_ATTR_INVALID = 0,
563 WLAN_HDD_TM_ATTR_CMD = 1,
564 WLAN_HDD_TM_ATTR_DATA = 2,
565 WLAN_HDD_TM_ATTR_TYPE = 3,
566 /* keep last */
567 WLAN_HDD_TM_ATTR_AFTER_LAST,
568 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
569};
570
571enum wlan_hdd_tm_cmd
572{
573 WLAN_HDD_TM_CMD_WLAN_HB = 1,
574};
575
576#define WLAN_HDD_TM_DATA_MAX_LEN 5000
577
578static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
579{
580 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
581 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
582 .len = WLAN_HDD_TM_DATA_MAX_LEN },
583};
584#endif /* WLAN_NL80211_TESTMODE */
585
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800586#ifdef FEATURE_WLAN_CH_AVOID
587/*
588 * FUNCTION: wlan_hdd_send_avoid_freq_event
589 * This is called when wlan driver needs to send vendor specific
590 * avoid frequency range event to userspace
591 */
592int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
593 tHddAvoidFreqList *pAvoidFreqList)
594{
595 struct sk_buff *vendor_event;
596
597 ENTER();
598
599 if (!pHddCtx)
600 {
601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
602 "%s: HDD context is null", __func__);
603 return -1;
604 }
605
606 if (!pAvoidFreqList)
607 {
608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
609 "%s: pAvoidFreqList is null", __func__);
610 return -1;
611 }
612
613 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530614#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
615 NULL,
616#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800617 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530618 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800619 GFP_KERNEL);
620 if (!vendor_event)
621 {
622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
623 "%s: cfg80211_vendor_event_alloc failed", __func__);
624 return -1;
625 }
626
627 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
628 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
629
630 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
631
632 EXIT();
633 return 0;
634}
635#endif /* FEATURE_WLAN_CH_AVOID */
636
Srinivas Dasari030bad32015-02-18 23:23:54 +0530637/*
638 * FUNCTION: __wlan_hdd_cfg80211_nan_request
639 * This is called when wlan driver needs to send vendor specific
640 * nan request event.
641 */
642static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
643 struct wireless_dev *wdev,
644 const void *data, int data_len)
645{
646 tNanRequestReq nan_req;
647 VOS_STATUS status;
648 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530649 struct net_device *dev = wdev->netdev;
650 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
651 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530652 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
653
654 if (0 == data_len)
655 {
656 hddLog(VOS_TRACE_LEVEL_ERROR,
657 FL("NAN - Invalid Request, length = 0"));
658 return ret_val;
659 }
660
661 if (NULL == data)
662 {
663 hddLog(VOS_TRACE_LEVEL_ERROR,
664 FL("NAN - Invalid Request, data is NULL"));
665 return ret_val;
666 }
667
668 status = wlan_hdd_validate_context(pHddCtx);
669 if (0 != status)
670 {
671 hddLog(VOS_TRACE_LEVEL_ERROR,
672 FL("HDD context is not valid"));
673 return -EINVAL;
674 }
675
676 hddLog(LOG1, FL("Received NAN command"));
677 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
678 (tANI_U8 *)data, data_len);
679
680 /* check the NAN Capability */
681 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
682 {
683 hddLog(VOS_TRACE_LEVEL_ERROR,
684 FL("NAN is not supported by Firmware"));
685 return -EINVAL;
686 }
687
688 nan_req.request_data_len = data_len;
689 nan_req.request_data = data;
690
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530691 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530692 if (VOS_STATUS_SUCCESS == status)
693 {
694 ret_val = 0;
695 }
696 return ret_val;
697}
698
699/*
700 * FUNCTION: wlan_hdd_cfg80211_nan_request
701 * Wrapper to protect the nan vendor command from ssr
702 */
703static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
704 struct wireless_dev *wdev,
705 const void *data, int data_len)
706{
707 int ret;
708
709 vos_ssr_protect(__func__);
710 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
711 vos_ssr_unprotect(__func__);
712
713 return ret;
714}
715
716/*
717 * FUNCTION: wlan_hdd_cfg80211_nan_callback
718 * This is a callback function and it gets called
719 * when we need to report nan response event to
720 * upper layers.
721 */
722static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
723{
724 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
725 struct sk_buff *vendor_event;
726 int status;
727 tSirNanEvent *data;
728
729 ENTER();
730 if (NULL == msg)
731 {
732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
733 FL(" msg received here is null"));
734 return;
735 }
736 data = msg;
737
738 status = wlan_hdd_validate_context(pHddCtx);
739
740 if (0 != status)
741 {
742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
743 FL("HDD context is not valid"));
744 return;
745 }
746
747 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530748#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
749 NULL,
750#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530751 data->event_data_len +
752 NLMSG_HDRLEN,
753 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
754 GFP_KERNEL);
755
756 if (!vendor_event)
757 {
758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
759 FL("cfg80211_vendor_event_alloc failed"));
760 return;
761 }
762 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
763 data->event_data_len, data->event_data))
764 {
765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
766 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
767 kfree_skb(vendor_event);
768 return;
769 }
770 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
771 EXIT();
772}
773
774/*
775 * FUNCTION: wlan_hdd_cfg80211_nan_init
776 * This function is called to register the callback to sme layer
777 */
778inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
779{
780 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
781}
782
783
Sunil Duttc69bccb2014-05-26 21:30:20 +0530784#ifdef WLAN_FEATURE_LINK_LAYER_STATS
785
786static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
787 struct sk_buff *vendor_event)
788{
789 if (nla_put_u8(vendor_event,
790 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
791 stats->rate.preamble) ||
792 nla_put_u8(vendor_event,
793 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
794 stats->rate.nss) ||
795 nla_put_u8(vendor_event,
796 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
797 stats->rate.bw) ||
798 nla_put_u8(vendor_event,
799 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
800 stats->rate.rateMcsIdx) ||
801 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
802 stats->rate.bitrate ) ||
803 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
804 stats->txMpdu ) ||
805 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
806 stats->rxMpdu ) ||
807 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
808 stats->mpduLost ) ||
809 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
810 stats->retries) ||
811 nla_put_u32(vendor_event,
812 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
813 stats->retriesShort ) ||
814 nla_put_u32(vendor_event,
815 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
816 stats->retriesLong))
817 {
818 hddLog(VOS_TRACE_LEVEL_ERROR,
819 FL("QCA_WLAN_VENDOR_ATTR put fail"));
820 return FALSE;
821 }
822 return TRUE;
823}
824
825static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
826 struct sk_buff *vendor_event)
827{
828 u32 i = 0;
829 struct nlattr *rateInfo;
830 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
831 stats->type) ||
832 nla_put(vendor_event,
833 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
834 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
835 nla_put_u32(vendor_event,
836 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
837 stats->capabilities) ||
838 nla_put_u32(vendor_event,
839 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
840 stats->numRate))
841 {
842 hddLog(VOS_TRACE_LEVEL_ERROR,
843 FL("QCA_WLAN_VENDOR_ATTR put fail"));
844 goto error;
845 }
846
847 rateInfo = nla_nest_start(vendor_event,
848 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530849 if(!rateInfo)
850 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530851 for (i = 0; i < stats->numRate; i++)
852 {
853 struct nlattr *rates;
854 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
855 stats->rateStats +
856 (i * sizeof(tSirWifiRateStat)));
857 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530858 if(!rates)
859 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530860
861 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
862 {
863 hddLog(VOS_TRACE_LEVEL_ERROR,
864 FL("QCA_WLAN_VENDOR_ATTR put fail"));
865 return FALSE;
866 }
867 nla_nest_end(vendor_event, rates);
868 }
869 nla_nest_end(vendor_event, rateInfo);
870
871 return TRUE;
872error:
873 return FALSE;
874}
875
876static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
877 struct sk_buff *vendor_event)
878{
879 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
880 stats->ac ) ||
881 nla_put_u32(vendor_event,
882 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
883 stats->txMpdu ) ||
884 nla_put_u32(vendor_event,
885 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
886 stats->rxMpdu ) ||
887 nla_put_u32(vendor_event,
888 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
889 stats->txMcast ) ||
890 nla_put_u32(vendor_event,
891 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
892 stats->rxMcast ) ||
893 nla_put_u32(vendor_event,
894 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
895 stats->rxAmpdu ) ||
896 nla_put_u32(vendor_event,
897 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
898 stats->txAmpdu ) ||
899 nla_put_u32(vendor_event,
900 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
901 stats->mpduLost )||
902 nla_put_u32(vendor_event,
903 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
904 stats->retries ) ||
905 nla_put_u32(vendor_event,
906 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
907 stats->retriesShort ) ||
908 nla_put_u32(vendor_event,
909 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
910 stats->retriesLong ) ||
911 nla_put_u32(vendor_event,
912 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
913 stats->contentionTimeMin ) ||
914 nla_put_u32(vendor_event,
915 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
916 stats->contentionTimeMax ) ||
917 nla_put_u32(vendor_event,
918 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
919 stats->contentionTimeAvg ) ||
920 nla_put_u32(vendor_event,
921 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
922 stats->contentionNumSamples ))
923 {
924 hddLog(VOS_TRACE_LEVEL_ERROR,
925 FL("QCA_WLAN_VENDOR_ATTR put fail") );
926 return FALSE;
927 }
928 return TRUE;
929}
930
931static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
932 struct sk_buff *vendor_event)
933{
Dino Myclec8f3f332014-07-21 16:48:27 +0530934 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530935 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
936 nla_put(vendor_event,
937 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
938 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
939 nla_put_u32(vendor_event,
940 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
941 stats->state ) ||
942 nla_put_u32(vendor_event,
943 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
944 stats->roaming ) ||
945 nla_put_u32(vendor_event,
946 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
947 stats->capabilities ) ||
948 nla_put(vendor_event,
949 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
950 strlen(stats->ssid), stats->ssid) ||
951 nla_put(vendor_event,
952 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
953 WNI_CFG_BSSID_LEN, stats->bssid) ||
954 nla_put(vendor_event,
955 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
956 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
957 nla_put(vendor_event,
958 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
959 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
960 )
961 {
962 hddLog(VOS_TRACE_LEVEL_ERROR,
963 FL("QCA_WLAN_VENDOR_ATTR put fail") );
964 return FALSE;
965 }
966 return TRUE;
967}
968
Dino Mycle3b9536d2014-07-09 22:05:24 +0530969static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
970 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530971 struct sk_buff *vendor_event)
972{
973 int i = 0;
974 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530975 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
976 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530977 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530978
Sunil Duttc69bccb2014-05-26 21:30:20 +0530979 if (FALSE == put_wifi_interface_info(
980 &pWifiIfaceStat->info,
981 vendor_event))
982 {
983 hddLog(VOS_TRACE_LEVEL_ERROR,
984 FL("QCA_WLAN_VENDOR_ATTR put fail") );
985 return FALSE;
986
987 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530988 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
989 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
990 if (NULL == pWifiIfaceStatTL)
991 {
992 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
993 return FALSE;
994 }
995
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530996 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
997 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
998 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
999 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1000
1001 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1002 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1003 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1004 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301005
1006 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1007 {
1008 if (VOS_STATUS_SUCCESS ==
1009 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1010 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1011 {
1012 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1013 * obtained from TL structure
1014 */
1015
1016 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1017 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301018 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1019
Srinivas Dasari98947432014-11-07 19:41:24 +05301020 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1021 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1022 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1023 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1024 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1025 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1026 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1027 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301028
Srinivas Dasari98947432014-11-07 19:41:24 +05301029 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1030 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1031 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1032 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1033 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1034 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1035 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1036 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301037
Srinivas Dasari98947432014-11-07 19:41:24 +05301038 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1039 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1040 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1041 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1042 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1043 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1044 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1045 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301046 }
1047 else
1048 {
1049 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1050 }
1051
Dino Mycle3b9536d2014-07-09 22:05:24 +05301052 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1053 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1054 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1055 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1056 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1057 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1058 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1059 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1060 }
1061 else
1062 {
1063 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1064 }
1065
1066
Sunil Duttc69bccb2014-05-26 21:30:20 +05301067
1068 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301069 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1070 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1071 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301072 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1073 pWifiIfaceStat->beaconRx) ||
1074 nla_put_u32(vendor_event,
1075 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1076 pWifiIfaceStat->mgmtRx) ||
1077 nla_put_u32(vendor_event,
1078 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1079 pWifiIfaceStat->mgmtActionRx) ||
1080 nla_put_u32(vendor_event,
1081 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1082 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301083 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301084 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1085 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301086 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301087 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1088 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301089 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301090 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1091 pWifiIfaceStat->rssiAck))
1092 {
1093 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301094 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1095 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301096 return FALSE;
1097 }
1098
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301099#ifdef FEATURE_EXT_LL_STAT
1100 /*
1101 * Ensure when EXT_LL_STAT is supported by both host and fwr,
1102 * then host should send Leaky AP stats to upper layer,
1103 * otherwise no need to send these stats.
1104 */
1105 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
1106 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
1107 )
1108 {
1109 hddLog(VOS_TRACE_LEVEL_INFO,
1110 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
1111 pWifiIfaceStat->leakyApStat.is_leaky_ap,
1112 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
1113 pWifiIfaceStat->leakyApStat.rx_leak_window,
1114 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
1115 if (nla_put_u32(vendor_event,
1116 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
1117 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
1118 nla_put_u32(vendor_event,
1119 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
1120 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
1121 nla_put_u32(vendor_event,
1122 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
1123 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
1124 nla_put_u64(vendor_event,
1125 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
1126 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
1127 {
1128 hddLog(VOS_TRACE_LEVEL_ERROR,
1129 FL("EXT_LL_STAT put fail"));
1130 vos_mem_free(pWifiIfaceStatTL);
1131 return FALSE;
1132 }
1133 }
1134#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301135 wmmInfo = nla_nest_start(vendor_event,
1136 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301137 if(!wmmInfo)
1138 {
1139 vos_mem_free(pWifiIfaceStatTL);
1140 return FALSE;
1141 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301142 for (i = 0; i < WIFI_AC_MAX; i++)
1143 {
1144 struct nlattr *wmmStats;
1145 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301146 if(!wmmStats)
1147 {
1148 vos_mem_free(pWifiIfaceStatTL);
1149 return FALSE;
1150 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301151 if (FALSE == put_wifi_wmm_ac_stat(
1152 &pWifiIfaceStat->AccessclassStats[i],
1153 vendor_event))
1154 {
1155 hddLog(VOS_TRACE_LEVEL_ERROR,
1156 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301157 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301158 return FALSE;
1159 }
1160
1161 nla_nest_end(vendor_event, wmmStats);
1162 }
1163 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301164 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301165 return TRUE;
1166}
1167
1168static tSirWifiInterfaceMode
1169 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1170{
1171 switch (deviceMode)
1172 {
1173 case WLAN_HDD_INFRA_STATION:
1174 return WIFI_INTERFACE_STA;
1175 case WLAN_HDD_SOFTAP:
1176 return WIFI_INTERFACE_SOFTAP;
1177 case WLAN_HDD_P2P_CLIENT:
1178 return WIFI_INTERFACE_P2P_CLIENT;
1179 case WLAN_HDD_P2P_GO:
1180 return WIFI_INTERFACE_P2P_GO;
1181 case WLAN_HDD_IBSS:
1182 return WIFI_INTERFACE_IBSS;
1183 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301184 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301185 }
1186}
1187
1188static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1189 tpSirWifiInterfaceInfo pInfo)
1190{
1191 v_U8_t *staMac = NULL;
1192 hdd_station_ctx_t *pHddStaCtx;
1193 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1194 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1195
1196 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1197
1198 vos_mem_copy(pInfo->macAddr,
1199 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1200
1201 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1202 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1203 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1204 {
1205 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1206 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1207 {
1208 pInfo->state = WIFI_DISCONNECTED;
1209 }
1210 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1211 {
1212 hddLog(VOS_TRACE_LEVEL_ERROR,
1213 "%s: Session ID %d, Connection is in progress", __func__,
1214 pAdapter->sessionId);
1215 pInfo->state = WIFI_ASSOCIATING;
1216 }
1217 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1218 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1219 {
1220 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1221 hddLog(VOS_TRACE_LEVEL_ERROR,
1222 "%s: client " MAC_ADDRESS_STR
1223 " is in the middle of WPS/EAPOL exchange.", __func__,
1224 MAC_ADDR_ARRAY(staMac));
1225 pInfo->state = WIFI_AUTHENTICATING;
1226 }
1227 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1228 {
1229 pInfo->state = WIFI_ASSOCIATED;
1230 vos_mem_copy(pInfo->bssid,
1231 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1232 vos_mem_copy(pInfo->ssid,
1233 pHddStaCtx->conn_info.SSID.SSID.ssId,
1234 pHddStaCtx->conn_info.SSID.SSID.length);
1235 //NULL Terminate the string.
1236 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1237 }
1238 }
1239 vos_mem_copy(pInfo->countryStr,
1240 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1241
1242 vos_mem_copy(pInfo->apCountryStr,
1243 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1244
1245 return TRUE;
1246}
1247
1248/*
1249 * hdd_link_layer_process_peer_stats () - This function is called after
1250 * receiving Link Layer Peer statistics from FW.This function converts
1251 * the firmware data to the NL data and sends the same to the kernel/upper
1252 * layers.
1253 */
1254static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1255 v_VOID_t *pData)
1256{
1257 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301258 tpSirWifiPeerStat pWifiPeerStat;
1259 tpSirWifiPeerInfo pWifiPeerInfo;
1260 struct nlattr *peerInfo;
1261 struct sk_buff *vendor_event;
1262 int status, i;
1263
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301264 ENTER();
1265
Sunil Duttc69bccb2014-05-26 21:30:20 +05301266 status = wlan_hdd_validate_context(pHddCtx);
1267 if (0 != status)
1268 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301269 return;
1270 }
1271
1272 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1273
1274 hddLog(VOS_TRACE_LEVEL_INFO,
1275 "LL_STATS_PEER_ALL : numPeers %u",
1276 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301277 /*
1278 * Allocate a size of 4096 for the peer stats comprising
1279 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1280 * sizeof (tSirWifiRateStat).Each field is put with an
1281 * NL attribute.The size of 4096 is considered assuming
1282 * that number of rates shall not exceed beyond 50 with
1283 * the sizeof (tSirWifiRateStat) being 32.
1284 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301285 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1286 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301287 if (!vendor_event)
1288 {
1289 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301290 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301291 __func__);
1292 return;
1293 }
1294 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301295 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1296 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1297 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301298 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1299 pWifiPeerStat->numPeers))
1300 {
1301 hddLog(VOS_TRACE_LEVEL_ERROR,
1302 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1303 kfree_skb(vendor_event);
1304 return;
1305 }
1306
1307 peerInfo = nla_nest_start(vendor_event,
1308 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301309 if(!peerInfo)
1310 {
1311 hddLog(VOS_TRACE_LEVEL_ERROR,
1312 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1313 __func__);
1314 kfree_skb(vendor_event);
1315 return;
1316 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301317
1318 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1319 pWifiPeerStat->peerInfo);
1320
1321 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1322 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301323 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301324 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301325
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301326 if(!peers)
1327 {
1328 hddLog(VOS_TRACE_LEVEL_ERROR,
1329 "%s: peer stats put fail",
1330 __func__);
1331 kfree_skb(vendor_event);
1332 return;
1333 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301334 if (FALSE == put_wifi_peer_info(
1335 pWifiPeerInfo, vendor_event))
1336 {
1337 hddLog(VOS_TRACE_LEVEL_ERROR,
1338 "%s: put_wifi_peer_info put fail", __func__);
1339 kfree_skb(vendor_event);
1340 return;
1341 }
1342
1343 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1344 pWifiPeerStat->peerInfo +
1345 (i * sizeof(tSirWifiPeerInfo)) +
1346 (numRate * sizeof (tSirWifiRateStat)));
1347 nla_nest_end(vendor_event, peers);
1348 }
1349 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301350 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301351 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301352}
1353
1354/*
1355 * hdd_link_layer_process_iface_stats () - This function is called after
1356 * receiving Link Layer Interface statistics from FW.This function converts
1357 * the firmware data to the NL data and sends the same to the kernel/upper
1358 * layers.
1359 */
1360static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1361 v_VOID_t *pData)
1362{
1363 tpSirWifiIfaceStat pWifiIfaceStat;
1364 struct sk_buff *vendor_event;
1365 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1366 int status;
1367
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301368 ENTER();
1369
Sunil Duttc69bccb2014-05-26 21:30:20 +05301370 status = wlan_hdd_validate_context(pHddCtx);
1371 if (0 != status)
1372 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301373 return;
1374 }
1375 /*
1376 * Allocate a size of 4096 for the interface stats comprising
1377 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1378 * assuming that all these fit with in the limit.Please take
1379 * a call on the limit based on the data requirements on
1380 * interface statistics.
1381 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301382 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1383 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301384 if (!vendor_event)
1385 {
1386 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301387 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301388 return;
1389 }
1390
1391 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1392
Dino Mycle3b9536d2014-07-09 22:05:24 +05301393
1394 if (FALSE == hdd_get_interface_info( pAdapter,
1395 &pWifiIfaceStat->info))
1396 {
1397 hddLog(VOS_TRACE_LEVEL_ERROR,
1398 FL("hdd_get_interface_info get fail") );
1399 kfree_skb(vendor_event);
1400 return;
1401 }
1402
1403 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1404 vendor_event))
1405 {
1406 hddLog(VOS_TRACE_LEVEL_ERROR,
1407 FL("put_wifi_iface_stats fail") );
1408 kfree_skb(vendor_event);
1409 return;
1410 }
1411
Sunil Duttc69bccb2014-05-26 21:30:20 +05301412 hddLog(VOS_TRACE_LEVEL_INFO,
1413 "WMI_LINK_STATS_IFACE Data");
1414
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301415 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301416
1417 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301418}
1419
1420/*
1421 * hdd_link_layer_process_radio_stats () - This function is called after
1422 * receiving Link Layer Radio statistics from FW.This function converts
1423 * the firmware data to the NL data and sends the same to the kernel/upper
1424 * layers.
1425 */
1426static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1427 v_VOID_t *pData)
1428{
1429 int status, i;
1430 tpSirWifiRadioStat pWifiRadioStat;
1431 tpSirWifiChannelStats pWifiChannelStats;
1432 struct sk_buff *vendor_event;
1433 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1434 struct nlattr *chList;
1435
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301436 ENTER();
1437
Sunil Duttc69bccb2014-05-26 21:30:20 +05301438 status = wlan_hdd_validate_context(pHddCtx);
1439 if (0 != status)
1440 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301441 return;
1442 }
1443 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1444
1445 hddLog(VOS_TRACE_LEVEL_INFO,
1446 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301447 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05301448 " radio is %d onTime is %u "
1449 " txTime is %u rxTime is %u "
1450 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301451 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301452 " onTimePnoScan is %u onTimeHs20 is %u "
1453 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301454 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301455 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1456 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1457 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301458 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301459 pWifiRadioStat->onTimeRoamScan,
1460 pWifiRadioStat->onTimePnoScan,
1461 pWifiRadioStat->onTimeHs20,
1462 pWifiRadioStat->numChannels);
1463 /*
1464 * Allocate a size of 4096 for the Radio stats comprising
1465 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1466 * (tSirWifiChannelStats).Each channel data is put with an
1467 * NL attribute.The size of 4096 is considered assuming that
1468 * number of channels shall not exceed beyond 60 with the
1469 * sizeof (tSirWifiChannelStats) being 24 bytes.
1470 */
1471
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301472 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1473 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301474 if (!vendor_event)
1475 {
1476 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301477 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301478 return;
1479 }
1480
1481 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301482 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1483 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1484 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301485 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1486 pWifiRadioStat->radio) ||
1487 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05301488 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
1489 NUM_RADIOS) ||
1490 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301491 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1492 pWifiRadioStat->onTime) ||
1493 nla_put_u32(vendor_event,
1494 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1495 pWifiRadioStat->txTime) ||
1496 nla_put_u32(vendor_event,
1497 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1498 pWifiRadioStat->rxTime) ||
1499 nla_put_u32(vendor_event,
1500 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1501 pWifiRadioStat->onTimeScan) ||
1502 nla_put_u32(vendor_event,
1503 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1504 pWifiRadioStat->onTimeNbd) ||
1505 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301506 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1507 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301508 nla_put_u32(vendor_event,
1509 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1510 pWifiRadioStat->onTimeRoamScan) ||
1511 nla_put_u32(vendor_event,
1512 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1513 pWifiRadioStat->onTimePnoScan) ||
1514 nla_put_u32(vendor_event,
1515 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1516 pWifiRadioStat->onTimeHs20) ||
1517 nla_put_u32(vendor_event,
1518 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1519 pWifiRadioStat->numChannels))
1520 {
1521 hddLog(VOS_TRACE_LEVEL_ERROR,
1522 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1523 kfree_skb(vendor_event);
1524 return ;
1525 }
1526
1527 chList = nla_nest_start(vendor_event,
1528 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301529 if(!chList)
1530 {
1531 hddLog(VOS_TRACE_LEVEL_ERROR,
1532 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1533 __func__);
1534 kfree_skb(vendor_event);
1535 return;
1536 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301537 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1538 {
1539 struct nlattr *chInfo;
1540
1541 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1542 pWifiRadioStat->channels +
1543 (i * sizeof(tSirWifiChannelStats)));
1544
Sunil Duttc69bccb2014-05-26 21:30:20 +05301545 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301546 if(!chInfo)
1547 {
1548 hddLog(VOS_TRACE_LEVEL_ERROR,
1549 "%s: failed to put chInfo",
1550 __func__);
1551 kfree_skb(vendor_event);
1552 return;
1553 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301554
1555 if (nla_put_u32(vendor_event,
1556 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1557 pWifiChannelStats->channel.width) ||
1558 nla_put_u32(vendor_event,
1559 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1560 pWifiChannelStats->channel.centerFreq) ||
1561 nla_put_u32(vendor_event,
1562 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1563 pWifiChannelStats->channel.centerFreq0) ||
1564 nla_put_u32(vendor_event,
1565 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1566 pWifiChannelStats->channel.centerFreq1) ||
1567 nla_put_u32(vendor_event,
1568 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1569 pWifiChannelStats->onTime) ||
1570 nla_put_u32(vendor_event,
1571 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1572 pWifiChannelStats->ccaBusyTime))
1573 {
1574 hddLog(VOS_TRACE_LEVEL_ERROR,
1575 FL("cfg80211_vendor_event_alloc failed") );
1576 kfree_skb(vendor_event);
1577 return ;
1578 }
1579 nla_nest_end(vendor_event, chInfo);
1580 }
1581 nla_nest_end(vendor_event, chList);
1582
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301583 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301584
1585 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301586 return;
1587}
1588
1589/*
1590 * hdd_link_layer_stats_ind_callback () - This function is called after
1591 * receiving Link Layer indications from FW.This callback converts the firmware
1592 * data to the NL data and send the same to the kernel/upper layers.
1593 */
1594static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1595 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301596 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301597{
Dino Mycled3d50022014-07-07 12:58:25 +05301598 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1599 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301600 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301601 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301602 int status;
1603
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301604 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301605
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301606 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301607 if (0 != status)
1608 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301609 return;
1610 }
1611
Dino Mycled3d50022014-07-07 12:58:25 +05301612 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1613 if (NULL == pAdapter)
1614 {
1615 hddLog(VOS_TRACE_LEVEL_ERROR,
1616 FL(" MAC address %pM does not exist with host"),
1617 macAddr);
1618 return;
1619 }
1620
Sunil Duttc69bccb2014-05-26 21:30:20 +05301621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301622 "%s: Interface: %s LLStats indType: %d", __func__,
1623 pAdapter->dev->name, indType);
1624
Sunil Duttc69bccb2014-05-26 21:30:20 +05301625 switch (indType)
1626 {
1627 case SIR_HAL_LL_STATS_RESULTS_RSP:
1628 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301629 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301630 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1631 "respId = %u, moreResultToFollow = %u",
1632 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1633 macAddr, linkLayerStatsResults->respId,
1634 linkLayerStatsResults->moreResultToFollow);
1635
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301636 spin_lock(&hdd_context_lock);
1637 context = &pHddCtx->ll_stats_context;
1638 /* validate response received from target */
1639 if ((context->request_id != linkLayerStatsResults->respId) ||
1640 !(context->request_bitmap & linkLayerStatsResults->paramId))
1641 {
1642 spin_unlock(&hdd_context_lock);
1643 hddLog(LOGE,
1644 FL("Error : Request id %d response id %d request bitmap 0x%x"
1645 "response bitmap 0x%x"),
1646 context->request_id, linkLayerStatsResults->respId,
1647 context->request_bitmap, linkLayerStatsResults->paramId);
1648 return;
1649 }
1650 spin_unlock(&hdd_context_lock);
1651
Sunil Duttc69bccb2014-05-26 21:30:20 +05301652 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1653 {
1654 hdd_link_layer_process_radio_stats(pAdapter,
1655 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301656 spin_lock(&hdd_context_lock);
1657 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1658 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301659 }
1660 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1661 {
1662 hdd_link_layer_process_iface_stats(pAdapter,
1663 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301664 spin_lock(&hdd_context_lock);
1665 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1666 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301667 }
1668 else if ( linkLayerStatsResults->paramId &
1669 WMI_LINK_STATS_ALL_PEER )
1670 {
1671 hdd_link_layer_process_peer_stats(pAdapter,
1672 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301673 spin_lock(&hdd_context_lock);
1674 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1675 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301676 } /* WMI_LINK_STATS_ALL_PEER */
1677 else
1678 {
1679 hddLog(VOS_TRACE_LEVEL_ERROR,
1680 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1681 }
1682
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301683 spin_lock(&hdd_context_lock);
1684 /* complete response event if all requests are completed */
1685 if (0 == context->request_bitmap)
1686 complete(&context->response_event);
1687 spin_unlock(&hdd_context_lock);
1688
Sunil Duttc69bccb2014-05-26 21:30:20 +05301689 break;
1690 }
1691 default:
1692 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1693 break;
1694 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301695
1696 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301697 return;
1698}
1699
1700const struct
1701nla_policy
1702qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1703{
1704 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1705 { .type = NLA_U32 },
1706 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1707 { .type = NLA_U32 },
1708};
1709
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301710static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1711 struct wireless_dev *wdev,
1712 const void *data,
1713 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301714{
1715 int status;
1716 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301717 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301718 struct net_device *dev = wdev->netdev;
1719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1720 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1721
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301722 ENTER();
1723
Sunil Duttc69bccb2014-05-26 21:30:20 +05301724 status = wlan_hdd_validate_context(pHddCtx);
1725 if (0 != status)
1726 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301727 return -EINVAL;
1728 }
1729
1730 if (NULL == pAdapter)
1731 {
1732 hddLog(VOS_TRACE_LEVEL_ERROR,
1733 FL("HDD adapter is Null"));
1734 return -ENODEV;
1735 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301736 /* check the LLStats Capability */
1737 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1738 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1739 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05301740 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301741 FL("Link Layer Statistics not supported by Firmware"));
1742 return -EINVAL;
1743 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301744
1745 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1746 (struct nlattr *)data,
1747 data_len, qca_wlan_vendor_ll_set_policy))
1748 {
1749 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1750 return -EINVAL;
1751 }
1752 if (!tb_vendor
1753 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1754 {
1755 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1756 return -EINVAL;
1757 }
1758 if (!tb_vendor[
1759 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1760 {
1761 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1762 return -EINVAL;
1763 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301764 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301765 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301766
Dino Mycledf0a5d92014-07-04 09:41:55 +05301767 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301768 nla_get_u32(
1769 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1770
Dino Mycledf0a5d92014-07-04 09:41:55 +05301771 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301772 nla_get_u32(
1773 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1774
Dino Mycled3d50022014-07-07 12:58:25 +05301775 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1776 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301777
1778
1779 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301780 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1781 "Statistics Gathering = %d ",
1782 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1783 linkLayerStatsSetReq.mpduSizeThreshold,
1784 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301785
1786 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1787 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301788 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301789 {
1790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1791 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301792 return -EINVAL;
1793
1794 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301795
Sunil Duttc69bccb2014-05-26 21:30:20 +05301796 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301797 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301798 {
1799 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1800 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301801 return -EINVAL;
1802 }
1803
1804 pAdapter->isLinkLayerStatsSet = 1;
1805
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301806 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301807 return 0;
1808}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301809static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1810 struct wireless_dev *wdev,
1811 const void *data,
1812 int data_len)
1813{
1814 int ret = 0;
1815
1816 vos_ssr_protect(__func__);
1817 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1818 vos_ssr_unprotect(__func__);
1819
1820 return ret;
1821}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301822
1823const struct
1824nla_policy
1825qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1826{
1827 /* Unsigned 32bit value provided by the caller issuing the GET stats
1828 * command. When reporting
1829 * the stats results, the driver uses the same value to indicate
1830 * which GET request the results
1831 * correspond to.
1832 */
1833 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1834
1835 /* Unsigned 32bit value . bit mask to identify what statistics are
1836 requested for retrieval */
1837 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1838};
1839
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301840static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1841 struct wireless_dev *wdev,
1842 const void *data,
1843 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301844{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301845 unsigned long rc;
1846 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301847 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1848 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301849 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301850 struct net_device *dev = wdev->netdev;
1851 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301852 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301853 int status;
1854
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301855 ENTER();
1856
Sunil Duttc69bccb2014-05-26 21:30:20 +05301857 status = wlan_hdd_validate_context(pHddCtx);
1858 if (0 != status)
1859 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301860 return -EINVAL ;
1861 }
1862
1863 if (NULL == pAdapter)
1864 {
1865 hddLog(VOS_TRACE_LEVEL_FATAL,
1866 "%s: HDD adapter is Null", __func__);
1867 return -ENODEV;
1868 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301869
1870 if (pHddStaCtx == NULL)
1871 {
1872 hddLog(VOS_TRACE_LEVEL_FATAL,
1873 "%s: HddStaCtx is Null", __func__);
1874 return -ENODEV;
1875 }
1876
Dino Mycledf0a5d92014-07-04 09:41:55 +05301877 /* check the LLStats Capability */
1878 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1879 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1880 {
1881 hddLog(VOS_TRACE_LEVEL_ERROR,
1882 FL("Link Layer Statistics not supported by Firmware"));
1883 return -EINVAL;
1884 }
1885
Sunil Duttc69bccb2014-05-26 21:30:20 +05301886
1887 if (!pAdapter->isLinkLayerStatsSet)
1888 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05301889 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301890 "%s: isLinkLayerStatsSet : %d",
1891 __func__, pAdapter->isLinkLayerStatsSet);
1892 return -EINVAL;
1893 }
1894
Mukul Sharma10313ba2015-07-29 19:14:39 +05301895 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1896 {
1897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1898 "%s: Roaming in progress, so unable to proceed this request", __func__);
1899 return -EBUSY;
1900 }
1901
Sunil Duttc69bccb2014-05-26 21:30:20 +05301902 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1903 (struct nlattr *)data,
1904 data_len, qca_wlan_vendor_ll_get_policy))
1905 {
1906 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1907 return -EINVAL;
1908 }
1909
1910 if (!tb_vendor
1911 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1912 {
1913 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1914 return -EINVAL;
1915 }
1916
1917 if (!tb_vendor
1918 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1919 {
1920 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1921 return -EINVAL;
1922 }
1923
Sunil Duttc69bccb2014-05-26 21:30:20 +05301924
Dino Mycledf0a5d92014-07-04 09:41:55 +05301925 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301926 nla_get_u32( tb_vendor[
1927 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301928 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301929 nla_get_u32( tb_vendor[
1930 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1931
Dino Mycled3d50022014-07-07 12:58:25 +05301932 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1933 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301934
1935 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301936 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1937 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301938 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301939
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301940 spin_lock(&hdd_context_lock);
1941 context = &pHddCtx->ll_stats_context;
1942 context->request_id = linkLayerStatsGetReq.reqId;
1943 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1944 INIT_COMPLETION(context->response_event);
1945 spin_unlock(&hdd_context_lock);
1946
Sunil Duttc69bccb2014-05-26 21:30:20 +05301947 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301948 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301949 {
1950 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1951 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301952 return -EINVAL;
1953 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301954
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301955 rc = wait_for_completion_timeout(&context->response_event,
1956 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1957 if (!rc)
1958 {
1959 hddLog(LOGE,
1960 FL("Target response timed out request id %d request bitmap 0x%x"),
1961 context->request_id, context->request_bitmap);
1962 return -ETIMEDOUT;
1963 }
1964
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301965 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301966 return 0;
1967}
1968
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301969static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1970 struct wireless_dev *wdev,
1971 const void *data,
1972 int data_len)
1973{
1974 int ret = 0;
1975
1976 vos_ssr_protect(__func__);
1977 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1978 vos_ssr_unprotect(__func__);
1979
1980 return ret;
1981}
1982
Sunil Duttc69bccb2014-05-26 21:30:20 +05301983const struct
1984nla_policy
1985qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1986{
1987 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1988 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1989 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1990 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1991};
1992
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301993static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1994 struct wireless_dev *wdev,
1995 const void *data,
1996 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301997{
1998 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1999 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302000 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302001 struct net_device *dev = wdev->netdev;
2002 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2003 u32 statsClearReqMask;
2004 u8 stopReq;
2005 int status;
2006
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302007 ENTER();
2008
Sunil Duttc69bccb2014-05-26 21:30:20 +05302009 status = wlan_hdd_validate_context(pHddCtx);
2010 if (0 != status)
2011 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302012 return -EINVAL;
2013 }
2014
2015 if (NULL == pAdapter)
2016 {
2017 hddLog(VOS_TRACE_LEVEL_FATAL,
2018 "%s: HDD adapter is Null", __func__);
2019 return -ENODEV;
2020 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302021 /* check the LLStats Capability */
2022 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2023 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2024 {
2025 hddLog(VOS_TRACE_LEVEL_ERROR,
2026 FL("Enable LLStats Capability"));
2027 return -EINVAL;
2028 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302029
2030 if (!pAdapter->isLinkLayerStatsSet)
2031 {
2032 hddLog(VOS_TRACE_LEVEL_FATAL,
2033 "%s: isLinkLayerStatsSet : %d",
2034 __func__, pAdapter->isLinkLayerStatsSet);
2035 return -EINVAL;
2036 }
2037
2038 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2039 (struct nlattr *)data,
2040 data_len, qca_wlan_vendor_ll_clr_policy))
2041 {
2042 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2043 return -EINVAL;
2044 }
2045
2046 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2047
2048 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2049 {
2050 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2051 return -EINVAL;
2052
2053 }
2054
Sunil Duttc69bccb2014-05-26 21:30:20 +05302055
Dino Mycledf0a5d92014-07-04 09:41:55 +05302056 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302057 nla_get_u32(
2058 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2059
Dino Mycledf0a5d92014-07-04 09:41:55 +05302060 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302061 nla_get_u8(
2062 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2063
2064 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302065 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302066
Dino Mycled3d50022014-07-07 12:58:25 +05302067 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2068 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302069
2070 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302071 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2072 "statsClearReqMask = 0x%X, stopReq = %d",
2073 linkLayerStatsClearReq.reqId,
2074 linkLayerStatsClearReq.macAddr,
2075 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302076 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302077
2078 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302079 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302080 {
2081 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302082 hdd_station_ctx_t *pHddStaCtx;
2083
2084 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2085 if (VOS_STATUS_SUCCESS !=
2086 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2087 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2088 {
2089 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2090 "WLANTL_ClearInterfaceStats Failed", __func__);
2091 return -EINVAL;
2092 }
2093 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2094 (statsClearReqMask & WIFI_STATS_IFACE)) {
2095 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2096 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2097 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2098 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2099 }
2100
Sunil Duttc69bccb2014-05-26 21:30:20 +05302101 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2102 2 * sizeof(u32) +
2103 NLMSG_HDRLEN);
2104
2105 if (temp_skbuff != NULL)
2106 {
2107
2108 if (nla_put_u32(temp_skbuff,
2109 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2110 statsClearReqMask) ||
2111 nla_put_u32(temp_skbuff,
2112 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2113 stopReq))
2114 {
2115 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2116 kfree_skb(temp_skbuff);
2117 return -EINVAL;
2118 }
2119 /* If the ask is to stop the stats collection as part of clear
2120 * (stopReq = 1) , ensure that no further requests of get
2121 * go to the firmware by having isLinkLayerStatsSet set to 0.
2122 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302123 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302124 * case the firmware is just asked to clear the statistics.
2125 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302126 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302127 pAdapter->isLinkLayerStatsSet = 0;
2128 return cfg80211_vendor_cmd_reply(temp_skbuff);
2129 }
2130 return -ENOMEM;
2131 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302132
2133 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302134 return -EINVAL;
2135}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302136static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2137 struct wireless_dev *wdev,
2138 const void *data,
2139 int data_len)
2140{
2141 int ret = 0;
2142
2143 vos_ssr_protect(__func__);
2144 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2145 vos_ssr_unprotect(__func__);
2146
2147 return ret;
2148
2149
2150}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302151#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2152
Dino Mycle6fb96c12014-06-10 11:52:40 +05302153#ifdef WLAN_FEATURE_EXTSCAN
2154static const struct nla_policy
2155wlan_hdd_extscan_config_policy
2156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2157{
2158 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2159 { .type = NLA_U32 },
2160 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2161 { .type = NLA_U32 },
2162 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2163 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2164 { .type = NLA_U32 },
2165 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2166 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2167
2168 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2169 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2170 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2171 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2172 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302173 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2174 { .type = NLA_U32 },
2175 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2176 { .type = NLA_U32 },
2177 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2178 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302179 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2180 { .type = NLA_U32 },
2181 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2182 { .type = NLA_U32 },
2183 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2184 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302185 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2186 { .type = NLA_U8 },
2187 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302188 { .type = NLA_U8 },
2189 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2190 { .type = NLA_U8 },
2191 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2192 { .type = NLA_U8 },
2193
2194 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2195 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05302196 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
2197 .type = NLA_UNSPEC,
2198 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05302199 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2200 { .type = NLA_S32 },
2201 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2202 { .type = NLA_S32 },
2203 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2204 { .type = NLA_U32 },
2205 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2206 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302207 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2208 { .type = NLA_U32 },
2209 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2210 { .type = NLA_BINARY,
2211 .len = IEEE80211_MAX_SSID_LEN + 1 },
2212 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302213 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302214 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2215 { .type = NLA_U32 },
2216 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2217 { .type = NLA_U8 },
2218 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2219 { .type = NLA_S32 },
2220 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2221 { .type = NLA_S32 },
2222 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2223 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302224};
2225
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302226/**
2227 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2228 * @ctx: hdd global context
2229 * @data: capabilities data
2230 *
2231 * Return: none
2232 */
2233static void
2234wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302235{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302236 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302237 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302238 tSirEXTScanCapabilitiesEvent *data =
2239 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302240
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302241 ENTER();
2242
2243 if (wlan_hdd_validate_context(pHddCtx))
2244 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302245 return;
2246 }
2247
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302248 if (!pMsg)
2249 {
2250 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2251 return;
2252 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302253
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302254 vos_spin_lock_acquire(&hdd_context_lock);
2255
2256 context = &pHddCtx->ext_scan_context;
2257 /* validate response received from target*/
2258 if (context->request_id != data->requestId)
2259 {
2260 vos_spin_lock_release(&hdd_context_lock);
2261 hddLog(LOGE,
2262 FL("Target response id did not match: request_id %d resposne_id %d"),
2263 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302264 return;
2265 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302266 else
2267 {
2268 context->capability_response = *data;
2269 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302270 }
2271
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302272 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302273
Dino Mycle6fb96c12014-06-10 11:52:40 +05302274 return;
2275}
2276
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302277/*
2278 * define short names for the global vendor params
2279 * used by wlan_hdd_send_ext_scan_capability()
2280 */
2281#define PARAM_REQUEST_ID \
2282 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2283#define PARAM_STATUS \
2284 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2285#define MAX_SCAN_CACHE_SIZE \
2286 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2287#define MAX_SCAN_BUCKETS \
2288 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2289#define MAX_AP_CACHE_PER_SCAN \
2290 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2291#define MAX_RSSI_SAMPLE_SIZE \
2292 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2293#define MAX_SCAN_RPT_THRHOLD \
2294 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2295#define MAX_HOTLIST_BSSIDS \
2296 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2297#define MAX_BSSID_HISTORY_ENTRIES \
2298 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2299#define MAX_HOTLIST_SSIDS \
2300 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302301#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2302 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302303
2304static int wlan_hdd_send_ext_scan_capability(void *ctx)
2305{
2306 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2307 struct sk_buff *skb = NULL;
2308 int ret;
2309 tSirEXTScanCapabilitiesEvent *data;
2310 tANI_U32 nl_buf_len;
2311
2312 ret = wlan_hdd_validate_context(pHddCtx);
2313 if (0 != ret)
2314 {
2315 return ret;
2316 }
2317
2318 data = &(pHddCtx->ext_scan_context.capability_response);
2319
2320 nl_buf_len = NLMSG_HDRLEN;
2321 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2322 (sizeof(data->status) + NLA_HDRLEN) +
2323 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2324 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2325 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2326 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2327 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2328 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2329 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2330 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2331
2332 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2333
2334 if (!skb)
2335 {
2336 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2337 return -ENOMEM;
2338 }
2339
2340 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2341 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2342 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2343 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2344 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2345 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2346 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2347 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2348
2349 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2350 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2351 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2352 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2353 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2354 data->maxApPerScan) ||
2355 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2356 data->maxRssiSampleSize) ||
2357 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2358 data->maxScanReportingThreshold) ||
2359 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2360 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2361 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302362 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2363 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302364 {
2365 hddLog(LOGE, FL("nla put fail"));
2366 goto nla_put_failure;
2367 }
2368
2369 cfg80211_vendor_cmd_reply(skb);
2370 return 0;
2371
2372nla_put_failure:
2373 kfree_skb(skb);
2374 return -EINVAL;;
2375}
2376
2377/*
2378 * done with short names for the global vendor params
2379 * used by wlan_hdd_send_ext_scan_capability()
2380 */
2381#undef PARAM_REQUEST_ID
2382#undef PARAM_STATUS
2383#undef MAX_SCAN_CACHE_SIZE
2384#undef MAX_SCAN_BUCKETS
2385#undef MAX_AP_CACHE_PER_SCAN
2386#undef MAX_RSSI_SAMPLE_SIZE
2387#undef MAX_SCAN_RPT_THRHOLD
2388#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302389#undef MAX_BSSID_HISTORY_ENTRIES
2390#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302391
2392static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2393{
2394 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2395 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302396 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302397 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302398
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302399 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302400
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302401 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302402 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302403
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302404 if (!pMsg)
2405 {
2406 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302407 return;
2408 }
2409
Dino Mycle6fb96c12014-06-10 11:52:40 +05302410 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2411 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2412
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302413 context = &pHddCtx->ext_scan_context;
2414 spin_lock(&hdd_context_lock);
2415 if (context->request_id == pData->requestId) {
2416 context->response_status = pData->status ? -EINVAL : 0;
2417 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302418 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302419 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302420
2421 /*
2422 * Store the Request ID for comparing with the requestID obtained
2423 * in other requests.HDD shall return a failure is the extscan_stop
2424 * request is issued with a different requestId as that of the
2425 * extscan_start request. Also, This requestId shall be used while
2426 * indicating the full scan results to the upper layers.
2427 * The requestId is stored with the assumption that the firmware
2428 * shall return the ext scan start request's requestId in ext scan
2429 * start response.
2430 */
2431 if (pData->status == 0)
2432 pMac->sme.extScanStartReqId = pData->requestId;
2433
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302434 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302435 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302436}
2437
2438
2439static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2440{
2441 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2442 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302443 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302444
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302445 ENTER();
2446
2447 if (wlan_hdd_validate_context(pHddCtx)){
2448 return;
2449 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302450
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302451 if (!pMsg)
2452 {
2453 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302454 return;
2455 }
2456
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302457 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2458 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302459
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302460 context = &pHddCtx->ext_scan_context;
2461 spin_lock(&hdd_context_lock);
2462 if (context->request_id == pData->requestId) {
2463 context->response_status = pData->status ? -EINVAL : 0;
2464 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302465 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302466 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302467
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302468 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302469 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302470}
2471
Dino Mycle6fb96c12014-06-10 11:52:40 +05302472static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2473 void *pMsg)
2474{
2475 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302476 tpSirEXTScanSetBssidHotListRspParams pData =
2477 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302478 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302479
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302480 ENTER();
2481
2482 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302483 return;
2484 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302485
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302486 if (!pMsg)
2487 {
2488 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2489 return;
2490 }
2491
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302492 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2493 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302494
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302495 context = &pHddCtx->ext_scan_context;
2496 spin_lock(&hdd_context_lock);
2497 if (context->request_id == pData->requestId) {
2498 context->response_status = pData->status ? -EINVAL : 0;
2499 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302500 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302501 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302502
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302503 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302504 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302505}
2506
2507static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2508 void *pMsg)
2509{
2510 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302511 tpSirEXTScanResetBssidHotlistRspParams pData =
2512 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302513 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302514
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302515 ENTER();
2516
2517 if (wlan_hdd_validate_context(pHddCtx)) {
2518 return;
2519 }
2520 if (!pMsg)
2521 {
2522 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302523 return;
2524 }
2525
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302526 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2527 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302528
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302529 context = &pHddCtx->ext_scan_context;
2530 spin_lock(&hdd_context_lock);
2531 if (context->request_id == pData->requestId) {
2532 context->response_status = pData->status ? -EINVAL : 0;
2533 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302534 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302535 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302536
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302537 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302538 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302539}
2540
Dino Mycle6fb96c12014-06-10 11:52:40 +05302541static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2542 void *pMsg)
2543{
2544 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2545 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302546 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302547 tANI_S32 totalResults;
2548 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302549 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2550 struct hdd_ext_scan_context *context;
2551 bool ignore_cached_results = false;
2552 tExtscanCachedScanResult *result;
2553 struct nlattr *nla_results;
2554 tANI_U16 ieLength= 0;
2555 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302556
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302557 ENTER();
2558
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302559 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302560 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302561
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302562 if (!pMsg)
2563 {
2564 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2565 return;
2566 }
2567
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302568 spin_lock(&hdd_context_lock);
2569 context = &pHddCtx->ext_scan_context;
2570 ignore_cached_results = context->ignore_cached_results;
2571 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302572
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302573 if (ignore_cached_results) {
2574 hddLog(LOGE,
2575 FL("Ignore the cached results received after timeout"));
2576 return;
2577 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302578
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302579 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2580 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302581
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302582 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302583
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302584 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2585 scan_id_index++) {
2586 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302587
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302588 totalResults = result->num_results;
2589 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2590 result->scan_id, result->flags, totalResults);
2591 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302592
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302593 do{
2594 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2595 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2596 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302597
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302598 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2599 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2600
2601 if (!skb) {
2602 hddLog(VOS_TRACE_LEVEL_ERROR,
2603 FL("cfg80211_vendor_event_alloc failed"));
2604 return;
2605 }
2606
2607 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2608
2609 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2610 pData->requestId) ||
2611 nla_put_u32(skb,
2612 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2613 resultsPerEvent)) {
2614 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2615 goto fail;
2616 }
2617 if (nla_put_u8(skb,
2618 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2619 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302620 {
2621 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2622 goto fail;
2623 }
2624
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302625 if (nla_put_u32(skb,
2626 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2627 result->scan_id)) {
2628 hddLog(LOGE, FL("put fail"));
2629 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302630 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302631
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302632 nla_results = nla_nest_start(skb,
2633 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2634 if (!nla_results)
2635 goto fail;
2636
2637 if (resultsPerEvent) {
2638 struct nlattr *aps;
2639 struct nlattr *nla_result;
2640
2641 nla_result = nla_nest_start(skb, scan_id_index);
2642 if(!nla_result)
2643 goto fail;
2644
2645 if (nla_put_u32(skb,
2646 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2647 result->scan_id) ||
2648 nla_put_u32(skb,
2649 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2650 result->flags) ||
2651 nla_put_u32(skb,
2652 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2653 totalResults)) {
2654 hddLog(LOGE, FL("put fail"));
2655 goto fail;
2656 }
2657
2658 aps = nla_nest_start(skb,
2659 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2660 if (!aps)
2661 {
2662 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2663 goto fail;
2664 }
2665
2666 head_ptr = (tpSirWifiScanResult) &(result->ap);
2667
2668 for (j = 0; j < resultsPerEvent; j++, i++) {
2669 struct nlattr *ap;
2670 pSirWifiScanResult = head_ptr + i;
2671
2672 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05302673 * Firmware returns timestamp from extscan_start till
2674 * BSSID was cached (in micro seconds). Add this with
2675 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302676 * to derive the time since boot when the
2677 * BSSID was cached.
2678 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05302679 pSirWifiScanResult->ts +=
2680 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302681 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2682 "Ssid (%s)"
2683 "Bssid: %pM "
2684 "Channel (%u)"
2685 "Rssi (%d)"
2686 "RTT (%u)"
2687 "RTT_SD (%u)"
2688 "Beacon Period %u"
2689 "Capability 0x%x "
2690 "Ie length %d",
2691 i,
2692 pSirWifiScanResult->ts,
2693 pSirWifiScanResult->ssid,
2694 pSirWifiScanResult->bssid,
2695 pSirWifiScanResult->channel,
2696 pSirWifiScanResult->rssi,
2697 pSirWifiScanResult->rtt,
2698 pSirWifiScanResult->rtt_sd,
2699 pSirWifiScanResult->beaconPeriod,
2700 pSirWifiScanResult->capability,
2701 ieLength);
2702
2703 ap = nla_nest_start(skb, j + 1);
2704 if (!ap)
2705 {
2706 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2707 goto fail;
2708 }
2709
2710 if (nla_put_u64(skb,
2711 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2712 pSirWifiScanResult->ts) )
2713 {
2714 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2715 goto fail;
2716 }
2717 if (nla_put(skb,
2718 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2719 sizeof(pSirWifiScanResult->ssid),
2720 pSirWifiScanResult->ssid) )
2721 {
2722 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2723 goto fail;
2724 }
2725 if (nla_put(skb,
2726 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2727 sizeof(pSirWifiScanResult->bssid),
2728 pSirWifiScanResult->bssid) )
2729 {
2730 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2731 goto fail;
2732 }
2733 if (nla_put_u32(skb,
2734 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2735 pSirWifiScanResult->channel) )
2736 {
2737 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2738 goto fail;
2739 }
2740 if (nla_put_s32(skb,
2741 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2742 pSirWifiScanResult->rssi) )
2743 {
2744 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2745 goto fail;
2746 }
2747 if (nla_put_u32(skb,
2748 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2749 pSirWifiScanResult->rtt) )
2750 {
2751 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2752 goto fail;
2753 }
2754 if (nla_put_u32(skb,
2755 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2756 pSirWifiScanResult->rtt_sd))
2757 {
2758 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2759 goto fail;
2760 }
2761 if (nla_put_u32(skb,
2762 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2763 pSirWifiScanResult->beaconPeriod))
2764 {
2765 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2766 goto fail;
2767 }
2768 if (nla_put_u32(skb,
2769 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2770 pSirWifiScanResult->capability))
2771 {
2772 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2773 goto fail;
2774 }
2775 if (nla_put_u32(skb,
2776 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2777 ieLength))
2778 {
2779 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2780 goto fail;
2781 }
2782
2783 if (ieLength)
2784 if (nla_put(skb,
2785 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2786 ieLength, ie)) {
2787 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2788 goto fail;
2789 }
2790
2791 nla_nest_end(skb, ap);
2792 }
2793 nla_nest_end(skb, aps);
2794 nla_nest_end(skb, nla_result);
2795 }
2796
2797 nla_nest_end(skb, nla_results);
2798
2799 cfg80211_vendor_cmd_reply(skb);
2800
2801 } while (totalResults > 0);
2802 }
2803
2804 if (!pData->moreData) {
2805 spin_lock(&hdd_context_lock);
2806 context->response_status = 0;
2807 complete(&context->response_event);
2808 spin_unlock(&hdd_context_lock);
2809 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302810
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302811 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302812 return;
2813fail:
2814 kfree_skb(skb);
2815 return;
2816}
2817
2818static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2819 void *pMsg)
2820{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302821 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302822 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2823 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302824 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302825
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302826 ENTER();
2827
2828 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302829 hddLog(LOGE,
2830 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302831 return;
2832 }
2833 if (!pMsg)
2834 {
2835 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302836 return;
2837 }
2838
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302839 if (pData->bss_found)
2840 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2841 else
2842 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2843
Dino Mycle6fb96c12014-06-10 11:52:40 +05302844 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302845#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2846 NULL,
2847#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302848 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302849 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302850
2851 if (!skb) {
2852 hddLog(VOS_TRACE_LEVEL_ERROR,
2853 FL("cfg80211_vendor_event_alloc failed"));
2854 return;
2855 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302856
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302857 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2858 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2859 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2860 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2861
2862 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302863 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2864 "Ssid (%s) "
2865 "Bssid (" MAC_ADDRESS_STR ") "
2866 "Channel (%u) "
2867 "Rssi (%d) "
2868 "RTT (%u) "
2869 "RTT_SD (%u) ",
2870 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302871 pData->bssHotlist[i].ts,
2872 pData->bssHotlist[i].ssid,
2873 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2874 pData->bssHotlist[i].channel,
2875 pData->bssHotlist[i].rssi,
2876 pData->bssHotlist[i].rtt,
2877 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302878 }
2879
2880 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2881 pData->requestId) ||
2882 nla_put_u32(skb,
2883 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302884 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302885 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2886 goto fail;
2887 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302888 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302889 struct nlattr *aps;
2890
2891 aps = nla_nest_start(skb,
2892 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2893 if (!aps)
2894 goto fail;
2895
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302896 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302897 struct nlattr *ap;
2898
2899 ap = nla_nest_start(skb, i + 1);
2900 if (!ap)
2901 goto fail;
2902
2903 if (nla_put_u64(skb,
2904 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302905 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302906 nla_put(skb,
2907 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302908 sizeof(pData->bssHotlist[i].ssid),
2909 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302910 nla_put(skb,
2911 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302912 sizeof(pData->bssHotlist[i].bssid),
2913 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302914 nla_put_u32(skb,
2915 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302916 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302917 nla_put_s32(skb,
2918 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302919 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302920 nla_put_u32(skb,
2921 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302922 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302923 nla_put_u32(skb,
2924 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302925 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302926 goto fail;
2927
2928 nla_nest_end(skb, ap);
2929 }
2930 nla_nest_end(skb, aps);
2931
2932 if (nla_put_u8(skb,
2933 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2934 pData->moreData))
2935 goto fail;
2936 }
2937
2938 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302939 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302940 return;
2941
2942fail:
2943 kfree_skb(skb);
2944 return;
2945
2946}
Dino Mycle6fb96c12014-06-10 11:52:40 +05302947
2948static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2949 void *pMsg)
2950{
2951 struct sk_buff *skb;
2952 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2953 tpSirWifiFullScanResultEvent pData =
2954 (tpSirWifiFullScanResultEvent) (pMsg);
2955
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302956 ENTER();
2957
2958 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302959 hddLog(LOGE,
2960 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302961 return;
2962 }
2963 if (!pMsg)
2964 {
2965 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302966 return;
2967 }
2968
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302969 /*
2970 * If the full scan result including IE data exceeds NL 4K size
2971 * limitation, drop that beacon/probe rsp frame.
2972 */
2973 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
2974 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
2975 return;
2976 }
2977
Dino Mycle6fb96c12014-06-10 11:52:40 +05302978 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302979#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2980 NULL,
2981#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302982 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2983 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2984 GFP_KERNEL);
2985
2986 if (!skb) {
2987 hddLog(VOS_TRACE_LEVEL_ERROR,
2988 FL("cfg80211_vendor_event_alloc failed"));
2989 return;
2990 }
2991
Dino Mycle6fb96c12014-06-10 11:52:40 +05302992 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2993 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2994 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2995 "Ssid (%s)"
2996 "Bssid (" MAC_ADDRESS_STR ")"
2997 "Channel (%u)"
2998 "Rssi (%d)"
2999 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303000 "RTT_SD (%u)"
3001 "Bcn Period %d"
3002 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303003 pData->ap.ts,
3004 pData->ap.ssid,
3005 MAC_ADDR_ARRAY(pData->ap.bssid),
3006 pData->ap.channel,
3007 pData->ap.rssi,
3008 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303009 pData->ap.rtt_sd,
3010 pData->ap.beaconPeriod,
3011 pData->ap.capability);
3012
Dino Mycle6fb96c12014-06-10 11:52:40 +05303013 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3014 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3015 pData->requestId) ||
3016 nla_put_u64(skb,
3017 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3018 pData->ap.ts) ||
3019 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3020 sizeof(pData->ap.ssid),
3021 pData->ap.ssid) ||
3022 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3023 WNI_CFG_BSSID_LEN,
3024 pData->ap.bssid) ||
3025 nla_put_u32(skb,
3026 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3027 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303028 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303029 pData->ap.rssi) ||
3030 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3031 pData->ap.rtt) ||
3032 nla_put_u32(skb,
3033 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3034 pData->ap.rtt_sd) ||
3035 nla_put_u16(skb,
3036 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3037 pData->ap.beaconPeriod) ||
3038 nla_put_u16(skb,
3039 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3040 pData->ap.capability) ||
3041 nla_put_u32(skb,
3042 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303043 pData->ieLength) ||
3044 nla_put_u8(skb,
3045 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3046 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303047 {
3048 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3049 goto nla_put_failure;
3050 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303051
3052 if (pData->ieLength) {
3053 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3054 pData->ieLength,
3055 pData->ie))
3056 {
3057 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3058 goto nla_put_failure;
3059 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303060 }
3061
3062 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303063 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303064 return;
3065
3066nla_put_failure:
3067 kfree_skb(skb);
3068 return;
3069}
3070
3071static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3072 void *pMsg)
3073{
3074 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3075 struct sk_buff *skb = NULL;
3076 tpSirEXTScanResultsAvailableIndParams pData =
3077 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3078
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303079 ENTER();
3080
3081 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303082 hddLog(LOGE,
3083 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303084 return;
3085 }
3086 if (!pMsg)
3087 {
3088 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303089 return;
3090 }
3091
3092 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303093#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3094 NULL,
3095#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303096 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3097 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3098 GFP_KERNEL);
3099
3100 if (!skb) {
3101 hddLog(VOS_TRACE_LEVEL_ERROR,
3102 FL("cfg80211_vendor_event_alloc failed"));
3103 return;
3104 }
3105
Dino Mycle6fb96c12014-06-10 11:52:40 +05303106 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3107 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3108 pData->numResultsAvailable);
3109 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3110 pData->requestId) ||
3111 nla_put_u32(skb,
3112 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3113 pData->numResultsAvailable)) {
3114 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3115 goto nla_put_failure;
3116 }
3117
3118 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303119 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303120 return;
3121
3122nla_put_failure:
3123 kfree_skb(skb);
3124 return;
3125}
3126
3127static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3128{
3129 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3130 struct sk_buff *skb = NULL;
3131 tpSirEXTScanProgressIndParams pData =
3132 (tpSirEXTScanProgressIndParams) pMsg;
3133
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303134 ENTER();
3135
3136 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303137 hddLog(LOGE,
3138 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303139 return;
3140 }
3141 if (!pMsg)
3142 {
3143 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303144 return;
3145 }
3146
3147 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303148#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3149 NULL,
3150#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303151 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3152 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3153 GFP_KERNEL);
3154
3155 if (!skb) {
3156 hddLog(VOS_TRACE_LEVEL_ERROR,
3157 FL("cfg80211_vendor_event_alloc failed"));
3158 return;
3159 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303160 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303161 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3162 pData->extScanEventType);
3163 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3164 pData->status);
3165
3166 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3167 pData->extScanEventType) ||
3168 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303169 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3170 pData->requestId) ||
3171 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303172 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3173 pData->status)) {
3174 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3175 goto nla_put_failure;
3176 }
3177
3178 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303179 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303180 return;
3181
3182nla_put_failure:
3183 kfree_skb(skb);
3184 return;
3185}
3186
3187void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3188 void *pMsg)
3189{
3190 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3191
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303192 ENTER();
3193
Dino Mycle6fb96c12014-06-10 11:52:40 +05303194 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303195 return;
3196 }
3197
3198 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3199
3200
3201 switch(evType) {
3202 case SIR_HAL_EXTSCAN_START_RSP:
3203 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3204 break;
3205
3206 case SIR_HAL_EXTSCAN_STOP_RSP:
3207 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3208 break;
3209 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3210 /* There is no need to send this response to upper layer
3211 Just log the message */
3212 hddLog(VOS_TRACE_LEVEL_INFO,
3213 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3214 break;
3215 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3216 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3217 break;
3218
3219 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3220 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3221 break;
3222
Dino Mycle6fb96c12014-06-10 11:52:40 +05303223 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303224 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303225 break;
3226 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3227 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3228 break;
3229 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3230 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3231 break;
3232 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3233 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3234 break;
3235 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3236 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3237 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303238 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3239 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3240 break;
3241 default:
3242 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3243 break;
3244 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303245 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303246}
3247
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303248static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3249 struct wireless_dev *wdev,
3250 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303251{
Dino Myclee8843b32014-07-04 14:21:45 +05303252 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303253 struct net_device *dev = wdev->netdev;
3254 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3255 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3256 struct nlattr
3257 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3258 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303259 struct hdd_ext_scan_context *context;
3260 unsigned long rc;
3261 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303262
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303263 ENTER();
3264
Dino Mycle6fb96c12014-06-10 11:52:40 +05303265 status = wlan_hdd_validate_context(pHddCtx);
3266 if (0 != status)
3267 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303268 return -EINVAL;
3269 }
Dino Myclee8843b32014-07-04 14:21:45 +05303270 /* check the EXTScan Capability */
3271 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303272 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3273 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303274 {
3275 hddLog(VOS_TRACE_LEVEL_ERROR,
3276 FL("EXTScan not enabled/supported by Firmware"));
3277 return -EINVAL;
3278 }
3279
Dino Mycle6fb96c12014-06-10 11:52:40 +05303280 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3281 data, dataLen,
3282 wlan_hdd_extscan_config_policy)) {
3283 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3284 return -EINVAL;
3285 }
3286
3287 /* Parse and fetch request Id */
3288 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3289 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3290 return -EINVAL;
3291 }
3292
Dino Myclee8843b32014-07-04 14:21:45 +05303293 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303294 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303295 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303296
Dino Myclee8843b32014-07-04 14:21:45 +05303297 reqMsg.sessionId = pAdapter->sessionId;
3298 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303299
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303300 vos_spin_lock_acquire(&hdd_context_lock);
3301 context = &pHddCtx->ext_scan_context;
3302 context->request_id = reqMsg.requestId;
3303 INIT_COMPLETION(context->response_event);
3304 vos_spin_lock_release(&hdd_context_lock);
3305
Dino Myclee8843b32014-07-04 14:21:45 +05303306 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303307 if (!HAL_STATUS_SUCCESS(status)) {
3308 hddLog(VOS_TRACE_LEVEL_ERROR,
3309 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303310 return -EINVAL;
3311 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303312
3313 rc = wait_for_completion_timeout(&context->response_event,
3314 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3315 if (!rc) {
3316 hddLog(LOGE, FL("Target response timed out"));
3317 return -ETIMEDOUT;
3318 }
3319
3320 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3321 if (ret)
3322 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3323
3324 return ret;
3325
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303326 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303327 return 0;
3328}
3329
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303330static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3331 struct wireless_dev *wdev,
3332 const void *data, int dataLen)
3333{
3334 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303335
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303336 vos_ssr_protect(__func__);
3337 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3338 vos_ssr_unprotect(__func__);
3339
3340 return ret;
3341}
3342
3343static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3344 struct wireless_dev *wdev,
3345 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303346{
Dino Myclee8843b32014-07-04 14:21:45 +05303347 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303348 struct net_device *dev = wdev->netdev;
3349 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3350 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3351 struct nlattr
3352 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3353 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303354 struct hdd_ext_scan_context *context;
3355 unsigned long rc;
3356 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303357
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303358 ENTER();
3359
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303360 if (VOS_FTM_MODE == hdd_get_conparam()) {
3361 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3362 return -EINVAL;
3363 }
3364
Dino Mycle6fb96c12014-06-10 11:52:40 +05303365 status = wlan_hdd_validate_context(pHddCtx);
3366 if (0 != status)
3367 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303368 return -EINVAL;
3369 }
Dino Myclee8843b32014-07-04 14:21:45 +05303370 /* check the EXTScan Capability */
3371 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303372 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3373 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303374 {
3375 hddLog(VOS_TRACE_LEVEL_ERROR,
3376 FL("EXTScan not enabled/supported by Firmware"));
3377 return -EINVAL;
3378 }
3379
Dino Mycle6fb96c12014-06-10 11:52:40 +05303380 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3381 data, dataLen,
3382 wlan_hdd_extscan_config_policy)) {
3383 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3384 return -EINVAL;
3385 }
3386 /* Parse and fetch request Id */
3387 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3388 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3389 return -EINVAL;
3390 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303391
Dino Myclee8843b32014-07-04 14:21:45 +05303392 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303393 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3394
Dino Myclee8843b32014-07-04 14:21:45 +05303395 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303396
Dino Myclee8843b32014-07-04 14:21:45 +05303397 reqMsg.sessionId = pAdapter->sessionId;
3398 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303399
3400 /* Parse and fetch flush parameter */
3401 if (!tb
3402 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3403 {
3404 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3405 goto failed;
3406 }
Dino Myclee8843b32014-07-04 14:21:45 +05303407 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303408 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3409
Dino Myclee8843b32014-07-04 14:21:45 +05303410 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303411
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303412 spin_lock(&hdd_context_lock);
3413 context = &pHddCtx->ext_scan_context;
3414 context->request_id = reqMsg.requestId;
3415 context->ignore_cached_results = false;
3416 INIT_COMPLETION(context->response_event);
3417 spin_unlock(&hdd_context_lock);
3418
Dino Myclee8843b32014-07-04 14:21:45 +05303419 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303420 if (!HAL_STATUS_SUCCESS(status)) {
3421 hddLog(VOS_TRACE_LEVEL_ERROR,
3422 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303423 return -EINVAL;
3424 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303425
3426 rc = wait_for_completion_timeout(&context->response_event,
3427 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3428 if (!rc) {
3429 hddLog(LOGE, FL("Target response timed out"));
3430 retval = -ETIMEDOUT;
3431 spin_lock(&hdd_context_lock);
3432 context->ignore_cached_results = true;
3433 spin_unlock(&hdd_context_lock);
3434 } else {
3435 spin_lock(&hdd_context_lock);
3436 retval = context->response_status;
3437 spin_unlock(&hdd_context_lock);
3438 }
3439
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303440 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303441 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303442
3443failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303444 return -EINVAL;
3445}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303446static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3447 struct wireless_dev *wdev,
3448 const void *data, int dataLen)
3449{
3450 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303451
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303452 vos_ssr_protect(__func__);
3453 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3454 vos_ssr_unprotect(__func__);
3455
3456 return ret;
3457}
3458
3459static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303461 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303462{
3463 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3464 struct net_device *dev = wdev->netdev;
3465 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3466 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3467 struct nlattr
3468 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3469 struct nlattr
3470 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3471 struct nlattr *apTh;
3472 eHalStatus status;
3473 tANI_U8 i = 0;
3474 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303475 struct hdd_ext_scan_context *context;
3476 tANI_U32 request_id;
3477 unsigned long rc;
3478 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303479
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303480 ENTER();
3481
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303482 if (VOS_FTM_MODE == hdd_get_conparam()) {
3483 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3484 return -EINVAL;
3485 }
3486
Dino Mycle6fb96c12014-06-10 11:52:40 +05303487 status = wlan_hdd_validate_context(pHddCtx);
3488 if (0 != status)
3489 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303490 return -EINVAL;
3491 }
Dino Myclee8843b32014-07-04 14:21:45 +05303492 /* check the EXTScan Capability */
3493 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303494 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3495 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303496 {
3497 hddLog(VOS_TRACE_LEVEL_ERROR,
3498 FL("EXTScan not enabled/supported by Firmware"));
3499 return -EINVAL;
3500 }
3501
Dino Mycle6fb96c12014-06-10 11:52:40 +05303502 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3503 data, dataLen,
3504 wlan_hdd_extscan_config_policy)) {
3505 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3506 return -EINVAL;
3507 }
3508
3509 /* Parse and fetch request Id */
3510 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3511 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3512 return -EINVAL;
3513 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303514 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3515 vos_mem_malloc(sizeof(*pReqMsg));
3516 if (!pReqMsg) {
3517 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3518 return -ENOMEM;
3519 }
3520
Dino Myclee8843b32014-07-04 14:21:45 +05303521
Dino Mycle6fb96c12014-06-10 11:52:40 +05303522 pReqMsg->requestId = nla_get_u32(
3523 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3524 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3525
3526 /* Parse and fetch number of APs */
3527 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3528 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3529 goto fail;
3530 }
3531
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303532 /* Parse and fetch lost ap sample size */
3533 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3534 hddLog(LOGE, FL("attr lost ap sample size failed"));
3535 goto fail;
3536 }
3537
3538 pReqMsg->lostBssidSampleSize = nla_get_u32(
3539 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3540 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3541
Dino Mycle6fb96c12014-06-10 11:52:40 +05303542 pReqMsg->sessionId = pAdapter->sessionId;
3543 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3544
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303545 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303546 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05303547 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
3548 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
3549 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
3550 goto fail;
3551 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303552 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303553
3554 nla_for_each_nested(apTh,
3555 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05303556 if (i == pReqMsg->numBssid) {
3557 hddLog(LOGW, FL("Ignoring excess AP"));
3558 break;
3559 }
3560
Dino Mycle6fb96c12014-06-10 11:52:40 +05303561 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3562 nla_data(apTh), nla_len(apTh),
3563 NULL)) {
3564 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3565 goto fail;
3566 }
3567
3568 /* Parse and fetch MAC address */
3569 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3570 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3571 goto fail;
3572 }
3573 memcpy(pReqMsg->ap[i].bssid, nla_data(
3574 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3575 sizeof(tSirMacAddr));
3576 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3577
3578 /* Parse and fetch low RSSI */
3579 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3580 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3581 goto fail;
3582 }
3583 pReqMsg->ap[i].low = nla_get_s32(
3584 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3585 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3586
3587 /* Parse and fetch high RSSI */
3588 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3589 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3590 goto fail;
3591 }
3592 pReqMsg->ap[i].high = nla_get_s32(
3593 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3594 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3595 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303596 i++;
3597 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303598
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05303599 if (i < pReqMsg->numBssid) {
3600 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
3601 i, pReqMsg->numBssid);
3602 pReqMsg->numBssid = i;
3603 }
3604
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303605 context = &pHddCtx->ext_scan_context;
3606 spin_lock(&hdd_context_lock);
3607 INIT_COMPLETION(context->response_event);
3608 context->request_id = request_id = pReqMsg->requestId;
3609 spin_unlock(&hdd_context_lock);
3610
Dino Mycle6fb96c12014-06-10 11:52:40 +05303611 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3612 if (!HAL_STATUS_SUCCESS(status)) {
3613 hddLog(VOS_TRACE_LEVEL_ERROR,
3614 FL("sme_SetBssHotlist failed(err=%d)"), status);
3615 vos_mem_free(pReqMsg);
3616 return -EINVAL;
3617 }
3618
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303619 /* request was sent -- wait for the response */
3620 rc = wait_for_completion_timeout(&context->response_event,
3621 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3622
3623 if (!rc) {
3624 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3625 retval = -ETIMEDOUT;
3626 } else {
3627 spin_lock(&hdd_context_lock);
3628 if (context->request_id == request_id)
3629 retval = context->response_status;
3630 else
3631 retval = -EINVAL;
3632 spin_unlock(&hdd_context_lock);
3633 }
3634
Dino Myclee8843b32014-07-04 14:21:45 +05303635 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303636 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303637 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303638
3639fail:
3640 vos_mem_free(pReqMsg);
3641 return -EINVAL;
3642}
3643
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303644static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3645 struct wireless_dev *wdev,
3646 const void *data, int dataLen)
3647{
3648 int ret = 0;
3649
3650 vos_ssr_protect(__func__);
3651 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3652 dataLen);
3653 vos_ssr_unprotect(__func__);
3654
3655 return ret;
3656}
3657
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303658static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303659 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303660 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303661{
Agrawal Ashish16abf782016-08-18 22:42:59 +05303662 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3663 struct net_device *dev = wdev->netdev;
3664 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3665 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3666 uint8_t num_channels = 0;
3667 uint8_t num_chan_new = 0;
3668 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05303669 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05303670 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303671 tWifiBand wifiBand;
3672 eHalStatus status;
3673 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05303674 tANI_U8 i,j,k;
3675 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303676
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303677 ENTER();
3678
Dino Mycle6fb96c12014-06-10 11:52:40 +05303679 status = wlan_hdd_validate_context(pHddCtx);
3680 if (0 != status)
3681 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303682 return -EINVAL;
3683 }
Dino Myclee8843b32014-07-04 14:21:45 +05303684
Dino Mycle6fb96c12014-06-10 11:52:40 +05303685 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3686 data, dataLen,
3687 wlan_hdd_extscan_config_policy)) {
3688 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3689 return -EINVAL;
3690 }
3691
3692 /* Parse and fetch request Id */
3693 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3695 return -EINVAL;
3696 }
3697 requestId = nla_get_u32(
3698 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3699 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3700
3701 /* Parse and fetch wifi band */
3702 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3703 {
3704 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3705 return -EINVAL;
3706 }
3707 wifiBand = nla_get_u32(
3708 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3709 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3710
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05303711 /* Parse and fetch max channels */
3712 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
3713 {
3714 hddLog(LOGE, FL("attr max channels failed"));
3715 return -EINVAL;
3716 }
3717 maxChannels = nla_get_u32(
3718 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
3719 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
3720
Dino Mycle6fb96c12014-06-10 11:52:40 +05303721 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05303722 wifiBand, chan_list,
3723 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303724 if (eHAL_STATUS_SUCCESS != status) {
3725 hddLog(VOS_TRACE_LEVEL_ERROR,
3726 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3727 return -EINVAL;
3728 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05303729
Agrawal Ashish16abf782016-08-18 22:42:59 +05303730 num_channels = VOS_MIN(num_channels, maxChannels);
3731 num_chan_new = num_channels;
3732 /* remove the indoor only channels if iface is SAP */
3733 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
3734 {
3735 num_chan_new = 0;
3736 for (i = 0; i < num_channels; i++)
3737 for (j = 0; j < IEEE80211_NUM_BANDS; j++) {
3738 if (wiphy->bands[j] == NULL)
3739 continue;
3740 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
3741 if ((chan_list[i] ==
3742 wiphy->bands[j]->channels[k].center_freq) &&
3743 (!(wiphy->bands[j]->channels[k].flags &
3744 IEEE80211_CHAN_INDOOR_ONLY))) {
3745 chan_list[num_chan_new] = chan_list[i];
3746 num_chan_new++;
3747 }
3748 }
3749 }
3750 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05303751
Agrawal Ashish16abf782016-08-18 22:42:59 +05303752 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
3753 for (i = 0; i < num_chan_new; i++)
3754 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
3755 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303756
3757 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05303758 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05303759 NLMSG_HDRLEN);
3760
3761 if (!replySkb) {
3762 hddLog(VOS_TRACE_LEVEL_ERROR,
3763 FL("valid channels: buffer alloc fail"));
3764 return -EINVAL;
3765 }
3766 if (nla_put_u32(replySkb,
3767 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05303768 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303769 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05303770 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303771
3772 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3773 kfree_skb(replySkb);
3774 return -EINVAL;
3775 }
3776
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303777 ret = cfg80211_vendor_cmd_reply(replySkb);
3778
3779 EXIT();
3780 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303781}
3782
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303783static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3784 struct wireless_dev *wdev,
3785 const void *data, int dataLen)
3786{
3787 int ret = 0;
3788
3789 vos_ssr_protect(__func__);
3790 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
3791 dataLen);
3792 vos_ssr_unprotect(__func__);
3793
3794 return ret;
3795}
3796
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303797static int hdd_extscan_start_fill_bucket_channel_spec(
3798 hdd_context_t *pHddCtx,
3799 tpSirEXTScanStartReqParams pReqMsg,
3800 struct nlattr **tb)
3801{
3802 struct nlattr *bucket[
3803 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3804 struct nlattr *channel[
3805 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3806 struct nlattr *buckets;
3807 struct nlattr *channels;
3808 int rem1, rem2;
3809 eHalStatus status;
3810 tANI_U8 bktIndex, j, numChannels;
3811 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3812 tANI_U32 passive_max_chn_time, active_max_chn_time;
3813
3814 bktIndex = 0;
3815
3816 nla_for_each_nested(buckets,
3817 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3818 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05303819 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3820 nla_data(buckets), nla_len(buckets),
3821 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303822 hddLog(LOGE, FL("nla_parse failed"));
3823 return -EINVAL;
3824 }
3825
3826 /* Parse and fetch bucket spec */
3827 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3828 hddLog(LOGE, FL("attr bucket index failed"));
3829 return -EINVAL;
3830 }
3831 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
3832 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3833 hddLog(LOG1, FL("Bucket spec Index %d"),
3834 pReqMsg->buckets[bktIndex].bucket);
3835
3836 /* Parse and fetch wifi band */
3837 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3838 hddLog(LOGE, FL("attr wifi band failed"));
3839 return -EINVAL;
3840 }
3841 pReqMsg->buckets[bktIndex].band = nla_get_u8(
3842 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3843 hddLog(LOG1, FL("Wifi band %d"),
3844 pReqMsg->buckets[bktIndex].band);
3845
3846 /* Parse and fetch period */
3847 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3848 hddLog(LOGE, FL("attr period failed"));
3849 return -EINVAL;
3850 }
3851 pReqMsg->buckets[bktIndex].period = nla_get_u32(
3852 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3853 hddLog(LOG1, FL("period %d"),
3854 pReqMsg->buckets[bktIndex].period);
3855
3856 /* Parse and fetch report events */
3857 if (!bucket[
3858 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3859 hddLog(LOGE, FL("attr report events failed"));
3860 return -EINVAL;
3861 }
3862 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
3863 bucket[
3864 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3865 hddLog(LOG1, FL("report events %d"),
3866 pReqMsg->buckets[bktIndex].reportEvents);
3867
3868 /* Parse and fetch max period */
3869 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
3870 hddLog(LOGE, FL("attr max period failed"));
3871 return -EINVAL;
3872 }
3873 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
3874 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
3875 hddLog(LOG1, FL("max period %u"),
3876 pReqMsg->buckets[bktIndex].max_period);
3877
3878 /* Parse and fetch exponent */
3879 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
3880 hddLog(LOGE, FL("attr exponent failed"));
3881 return -EINVAL;
3882 }
3883 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
3884 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
3885 hddLog(LOG1, FL("exponent %u"),
3886 pReqMsg->buckets[bktIndex].exponent);
3887
3888 /* Parse and fetch step count */
3889 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
3890 hddLog(LOGE, FL("attr step count failed"));
3891 return -EINVAL;
3892 }
3893 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
3894 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
3895 hddLog(LOG1, FL("Step count %u"),
3896 pReqMsg->buckets[bktIndex].step_count);
3897
3898 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
3899 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
3900
3901 /* Framework shall pass the channel list if the input WiFi band is
3902 * WIFI_BAND_UNSPECIFIED.
3903 * If the input WiFi band is specified (any value other than
3904 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
3905 */
3906 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
3907 numChannels = 0;
3908 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
3909 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
3910 pReqMsg->buckets[bktIndex].band,
3911 chanList, &numChannels);
3912 if (!HAL_STATUS_SUCCESS(status)) {
3913 hddLog(LOGE,
3914 FL("sme_GetValidChannelsByBand failed (err=%d)"),
3915 status);
3916 return -EINVAL;
3917 }
3918
3919 pReqMsg->buckets[bktIndex].numChannels =
3920 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
3921 hddLog(LOG1, FL("Num channels %d"),
3922 pReqMsg->buckets[bktIndex].numChannels);
3923
3924 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
3925 j++) {
3926 pReqMsg->buckets[bktIndex].channels[j].channel =
3927 chanList[j];
3928 pReqMsg->buckets[bktIndex].channels[j].
3929 chnlClass = 0;
3930 if (CSR_IS_CHANNEL_DFS(
3931 vos_freq_to_chan(chanList[j]))) {
3932 pReqMsg->buckets[bktIndex].channels[j].
3933 passive = 1;
3934 pReqMsg->buckets[bktIndex].channels[j].
3935 dwellTimeMs = passive_max_chn_time;
3936 } else {
3937 pReqMsg->buckets[bktIndex].channels[j].
3938 passive = 0;
3939 pReqMsg->buckets[bktIndex].channels[j].
3940 dwellTimeMs = active_max_chn_time;
3941 }
3942
3943 hddLog(LOG1,
3944 "Channel %u Passive %u Dwell time %u ms",
3945 pReqMsg->buckets[bktIndex].channels[j].channel,
3946 pReqMsg->buckets[bktIndex].channels[j].passive,
3947 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
3948 }
3949
3950 bktIndex++;
3951 continue;
3952 }
3953
3954 /* Parse and fetch number of channels */
3955 if (!bucket[
3956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
3957 hddLog(LOGE, FL("attr num channels failed"));
3958 return -EINVAL;
3959 }
3960
3961 pReqMsg->buckets[bktIndex].numChannels =
3962 nla_get_u32(bucket[
3963 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3964 hddLog(LOG1, FL("num channels %d"),
3965 pReqMsg->buckets[bktIndex].numChannels);
3966
3967 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3968 hddLog(LOGE, FL("attr channel spec failed"));
3969 return -EINVAL;
3970 }
3971
3972 j = 0;
3973 nla_for_each_nested(channels,
3974 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3975 if (nla_parse(channel,
3976 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3977 nla_data(channels), nla_len(channels),
3978 wlan_hdd_extscan_config_policy)) {
3979 hddLog(LOGE, FL("nla_parse failed"));
3980 return -EINVAL;
3981 }
3982
3983 /* Parse and fetch channel */
3984 if (!channel[
3985 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3986 hddLog(LOGE, FL("attr channel failed"));
3987 return -EINVAL;
3988 }
3989 pReqMsg->buckets[bktIndex].channels[j].channel =
3990 nla_get_u32(channel[
3991 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3992 hddLog(LOG1, FL("channel %u"),
3993 pReqMsg->buckets[bktIndex].channels[j].channel);
3994
3995 /* Parse and fetch dwell time */
3996 if (!channel[
3997 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3998 hddLog(LOGE, FL("attr dwelltime failed"));
3999 return -EINVAL;
4000 }
4001 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4002 nla_get_u32(channel[
4003 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4004
4005 hddLog(LOG1, FL("Dwell time (%u ms)"),
4006 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4007
4008
4009 /* Parse and fetch channel spec passive */
4010 if (!channel[
4011 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4012 hddLog(LOGE,
4013 FL("attr channel spec passive failed"));
4014 return -EINVAL;
4015 }
4016 pReqMsg->buckets[bktIndex].channels[j].passive =
4017 nla_get_u8(channel[
4018 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4019 hddLog(LOG1, FL("Chnl spec passive %u"),
4020 pReqMsg->buckets[bktIndex].channels[j].passive);
4021
4022 j++;
4023 }
4024
4025 bktIndex++;
4026 }
4027
4028 return 0;
4029}
4030
4031
4032/*
4033 * define short names for the global vendor params
4034 * used by wlan_hdd_cfg80211_extscan_start()
4035 */
4036#define PARAM_MAX \
4037QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4038#define PARAM_REQUEST_ID \
4039QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4040#define PARAM_BASE_PERIOD \
4041QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4042#define PARAM_MAX_AP_PER_SCAN \
4043QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4044#define PARAM_RPT_THRHLD_PERCENT \
4045QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4046#define PARAM_RPT_THRHLD_NUM_SCANS \
4047QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4048#define PARAM_NUM_BUCKETS \
4049QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4050
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304051static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304052 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304053 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304054{
Dino Myclee8843b32014-07-04 14:21:45 +05304055 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304056 struct net_device *dev = wdev->netdev;
4057 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4058 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4059 struct nlattr *tb[PARAM_MAX + 1];
4060 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304061 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304062 tANI_U32 request_id;
4063 struct hdd_ext_scan_context *context;
4064 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304065
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304066 ENTER();
4067
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304068 if (VOS_FTM_MODE == hdd_get_conparam()) {
4069 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4070 return -EINVAL;
4071 }
4072
Dino Mycle6fb96c12014-06-10 11:52:40 +05304073 status = wlan_hdd_validate_context(pHddCtx);
4074 if (0 != status)
4075 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304076 return -EINVAL;
4077 }
Dino Myclee8843b32014-07-04 14:21:45 +05304078 /* check the EXTScan Capability */
4079 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304080 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4081 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304082 {
4083 hddLog(VOS_TRACE_LEVEL_ERROR,
4084 FL("EXTScan not enabled/supported by Firmware"));
4085 return -EINVAL;
4086 }
4087
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304088 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304089 data, dataLen,
4090 wlan_hdd_extscan_config_policy)) {
4091 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4092 return -EINVAL;
4093 }
4094
4095 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304096 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304097 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4098 return -EINVAL;
4099 }
4100
Dino Myclee8843b32014-07-04 14:21:45 +05304101 pReqMsg = (tpSirEXTScanStartReqParams)
4102 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304103 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304104 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4105 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304106 }
4107
4108 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304109 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304110 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4111
4112 pReqMsg->sessionId = pAdapter->sessionId;
4113 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4114
4115 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304116 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304117 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4118 goto fail;
4119 }
4120 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304121 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304122 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4123 pReqMsg->basePeriod);
4124
4125 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304126 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304127 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4128 goto fail;
4129 }
4130 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304131 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304132 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4133 pReqMsg->maxAPperScan);
4134
4135 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304136 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304137 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4138 goto fail;
4139 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304140 pReqMsg->reportThresholdPercent = nla_get_u8(
4141 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304142 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304143 pReqMsg->reportThresholdPercent);
4144
4145 /* Parse and fetch report threshold num scans */
4146 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4147 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4148 goto fail;
4149 }
4150 pReqMsg->reportThresholdNumScans = nla_get_u8(
4151 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4152 hddLog(LOG1, FL("Report Threshold num scans %d"),
4153 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304154
4155 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304156 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304157 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4158 goto fail;
4159 }
4160 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304161 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304162 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4163 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4164 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4165 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4166 }
4167 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4168 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304169
Dino Mycle6fb96c12014-06-10 11:52:40 +05304170 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4171 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4172 goto fail;
4173 }
4174
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304175 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304176
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304177 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4178 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304179
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304180 context = &pHddCtx->ext_scan_context;
4181 spin_lock(&hdd_context_lock);
4182 INIT_COMPLETION(context->response_event);
4183 context->request_id = request_id = pReqMsg->requestId;
4184 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304185
Dino Mycle6fb96c12014-06-10 11:52:40 +05304186 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4187 if (!HAL_STATUS_SUCCESS(status)) {
4188 hddLog(VOS_TRACE_LEVEL_ERROR,
4189 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304190 goto fail;
4191 }
4192
Srinivas Dasari91727c12016-03-23 17:59:06 +05304193 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
4194
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304195 /* request was sent -- wait for the response */
4196 rc = wait_for_completion_timeout(&context->response_event,
4197 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4198
4199 if (!rc) {
4200 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4201 retval = -ETIMEDOUT;
4202 } else {
4203 spin_lock(&hdd_context_lock);
4204 if (context->request_id == request_id)
4205 retval = context->response_status;
4206 else
4207 retval = -EINVAL;
4208 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304209 }
4210
Dino Myclee8843b32014-07-04 14:21:45 +05304211 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304212 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304213 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304214
4215fail:
4216 vos_mem_free(pReqMsg);
4217 return -EINVAL;
4218}
4219
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304220/*
4221 * done with short names for the global vendor params
4222 * used by wlan_hdd_cfg80211_extscan_start()
4223 */
4224#undef PARAM_MAX
4225#undef PARAM_REQUEST_ID
4226#undef PARAM_BASE_PERIOD
4227#undef PARAMS_MAX_AP_PER_SCAN
4228#undef PARAMS_RPT_THRHLD_PERCENT
4229#undef PARAMS_RPT_THRHLD_NUM_SCANS
4230#undef PARAMS_NUM_BUCKETS
4231
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304232static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4233 struct wireless_dev *wdev,
4234 const void *data, int dataLen)
4235{
4236 int ret = 0;
4237
4238 vos_ssr_protect(__func__);
4239 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4240 vos_ssr_unprotect(__func__);
4241
4242 return ret;
4243}
4244
4245static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304246 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304247 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304248{
Dino Myclee8843b32014-07-04 14:21:45 +05304249 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304250 struct net_device *dev = wdev->netdev;
4251 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4252 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4253 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4254 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304255 int retval;
4256 unsigned long rc;
4257 struct hdd_ext_scan_context *context;
4258 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304259
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304260 ENTER();
4261
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304262 if (VOS_FTM_MODE == hdd_get_conparam()) {
4263 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4264 return -EINVAL;
4265 }
4266
Dino Mycle6fb96c12014-06-10 11:52:40 +05304267 status = wlan_hdd_validate_context(pHddCtx);
4268 if (0 != status)
4269 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304270 return -EINVAL;
4271 }
Dino Myclee8843b32014-07-04 14:21:45 +05304272 /* check the EXTScan Capability */
4273 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304274 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4275 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304276 {
4277 hddLog(VOS_TRACE_LEVEL_ERROR,
4278 FL("EXTScan not enabled/supported by Firmware"));
4279 return -EINVAL;
4280 }
4281
Dino Mycle6fb96c12014-06-10 11:52:40 +05304282 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4283 data, dataLen,
4284 wlan_hdd_extscan_config_policy)) {
4285 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4286 return -EINVAL;
4287 }
4288
4289 /* Parse and fetch request Id */
4290 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4291 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4292 return -EINVAL;
4293 }
4294
Dino Myclee8843b32014-07-04 14:21:45 +05304295 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304296 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304297 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304298
Dino Myclee8843b32014-07-04 14:21:45 +05304299 reqMsg.sessionId = pAdapter->sessionId;
4300 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304301
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304302 context = &pHddCtx->ext_scan_context;
4303 spin_lock(&hdd_context_lock);
4304 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05304305 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304306 spin_unlock(&hdd_context_lock);
4307
Dino Myclee8843b32014-07-04 14:21:45 +05304308 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304309 if (!HAL_STATUS_SUCCESS(status)) {
4310 hddLog(VOS_TRACE_LEVEL_ERROR,
4311 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304312 return -EINVAL;
4313 }
4314
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304315 /* request was sent -- wait for the response */
4316 rc = wait_for_completion_timeout(&context->response_event,
4317 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4318
4319 if (!rc) {
4320 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4321 retval = -ETIMEDOUT;
4322 } else {
4323 spin_lock(&hdd_context_lock);
4324 if (context->request_id == request_id)
4325 retval = context->response_status;
4326 else
4327 retval = -EINVAL;
4328 spin_unlock(&hdd_context_lock);
4329 }
4330
4331 return retval;
4332
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304333 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304334 return 0;
4335}
4336
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304337static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4338 struct wireless_dev *wdev,
4339 const void *data, int dataLen)
4340{
4341 int ret = 0;
4342
4343 vos_ssr_protect(__func__);
4344 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4345 vos_ssr_unprotect(__func__);
4346
4347 return ret;
4348}
4349
4350static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304351 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304352 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304353{
Dino Myclee8843b32014-07-04 14:21:45 +05304354 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304355 struct net_device *dev = wdev->netdev;
4356 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4357 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4358 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4359 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304360 struct hdd_ext_scan_context *context;
4361 tANI_U32 request_id;
4362 unsigned long rc;
4363 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304364
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304365 ENTER();
4366
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304367 if (VOS_FTM_MODE == hdd_get_conparam()) {
4368 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4369 return -EINVAL;
4370 }
4371
Dino Mycle6fb96c12014-06-10 11:52:40 +05304372 status = wlan_hdd_validate_context(pHddCtx);
4373 if (0 != status)
4374 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304375 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304376 return -EINVAL;
4377 }
Dino Myclee8843b32014-07-04 14:21:45 +05304378 /* check the EXTScan Capability */
4379 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304380 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4381 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304382 {
4383 hddLog(VOS_TRACE_LEVEL_ERROR,
4384 FL("EXTScan not enabled/supported by Firmware"));
4385 return -EINVAL;
4386 }
4387
Dino Mycle6fb96c12014-06-10 11:52:40 +05304388 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4389 data, dataLen,
4390 wlan_hdd_extscan_config_policy)) {
4391 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4392 return -EINVAL;
4393 }
4394
4395 /* Parse and fetch request Id */
4396 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4397 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4398 return -EINVAL;
4399 }
4400
Dino Myclee8843b32014-07-04 14:21:45 +05304401 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304402 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304403 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304404
Dino Myclee8843b32014-07-04 14:21:45 +05304405 reqMsg.sessionId = pAdapter->sessionId;
4406 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304407
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304408 context = &pHddCtx->ext_scan_context;
4409 spin_lock(&hdd_context_lock);
4410 INIT_COMPLETION(context->response_event);
4411 context->request_id = request_id = reqMsg.requestId;
4412 spin_unlock(&hdd_context_lock);
4413
Dino Myclee8843b32014-07-04 14:21:45 +05304414 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304415 if (!HAL_STATUS_SUCCESS(status)) {
4416 hddLog(VOS_TRACE_LEVEL_ERROR,
4417 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304418 return -EINVAL;
4419 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304420
4421 /* request was sent -- wait for the response */
4422 rc = wait_for_completion_timeout(&context->response_event,
4423 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4424 if (!rc) {
4425 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4426 retval = -ETIMEDOUT;
4427 } else {
4428 spin_lock(&hdd_context_lock);
4429 if (context->request_id == request_id)
4430 retval = context->response_status;
4431 else
4432 retval = -EINVAL;
4433 spin_unlock(&hdd_context_lock);
4434 }
4435
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304436 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304437 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304438}
4439
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304440static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4441 struct wireless_dev *wdev,
4442 const void *data, int dataLen)
4443{
4444 int ret = 0;
4445
4446 vos_ssr_protect(__func__);
4447 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4448 vos_ssr_unprotect(__func__);
4449
4450 return ret;
4451}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304452#endif /* WLAN_FEATURE_EXTSCAN */
4453
Atul Mittal115287b2014-07-08 13:26:33 +05304454/*EXT TDLS*/
4455static const struct nla_policy
4456wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4457{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05304458 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
4459 .type = NLA_UNSPEC,
4460 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05304461 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4462 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4463 {.type = NLA_S32 },
4464 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4465 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4466
4467};
4468
4469static const struct nla_policy
4470wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4471{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05304472 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
4473 .type = NLA_UNSPEC,
4474 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05304475
4476};
4477
4478static const struct nla_policy
4479wlan_hdd_tdls_config_state_change_policy[
4480 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4481{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05304482 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
4483 .type = NLA_UNSPEC,
4484 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05304485 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4486 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304487 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4488 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4489 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304490
4491};
4492
4493static const struct nla_policy
4494wlan_hdd_tdls_config_get_status_policy[
4495 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4496{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05304497 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
4498 .type = NLA_UNSPEC,
4499 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05304500 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4501 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304502 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4503 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4504 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304505
4506};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304507
4508static const struct nla_policy
4509wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4510{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05304511 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
4512 .type = NLA_UNSPEC,
4513 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304514};
4515
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304516static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304517 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304518 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304519 int data_len)
4520{
4521
4522 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4523 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4524
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304525 ENTER();
4526
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304527 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304528 return -EINVAL;
4529 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05304530 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05304531 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304532 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304533 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304534 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05304535 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304536 return -ENOTSUPP;
4537 }
4538
4539 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4540 data, data_len, wlan_hdd_mac_config)) {
4541 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4542 return -EINVAL;
4543 }
4544
4545 /* Parse and fetch mac address */
4546 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4547 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4548 return -EINVAL;
4549 }
4550
4551 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4552 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4553 VOS_MAC_ADDR_LAST_3_BYTES);
4554
Siddharth Bhal76972212014-10-15 16:22:51 +05304555 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4556
4557 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304558 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4559 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304560 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4561 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4562 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4563 {
4564 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4565 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4566 VOS_MAC_ADDRESS_LEN);
4567 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304568 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304569
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05304570 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
4571 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304572
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304573 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304574 return 0;
4575}
4576
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304577static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
4578 struct wireless_dev *wdev,
4579 const void *data,
4580 int data_len)
4581{
4582 int ret = 0;
4583
4584 vos_ssr_protect(__func__);
4585 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
4586 vos_ssr_unprotect(__func__);
4587
4588 return ret;
4589}
4590
4591static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304592 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304593 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304594 int data_len)
4595{
4596 u8 peer[6] = {0};
4597 struct net_device *dev = wdev->netdev;
4598 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4599 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4600 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4601 eHalStatus ret;
4602 tANI_S32 state;
4603 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304604 tANI_S32 global_operating_class = 0;
4605 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304606 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304607 int retVal;
4608
4609 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304610
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304611 if (!pAdapter) {
4612 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4613 return -EINVAL;
4614 }
4615
Atul Mittal115287b2014-07-08 13:26:33 +05304616 ret = wlan_hdd_validate_context(pHddCtx);
4617 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304618 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304619 return -EINVAL;
4620 }
4621 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304622 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304623 return -ENOTSUPP;
4624 }
4625 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4626 data, data_len,
4627 wlan_hdd_tdls_config_get_status_policy)) {
4628 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4629 return -EINVAL;
4630 }
4631
4632 /* Parse and fetch mac address */
4633 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4634 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4635 return -EINVAL;
4636 }
4637
4638 memcpy(peer, nla_data(
4639 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4640 sizeof(peer));
4641 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4642
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05304643 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05304644
Atul Mittal115287b2014-07-08 13:26:33 +05304645 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304646 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304647 NLMSG_HDRLEN);
4648
4649 if (!skb) {
4650 hddLog(VOS_TRACE_LEVEL_ERROR,
4651 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4652 return -EINVAL;
4653 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304654 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 +05304655 reason,
4656 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304657 global_operating_class,
4658 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304659 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304660 if (nla_put_s32(skb,
4661 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4662 state) ||
4663 nla_put_s32(skb,
4664 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4665 reason) ||
4666 nla_put_s32(skb,
4667 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4668 global_operating_class) ||
4669 nla_put_s32(skb,
4670 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4671 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304672
4673 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4674 goto nla_put_failure;
4675 }
4676
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304677 retVal = cfg80211_vendor_cmd_reply(skb);
4678 EXIT();
4679 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05304680
4681nla_put_failure:
4682 kfree_skb(skb);
4683 return -EINVAL;
4684}
4685
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304686static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4687 struct wireless_dev *wdev,
4688 const void *data,
4689 int data_len)
4690{
4691 int ret = 0;
4692
4693 vos_ssr_protect(__func__);
4694 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
4695 vos_ssr_unprotect(__func__);
4696
4697 return ret;
4698}
4699
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05304700static int wlan_hdd_cfg80211_exttdls_callback(
4701#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
4702 const tANI_U8* mac,
4703#else
4704 tANI_U8* mac,
4705#endif
Atul Mittal115287b2014-07-08 13:26:33 +05304706 tANI_S32 state,
4707 tANI_S32 reason,
4708 void *ctx)
4709{
4710 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05304711 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304712 tANI_S32 global_operating_class = 0;
4713 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304714 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05304715
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304716 ENTER();
4717
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304718 if (!pAdapter) {
4719 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4720 return -EINVAL;
4721 }
4722
4723 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05304724 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304726 return -EINVAL;
4727 }
4728
4729 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304730 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304731 return -ENOTSUPP;
4732 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304733 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
4734#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4735 NULL,
4736#endif
Atul Mittal115287b2014-07-08 13:26:33 +05304737 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4738 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4739 GFP_KERNEL);
4740
4741 if (!skb) {
4742 hddLog(VOS_TRACE_LEVEL_ERROR,
4743 FL("cfg80211_vendor_event_alloc failed"));
4744 return -EINVAL;
4745 }
4746 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304747 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4748 reason,
4749 state,
4750 global_operating_class,
4751 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304752 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4753 MAC_ADDR_ARRAY(mac));
4754
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304755 if (nla_put(skb,
4756 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4757 VOS_MAC_ADDR_SIZE, mac) ||
4758 nla_put_s32(skb,
4759 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4760 state) ||
4761 nla_put_s32(skb,
4762 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4763 reason) ||
4764 nla_put_s32(skb,
4765 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4766 channel) ||
4767 nla_put_s32(skb,
4768 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4769 global_operating_class)
4770 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304771 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4772 goto nla_put_failure;
4773 }
4774
4775 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304776 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05304777 return (0);
4778
4779nla_put_failure:
4780 kfree_skb(skb);
4781 return -EINVAL;
4782}
4783
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304784static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304785 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304786 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304787 int data_len)
4788{
4789 u8 peer[6] = {0};
4790 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304791 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4792 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4793 eHalStatus status;
4794 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304795 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304796 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304797
4798 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304799
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304800 if (!dev) {
4801 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4802 return -EINVAL;
4803 }
4804
4805 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4806 if (!pAdapter) {
4807 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4808 return -EINVAL;
4809 }
4810
Atul Mittal115287b2014-07-08 13:26:33 +05304811 status = wlan_hdd_validate_context(pHddCtx);
4812 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304813 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304814 return -EINVAL;
4815 }
4816 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304818 return -ENOTSUPP;
4819 }
4820 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4821 data, data_len,
4822 wlan_hdd_tdls_config_enable_policy)) {
4823 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4824 return -EINVAL;
4825 }
4826
4827 /* Parse and fetch mac address */
4828 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4829 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4830 return -EINVAL;
4831 }
4832
4833 memcpy(peer, nla_data(
4834 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4835 sizeof(peer));
4836 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4837
4838 /* Parse and fetch channel */
4839 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4840 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4841 return -EINVAL;
4842 }
4843 pReqMsg.channel = nla_get_s32(
4844 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4845 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4846
4847 /* Parse and fetch global operating class */
4848 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4849 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4850 return -EINVAL;
4851 }
4852 pReqMsg.global_operating_class = nla_get_s32(
4853 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4854 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4855 pReqMsg.global_operating_class);
4856
4857 /* Parse and fetch latency ms */
4858 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4859 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4860 return -EINVAL;
4861 }
4862 pReqMsg.max_latency_ms = nla_get_s32(
4863 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4864 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4865 pReqMsg.max_latency_ms);
4866
4867 /* Parse and fetch required bandwidth kbps */
4868 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4869 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4870 return -EINVAL;
4871 }
4872
4873 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4874 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4875 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4876 pReqMsg.min_bandwidth_kbps);
4877
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304878 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05304879 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05304880 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304881 wlan_hdd_cfg80211_exttdls_callback);
4882
4883 EXIT();
4884 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304885}
4886
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304887static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4888 struct wireless_dev *wdev,
4889 const void *data,
4890 int data_len)
4891{
4892 int ret = 0;
4893
4894 vos_ssr_protect(__func__);
4895 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
4896 vos_ssr_unprotect(__func__);
4897
4898 return ret;
4899}
4900
4901static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304902 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304903 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304904 int data_len)
4905{
4906 u8 peer[6] = {0};
4907 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304908 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4909 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4910 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304911 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304912 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304913
4914 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304915
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304916 if (!dev) {
4917 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4918 return -EINVAL;
4919 }
4920
4921 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4922 if (!pAdapter) {
4923 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
4924 return -EINVAL;
4925 }
4926
Atul Mittal115287b2014-07-08 13:26:33 +05304927 status = wlan_hdd_validate_context(pHddCtx);
4928 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304929 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304930 return -EINVAL;
4931 }
4932 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304933 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304934 return -ENOTSUPP;
4935 }
4936 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4937 data, data_len,
4938 wlan_hdd_tdls_config_disable_policy)) {
4939 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4940 return -EINVAL;
4941 }
4942 /* Parse and fetch mac address */
4943 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4944 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4945 return -EINVAL;
4946 }
4947
4948 memcpy(peer, nla_data(
4949 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4950 sizeof(peer));
4951 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4952
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304953 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
4954
4955 EXIT();
4956 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304957}
4958
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304959static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4960 struct wireless_dev *wdev,
4961 const void *data,
4962 int data_len)
4963{
4964 int ret = 0;
4965
4966 vos_ssr_protect(__func__);
4967 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
4968 vos_ssr_unprotect(__func__);
4969
4970 return ret;
4971}
4972
Dasari Srinivas7875a302014-09-26 17:50:57 +05304973static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304974__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05304975 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304976 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05304977{
4978 struct net_device *dev = wdev->netdev;
4979 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4980 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4981 struct sk_buff *skb = NULL;
4982 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304983 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05304984
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304985 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304986
4987 ret = wlan_hdd_validate_context(pHddCtx);
4988 if (0 != ret)
4989 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304990 return ret;
4991 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05304992 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
4993 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
4994 fset |= WIFI_FEATURE_INFRA;
4995 }
4996
4997 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
4998 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
4999 fset |= WIFI_FEATURE_INFRA_5G;
5000 }
5001
5002#ifdef WLAN_FEATURE_P2P
5003 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5004 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5005 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5006 fset |= WIFI_FEATURE_P2P;
5007 }
5008#endif
5009
5010 /* Soft-AP is supported currently by default */
5011 fset |= WIFI_FEATURE_SOFT_AP;
5012
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305013 /* HOTSPOT is a supplicant feature, enable it by default */
5014 fset |= WIFI_FEATURE_HOTSPOT;
5015
Dasari Srinivas7875a302014-09-26 17:50:57 +05305016#ifdef WLAN_FEATURE_EXTSCAN
5017 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305018 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5019 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5020 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305021 fset |= WIFI_FEATURE_EXTSCAN;
5022 }
5023#endif
5024
Dasari Srinivas7875a302014-09-26 17:50:57 +05305025 if (sme_IsFeatureSupportedByFW(NAN)) {
5026 hddLog(LOG1, FL("NAN is supported by firmware"));
5027 fset |= WIFI_FEATURE_NAN;
5028 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305029
5030 /* D2D RTT is not supported currently by default */
5031 if (sme_IsFeatureSupportedByFW(RTT)) {
5032 hddLog(LOG1, FL("RTT is supported by firmware"));
5033 fset |= WIFI_FEATURE_D2AP_RTT;
5034 }
5035
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305036 if (sme_IsFeatureSupportedByFW(RTT3)) {
5037 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5038 fset |= WIFI_FEATURE_RTT3;
5039 }
5040
Dasari Srinivas7875a302014-09-26 17:50:57 +05305041#ifdef FEATURE_WLAN_BATCH_SCAN
5042 if (fset & WIFI_FEATURE_EXTSCAN) {
5043 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5044 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5045 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5046 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5047 fset |= WIFI_FEATURE_BATCH_SCAN;
5048 }
5049#endif
5050
5051#ifdef FEATURE_WLAN_SCAN_PNO
5052 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5053 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5054 hddLog(LOG1, FL("PNO is supported by firmware"));
5055 fset |= WIFI_FEATURE_PNO;
5056 }
5057#endif
5058
5059 /* STA+STA is supported currently by default */
5060 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5061
5062#ifdef FEATURE_WLAN_TDLS
5063 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5064 sme_IsFeatureSupportedByFW(TDLS)) {
5065 hddLog(LOG1, FL("TDLS is supported by firmware"));
5066 fset |= WIFI_FEATURE_TDLS;
5067 }
5068
5069 /* TDLS_OFFCHANNEL is not supported currently by default */
5070#endif
5071
5072#ifdef WLAN_AP_STA_CONCURRENCY
5073 /* AP+STA concurrency is supported currently by default */
5074 fset |= WIFI_FEATURE_AP_STA;
5075#endif
5076
Mukul Sharma5add0532015-08-17 15:57:47 +05305077#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5078 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5079 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5080#endif
5081
Dasari Srinivas7875a302014-09-26 17:50:57 +05305082 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5083 NLMSG_HDRLEN);
5084
5085 if (!skb) {
5086 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5087 return -EINVAL;
5088 }
5089 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5090
5091 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5092 hddLog(LOGE, FL("nla put fail"));
5093 goto nla_put_failure;
5094 }
5095
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305096 ret = cfg80211_vendor_cmd_reply(skb);
5097 EXIT();
5098 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305099
5100nla_put_failure:
5101 kfree_skb(skb);
5102 return -EINVAL;
5103}
5104
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305105static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305106wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5107 struct wireless_dev *wdev,
5108 const void *data, int data_len)
5109{
5110 int ret = 0;
5111
5112 vos_ssr_protect(__func__);
5113 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5114 vos_ssr_unprotect(__func__);
5115
5116 return ret;
5117}
5118
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305119
5120static const struct
5121nla_policy
5122qca_wlan_vendor_wifi_logger_get_ring_data_policy
5123[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5124 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5125 = {.type = NLA_U32 },
5126};
5127
5128static int
5129 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5130 struct wireless_dev *wdev,
5131 const void *data,
5132 int data_len)
5133{
5134 int ret;
5135 VOS_STATUS status;
5136 uint32_t ring_id;
5137 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5138 struct nlattr *tb
5139 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5140
5141 ENTER();
5142
5143 ret = wlan_hdd_validate_context(hdd_ctx);
5144 if (0 != ret) {
5145 return ret;
5146 }
5147
5148 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5149 data, data_len,
5150 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5151 hddLog(LOGE, FL("Invalid attribute"));
5152 return -EINVAL;
5153 }
5154
5155 /* Parse and fetch ring id */
5156 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5157 hddLog(LOGE, FL("attr ATTR failed"));
5158 return -EINVAL;
5159 }
5160
5161 ring_id = nla_get_u32(
5162 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5163
5164 hddLog(LOG1, FL("Bug report triggered by framework"));
5165
5166 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5167 WLAN_LOG_INDICATOR_FRAMEWORK,
5168 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305169 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305170 );
5171 if (VOS_STATUS_SUCCESS != status) {
5172 hddLog(LOGE, FL("Failed to trigger bug report"));
5173
5174 return -EINVAL;
5175 }
5176
5177 return 0;
5178
5179
5180}
5181
5182
5183static int
5184 wlan_hdd_cfg80211_wifi_logger_get_ring_data(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_wifi_logger_get_ring_data(wiphy,
5193 wdev, data, data_len);
5194 vos_ssr_unprotect(__func__);
5195
5196 return ret;
5197
5198}
5199
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305200#define MAX_CONCURRENT_MATRIX \
5201 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
5202#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
5203 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
5204static const struct nla_policy
5205wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
5206 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
5207};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305208
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305209static int
5210__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305211 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305212 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305213{
5214 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5215 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305216 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305217 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305218 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5219 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305220
5221 ENTER();
5222
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305223 ret = wlan_hdd_validate_context(pHddCtx);
5224 if (0 != ret)
5225 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305226 return ret;
5227 }
5228
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305229 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
5230 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305231 hddLog(LOGE, FL("Invalid ATTR"));
5232 return -EINVAL;
5233 }
5234
5235 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305236 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305237 hddLog(LOGE, FL("Attr max feature set size failed"));
5238 return -EINVAL;
5239 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305240 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305241 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5242
5243 /* Fill feature combination matrix */
5244 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305245 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5246 WIFI_FEATURE_P2P;
5247
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305248 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5249 WIFI_FEATURE_SOFT_AP;
5250
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305251 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5252 WIFI_FEATURE_SOFT_AP;
5253
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305254 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5255 WIFI_FEATURE_SOFT_AP |
5256 WIFI_FEATURE_P2P;
5257
5258 /* Add more feature combinations here */
5259
5260 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5261 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5262 hddLog(LOG1, "Feature set matrix");
5263 for (i = 0; i < feature_sets; i++)
5264 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5265
5266 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5267 sizeof(u32) * feature_sets +
5268 NLMSG_HDRLEN);
5269
5270 if (reply_skb) {
5271 if (nla_put_u32(reply_skb,
5272 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5273 feature_sets) ||
5274 nla_put(reply_skb,
5275 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5276 sizeof(u32) * feature_sets, feature_set_matrix)) {
5277 hddLog(LOGE, FL("nla put fail"));
5278 kfree_skb(reply_skb);
5279 return -EINVAL;
5280 }
5281
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305282 ret = cfg80211_vendor_cmd_reply(reply_skb);
5283 EXIT();
5284 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305285 }
5286 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5287 return -ENOMEM;
5288
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305289}
5290
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05305291#undef MAX_CONCURRENT_MATRIX
5292#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
5293
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305294static int
5295wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5296 struct wireless_dev *wdev,
5297 const void *data, int data_len)
5298{
5299 int ret = 0;
5300
5301 vos_ssr_protect(__func__);
5302 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5303 data_len);
5304 vos_ssr_unprotect(__func__);
5305
5306 return ret;
5307}
5308
c_manjeecfd1efb2015-09-25 19:32:34 +05305309
5310static int
5311__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5312 struct wireless_dev *wdev,
5313 const void *data, int data_len)
5314{
5315 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5316 int ret;
5317 ENTER();
5318
5319 ret = wlan_hdd_validate_context(pHddCtx);
5320 if (0 != ret)
5321 {
5322 return ret;
5323 }
5324
5325 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5326 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5327 {
5328 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5329 return -EINVAL;
5330 }
5331 /*call common API for FW mem dump req*/
5332 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5333
Abhishek Singhc783fa72015-12-09 18:07:34 +05305334 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05305335 {
5336 /*indicate to userspace the status of fw mem dump */
5337 wlan_indicate_mem_dump_complete(true);
5338 }
5339 else
5340 {
5341 /*else send failure to userspace */
5342 wlan_indicate_mem_dump_complete(false);
5343 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305344 EXIT();
5345 return ret;
5346}
5347
5348/**
5349 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5350 * @wiphy: pointer to wireless wiphy structure.
5351 * @wdev: pointer to wireless_dev structure.
5352 * @data: Pointer to the NL data.
5353 * @data_len:Length of @data
5354 *
5355 * This is called when wlan driver needs to get the firmware memory dump
5356 * via vendor specific command.
5357 *
5358 * Return: 0 on success, error number otherwise.
5359 */
5360
5361static int
5362wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5363 struct wireless_dev *wdev,
5364 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305365{
5366 int ret = 0;
5367 vos_ssr_protect(__func__);
5368 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5369 data_len);
5370 vos_ssr_unprotect(__func__);
5371 return ret;
5372}
c_manjeecfd1efb2015-09-25 19:32:34 +05305373
Sushant Kaushik8e644982015-09-23 12:18:54 +05305374static const struct
5375nla_policy
5376qca_wlan_vendor_wifi_logger_start_policy
5377[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5378 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5379 = {.type = NLA_U32 },
5380 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5381 = {.type = NLA_U32 },
5382 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5383 = {.type = NLA_U32 },
5384};
5385
5386/**
5387 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5388 * or disable the collection of packet statistics from the firmware
5389 * @wiphy: WIPHY structure pointer
5390 * @wdev: Wireless device structure pointer
5391 * @data: Pointer to the data received
5392 * @data_len: Length of the data received
5393 *
5394 * This function is used to enable or disable the collection of packet
5395 * statistics from the firmware
5396 *
5397 * Return: 0 on success and errno on failure
5398 */
5399static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5400 struct wireless_dev *wdev,
5401 const void *data,
5402 int data_len)
5403{
5404 eHalStatus status;
5405 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5406 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5407 tAniWifiStartLog start_log;
5408
5409 status = wlan_hdd_validate_context(hdd_ctx);
5410 if (0 != status) {
5411 return -EINVAL;
5412 }
5413
5414 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5415 data, data_len,
5416 qca_wlan_vendor_wifi_logger_start_policy)) {
5417 hddLog(LOGE, FL("Invalid attribute"));
5418 return -EINVAL;
5419 }
5420
5421 /* Parse and fetch ring id */
5422 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5423 hddLog(LOGE, FL("attr ATTR failed"));
5424 return -EINVAL;
5425 }
5426 start_log.ringId = nla_get_u32(
5427 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5428 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5429
5430 /* Parse and fetch verbose level */
5431 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5432 hddLog(LOGE, FL("attr verbose_level failed"));
5433 return -EINVAL;
5434 }
5435 start_log.verboseLevel = nla_get_u32(
5436 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5437 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5438
5439 /* Parse and fetch flag */
5440 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5441 hddLog(LOGE, FL("attr flag failed"));
5442 return -EINVAL;
5443 }
5444 start_log.flag = nla_get_u32(
5445 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5446 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5447
5448 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305449 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5450 !vos_isPktStatsEnabled()))
5451
Sushant Kaushik8e644982015-09-23 12:18:54 +05305452 {
5453 hddLog(LOGE, FL("per pkt stats not enabled"));
5454 return -EINVAL;
5455 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305456
Sushant Kaushik33200572015-08-05 16:46:20 +05305457 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305458 return 0;
5459}
5460
5461/**
5462 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5463 * or disable the collection of packet statistics from the firmware
5464 * @wiphy: WIPHY structure pointer
5465 * @wdev: Wireless device structure pointer
5466 * @data: Pointer to the data received
5467 * @data_len: Length of the data received
5468 *
5469 * This function is used to enable or disable the collection of packet
5470 * statistics from the firmware
5471 *
5472 * Return: 0 on success and errno on failure
5473 */
5474static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5475 struct wireless_dev *wdev,
5476 const void *data,
5477 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05305478{
5479 int ret = 0;
5480
5481 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305482
5483 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
5484 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05305485 vos_ssr_unprotect(__func__);
5486
5487 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05305488}
5489
5490
Agarwal Ashish738843c2014-09-25 12:27:56 +05305491static const struct nla_policy
5492wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5493 +1] =
5494{
5495 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5496};
5497
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305498static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305499 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305500 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305501 int data_len)
5502{
5503 struct net_device *dev = wdev->netdev;
5504 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5505 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5506 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5507 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5508 eHalStatus status;
5509 u32 dfsFlag = 0;
5510
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305511 ENTER();
5512
Agarwal Ashish738843c2014-09-25 12:27:56 +05305513 status = wlan_hdd_validate_context(pHddCtx);
5514 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305515 return -EINVAL;
5516 }
5517 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5518 data, data_len,
5519 wlan_hdd_set_no_dfs_flag_config_policy)) {
5520 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5521 return -EINVAL;
5522 }
5523
5524 /* Parse and fetch required bandwidth kbps */
5525 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5526 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5527 return -EINVAL;
5528 }
5529
5530 dfsFlag = nla_get_u32(
5531 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5532 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5533 dfsFlag);
5534
5535 pHddCtx->disable_dfs_flag = dfsFlag;
5536
5537 sme_disable_dfs_channel(hHal, dfsFlag);
5538 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305539
5540 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305541 return 0;
5542}
Atul Mittal115287b2014-07-08 13:26:33 +05305543
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305544static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5545 struct wireless_dev *wdev,
5546 const void *data,
5547 int data_len)
5548{
5549 int ret = 0;
5550
5551 vos_ssr_protect(__func__);
5552 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5553 vos_ssr_unprotect(__func__);
5554
5555 return ret;
5556
5557}
5558
Mukul Sharma2a271632014-10-13 14:59:01 +05305559const struct
5560nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5561{
5562 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305563 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
5564 .type = NLA_UNSPEC,
5565 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05305566};
5567
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305568static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305569 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305570{
5571
5572 u8 bssid[6] = {0};
5573 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5574 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5575 eHalStatus status = eHAL_STATUS_SUCCESS;
5576 v_U32_t isFwrRoamEnabled = FALSE;
5577 int ret;
5578
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305579 ENTER();
5580
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305581 ret = wlan_hdd_validate_context(pHddCtx);
5582 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305583 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305584 }
5585
5586 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5587 data, data_len,
5588 qca_wlan_vendor_attr);
5589 if (ret){
5590 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5591 return -EINVAL;
5592 }
5593
5594 /* Parse and fetch Enable flag */
5595 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5596 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5597 return -EINVAL;
5598 }
5599
5600 isFwrRoamEnabled = nla_get_u32(
5601 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5602
5603 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5604
5605 /* Parse and fetch bssid */
5606 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5607 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5608 return -EINVAL;
5609 }
5610
5611 memcpy(bssid, nla_data(
5612 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5613 sizeof(bssid));
5614 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5615
5616 //Update roaming
5617 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05305618 if (!HAL_STATUS_SUCCESS(status)) {
5619 hddLog(LOGE,
5620 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
5621 return -EINVAL;
5622 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305623 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05305624 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05305625}
5626
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305627static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5628 struct wireless_dev *wdev, const void *data, int data_len)
5629{
5630 int ret = 0;
5631
5632 vos_ssr_protect(__func__);
5633 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5634 vos_ssr_unprotect(__func__);
5635
5636 return ret;
5637}
5638
Sushant Kaushik847890c2015-09-28 16:05:17 +05305639static const struct
5640nla_policy
5641qca_wlan_vendor_get_wifi_info_policy[
5642 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
5643 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
5644 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
5645};
5646
5647
5648/**
5649 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
5650 * @wiphy: pointer to wireless wiphy structure.
5651 * @wdev: pointer to wireless_dev structure.
5652 * @data: Pointer to the data to be passed via vendor interface
5653 * @data_len:Length of the data to be passed
5654 *
5655 * This is called when wlan driver needs to send wifi driver related info
5656 * (driver/fw version) to the user space application upon request.
5657 *
5658 * Return: Return the Success or Failure code.
5659 */
5660static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
5661 struct wireless_dev *wdev,
5662 const void *data, int data_len)
5663{
5664 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5665 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
5666 tSirVersionString version;
5667 uint32 version_len;
5668 uint8 attr;
5669 int status;
5670 struct sk_buff *reply_skb = NULL;
5671
5672 if (VOS_FTM_MODE == hdd_get_conparam()) {
5673 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5674 return -EINVAL;
5675 }
5676
5677 status = wlan_hdd_validate_context(hdd_ctx);
5678 if (0 != status) {
5679 hddLog(LOGE, FL("HDD context is not valid"));
5680 return -EINVAL;
5681 }
5682
5683 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
5684 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
5685 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
5686 return -EINVAL;
5687 }
5688
5689 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
5690 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
5691 QWLAN_VERSIONSTR);
5692 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
5693 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
5694 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
5695 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
5696 hdd_ctx->fw_Version);
5697 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
5698 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
5699 } else {
5700 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
5701 return -EINVAL;
5702 }
5703
5704 version_len = strlen(version);
5705 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
5706 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
5707 if (!reply_skb) {
5708 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5709 return -ENOMEM;
5710 }
5711
5712 if (nla_put(reply_skb, attr, version_len, version)) {
5713 hddLog(LOGE, FL("nla put fail"));
5714 kfree_skb(reply_skb);
5715 return -EINVAL;
5716 }
5717
5718 return cfg80211_vendor_cmd_reply(reply_skb);
5719}
5720
5721/**
5722 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
5723 * @wiphy: pointer to wireless wiphy structure.
5724 * @wdev: pointer to wireless_dev structure.
5725 * @data: Pointer to the data to be passed via vendor interface
5726 * @data_len:Length of the data to be passed
5727 * @data_len: Length of the data received
5728 *
5729 * This function is used to enable or disable the collection of packet
5730 * statistics from the firmware
5731 *
5732 * Return: 0 on success and errno on failure
5733 */
5734
5735static int
5736wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
5737 struct wireless_dev *wdev,
5738 const void *data, int data_len)
5739
5740
5741{
5742 int ret = 0;
5743
5744 vos_ssr_protect(__func__);
5745 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
5746 wdev, data, data_len);
5747 vos_ssr_unprotect(__func__);
5748
5749 return ret;
5750}
5751
5752
Gupta, Kapil7c34b322015-09-30 13:12:35 +05305753/*
5754 * define short names for the global vendor params
5755 * used by __wlan_hdd_cfg80211_monitor_rssi()
5756 */
5757#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
5758#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
5759#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
5760#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
5761#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
5762
5763/**---------------------------------------------------------------------------
5764
5765 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
5766 monitor start is completed successfully.
5767
5768 \return - None
5769
5770 --------------------------------------------------------------------------*/
5771void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
5772{
5773 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
5774
5775 if (NULL == pHddCtx)
5776 {
5777 hddLog(VOS_TRACE_LEVEL_ERROR,
5778 "%s: HDD context is NULL",__func__);
5779 return;
5780 }
5781
5782 if (VOS_STATUS_SUCCESS == status)
5783 {
5784 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
5785 }
5786 else
5787 {
5788 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
5789 }
5790
5791 return;
5792}
5793
5794/**---------------------------------------------------------------------------
5795
5796 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
5797 stop is completed successfully.
5798
5799 \return - None
5800
5801 --------------------------------------------------------------------------*/
5802void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
5803{
5804 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
5805
5806 if (NULL == pHddCtx)
5807 {
5808 hddLog(VOS_TRACE_LEVEL_ERROR,
5809 "%s: HDD context is NULL",__func__);
5810 return;
5811 }
5812
5813 if (VOS_STATUS_SUCCESS == status)
5814 {
5815 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
5816 }
5817 else
5818 {
5819 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
5820 }
5821
5822 return;
5823}
5824
5825/**
5826 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
5827 * @wiphy: Pointer to wireless phy
5828 * @wdev: Pointer to wireless device
5829 * @data: Pointer to data
5830 * @data_len: Data length
5831 *
5832 * Return: 0 on success, negative errno on failure
5833 */
5834
5835static int
5836__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
5837 struct wireless_dev *wdev,
5838 const void *data,
5839 int data_len)
5840{
5841 struct net_device *dev = wdev->netdev;
5842 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5843 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5844 hdd_station_ctx_t *pHddStaCtx;
5845 struct nlattr *tb[PARAM_MAX + 1];
5846 tpSirRssiMonitorReq pReq;
5847 eHalStatus status;
5848 int ret;
5849 uint32_t control;
5850 static const struct nla_policy policy[PARAM_MAX + 1] = {
5851 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
5852 [PARAM_CONTROL] = { .type = NLA_U32 },
5853 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
5854 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
5855 };
5856
5857 ENTER();
5858
5859 ret = wlan_hdd_validate_context(hdd_ctx);
5860 if (0 != ret) {
5861 return -EINVAL;
5862 }
5863
5864 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
5865 hddLog(LOGE, FL("Not in Connected state!"));
5866 return -ENOTSUPP;
5867 }
5868
5869 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
5870 hddLog(LOGE, FL("Invalid ATTR"));
5871 return -EINVAL;
5872 }
5873
5874 if (!tb[PARAM_REQUEST_ID]) {
5875 hddLog(LOGE, FL("attr request id failed"));
5876 return -EINVAL;
5877 }
5878
5879 if (!tb[PARAM_CONTROL]) {
5880 hddLog(LOGE, FL("attr control failed"));
5881 return -EINVAL;
5882 }
5883
5884 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5885
5886 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
5887 if(NULL == pReq)
5888 {
5889 hddLog(LOGE,
5890 FL("vos_mem_alloc failed "));
5891 return eHAL_STATUS_FAILED_ALLOC;
5892 }
5893 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
5894
5895 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
5896 pReq->sessionId = pAdapter->sessionId;
5897 pReq->rssiMonitorCbContext = hdd_ctx;
5898 control = nla_get_u32(tb[PARAM_CONTROL]);
5899 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
5900
5901 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
5902 pReq->requestId, pReq->sessionId, control);
5903
5904 if (control == QCA_WLAN_RSSI_MONITORING_START) {
5905 if (!tb[PARAM_MIN_RSSI]) {
5906 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05305907 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05305908 }
5909
5910 if (!tb[PARAM_MAX_RSSI]) {
5911 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05305912 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05305913 }
5914
5915 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
5916 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
5917 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
5918
5919 if (!(pReq->minRssi < pReq->maxRssi)) {
5920 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
5921 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05305922 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05305923 }
5924 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
5925 pReq->minRssi, pReq->maxRssi);
5926 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
5927
5928 }
5929 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
5930 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
5931 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
5932 }
5933 else {
5934 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05305935 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05305936 }
5937
5938 if (!HAL_STATUS_SUCCESS(status)) {
5939 hddLog(LOGE,
5940 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05305941 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05305942 }
5943
5944 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05305945fail:
5946 vos_mem_free(pReq);
5947 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05305948}
5949
5950/*
5951 * done with short names for the global vendor params
5952 * used by __wlan_hdd_cfg80211_monitor_rssi()
5953 */
5954#undef PARAM_MAX
5955#undef PARAM_CONTROL
5956#undef PARAM_REQUEST_ID
5957#undef PARAM_MAX_RSSI
5958#undef PARAM_MIN_RSSI
5959
5960/**
5961 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
5962 * @wiphy: wiphy structure pointer
5963 * @wdev: Wireless device structure pointer
5964 * @data: Pointer to the data received
5965 * @data_len: Length of @data
5966 *
5967 * Return: 0 on success; errno on failure
5968 */
5969static int
5970wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
5971 const void *data, int data_len)
5972{
5973 int ret;
5974
5975 vos_ssr_protect(__func__);
5976 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
5977 vos_ssr_unprotect(__func__);
5978
5979 return ret;
5980}
5981
5982/**
5983 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
5984 * @hddctx: HDD context
5985 * @data: rssi breached event data
5986 *
5987 * This function reads the rssi breached event %data and fill in the skb with
5988 * NL attributes and send up the NL event.
5989 * This callback execute in atomic context and must not invoke any
5990 * blocking calls.
5991 *
5992 * Return: none
5993 */
5994void hdd_rssi_threshold_breached_cb(void *hddctx,
5995 struct rssi_breach_event *data)
5996{
5997 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
5998 int status;
5999 struct sk_buff *skb;
6000
6001 ENTER();
6002 status = wlan_hdd_validate_context(pHddCtx);
6003
6004 if (0 != status) {
6005 return;
6006 }
6007
6008 if (!data) {
6009 hddLog(LOGE, FL("data is null"));
6010 return;
6011 }
6012
6013 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6014#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6015 NULL,
6016#endif
6017 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6018 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6019 GFP_KERNEL);
6020
6021 if (!skb) {
6022 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6023 return;
6024 }
6025
6026 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6027 data->request_id, data->curr_rssi);
6028 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6029 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6030
6031 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6032 data->request_id) ||
6033 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6034 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6035 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6036 data->curr_rssi)) {
6037 hddLog(LOGE, FL("nla put fail"));
6038 goto fail;
6039 }
6040
6041 cfg80211_vendor_event(skb, GFP_KERNEL);
6042 return;
6043
6044fail:
6045 kfree_skb(skb);
6046 return;
6047}
6048
6049
6050
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306051/**
6052 * __wlan_hdd_cfg80211_setband() - set band
6053 * @wiphy: Pointer to wireless phy
6054 * @wdev: Pointer to wireless device
6055 * @data: Pointer to data
6056 * @data_len: Data length
6057 *
6058 * Return: 0 on success, negative errno on failure
6059 */
6060static int
6061__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6062 struct wireless_dev *wdev,
6063 const void *data,
6064 int data_len)
6065{
6066 struct net_device *dev = wdev->netdev;
6067 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6068 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6069 int ret;
6070 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6071 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6072
6073 ENTER();
6074
6075 ret = wlan_hdd_validate_context(hdd_ctx);
6076 if (0 != ret) {
6077 hddLog(LOGE, FL("HDD context is not valid"));
6078 return ret;
6079 }
6080
6081 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6082 policy)) {
6083 hddLog(LOGE, FL("Invalid ATTR"));
6084 return -EINVAL;
6085 }
6086
6087 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6088 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6089 return -EINVAL;
6090 }
6091
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306092 hdd_ctx->isSetBandByNL = TRUE;
6093 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306094 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306095 hdd_ctx->isSetBandByNL = FALSE;
6096
6097 EXIT();
6098 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306099}
6100
6101/**
6102 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6103 * @wiphy: wiphy structure pointer
6104 * @wdev: Wireless device structure pointer
6105 * @data: Pointer to the data received
6106 * @data_len: Length of @data
6107 *
6108 * Return: 0 on success; errno on failure
6109 */
6110static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6111 struct wireless_dev *wdev,
6112 const void *data,
6113 int data_len)
6114{
6115 int ret = 0;
6116
6117 vos_ssr_protect(__func__);
6118 ret = __wlan_hdd_cfg80211_setband(wiphy,
6119 wdev, data, data_len);
6120 vos_ssr_unprotect(__func__);
6121
6122 return ret;
6123}
6124
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306125#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6126/**
6127 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6128 * @hdd_ctx: HDD context
6129 * @request_id: [input] request id
6130 * @pattern_id: [output] pattern id
6131 *
6132 * This function loops through request id to pattern id array
6133 * if the slot is available, store the request id and return pattern id
6134 * if entry exists, return the pattern id
6135 *
6136 * Return: 0 on success and errno on failure
6137 */
6138static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6139 uint32_t request_id,
6140 uint8_t *pattern_id)
6141{
6142 uint32_t i;
6143
6144 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6145 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6146 {
6147 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6148 {
6149 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6150 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6151 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6152 return 0;
6153 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6154 request_id) {
6155 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6156 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6157 return 0;
6158 }
6159 }
6160 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6161 return -EINVAL;
6162}
6163
6164/**
6165 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6166 * @hdd_ctx: HDD context
6167 * @request_id: [input] request id
6168 * @pattern_id: [output] pattern id
6169 *
6170 * This function loops through request id to pattern id array
6171 * reset request id to 0 (slot available again) and
6172 * return pattern id
6173 *
6174 * Return: 0 on success and errno on failure
6175 */
6176static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6177 uint32_t request_id,
6178 uint8_t *pattern_id)
6179{
6180 uint32_t i;
6181
6182 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6183 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6184 {
6185 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6186 {
6187 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6188 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6189 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6190 return 0;
6191 }
6192 }
6193 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6194 return -EINVAL;
6195}
6196
6197
6198/*
6199 * define short names for the global vendor params
6200 * used by __wlan_hdd_cfg80211_offloaded_packets()
6201 */
6202#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6203#define PARAM_REQUEST_ID \
6204 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6205#define PARAM_CONTROL \
6206 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6207#define PARAM_IP_PACKET \
6208 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6209#define PARAM_SRC_MAC_ADDR \
6210 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6211#define PARAM_DST_MAC_ADDR \
6212 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6213#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6214
6215/**
6216 * wlan_hdd_add_tx_ptrn() - add tx pattern
6217 * @adapter: adapter pointer
6218 * @hdd_ctx: hdd context
6219 * @tb: nl attributes
6220 *
6221 * This function reads the NL attributes and forms a AddTxPtrn message
6222 * posts it to SME.
6223 *
6224 */
6225static int
6226wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6227 struct nlattr **tb)
6228{
6229 struct sSirAddPeriodicTxPtrn *add_req;
6230 eHalStatus status;
6231 uint32_t request_id, ret, len;
6232 uint8_t pattern_id = 0;
6233 v_MACADDR_t dst_addr;
6234 uint16_t eth_type = htons(ETH_P_IP);
6235
6236 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6237 {
6238 hddLog(LOGE, FL("Not in Connected state!"));
6239 return -ENOTSUPP;
6240 }
6241
6242 add_req = vos_mem_malloc(sizeof(*add_req));
6243 if (!add_req)
6244 {
6245 hddLog(LOGE, FL("memory allocation failed"));
6246 return -ENOMEM;
6247 }
6248
6249 /* Parse and fetch request Id */
6250 if (!tb[PARAM_REQUEST_ID])
6251 {
6252 hddLog(LOGE, FL("attr request id failed"));
6253 goto fail;
6254 }
6255
6256 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6257 hddLog(LOG1, FL("Request Id: %u"), request_id);
6258 if (request_id == 0)
6259 {
6260 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306261 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306262 }
6263
6264 if (!tb[PARAM_PERIOD])
6265 {
6266 hddLog(LOGE, FL("attr period failed"));
6267 goto fail;
6268 }
6269 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6270 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6271 if (add_req->usPtrnIntervalMs == 0)
6272 {
6273 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6274 goto fail;
6275 }
6276
6277 if (!tb[PARAM_SRC_MAC_ADDR])
6278 {
6279 hddLog(LOGE, FL("attr source mac address failed"));
6280 goto fail;
6281 }
6282 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6283 VOS_MAC_ADDR_SIZE);
6284 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6285 MAC_ADDR_ARRAY(add_req->macAddress));
6286
6287 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6288 VOS_MAC_ADDR_SIZE))
6289 {
6290 hddLog(LOGE,
6291 FL("input src mac address and connected ap bssid are different"));
6292 goto fail;
6293 }
6294
6295 if (!tb[PARAM_DST_MAC_ADDR])
6296 {
6297 hddLog(LOGE, FL("attr dst mac address failed"));
6298 goto fail;
6299 }
6300 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6301 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6302 MAC_ADDR_ARRAY(dst_addr.bytes));
6303
6304 if (!tb[PARAM_IP_PACKET])
6305 {
6306 hddLog(LOGE, FL("attr ip packet failed"));
6307 goto fail;
6308 }
6309 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6310 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6311
6312 if (add_req->ucPtrnSize < 0 ||
6313 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6314 HDD_ETH_HEADER_LEN))
6315 {
6316 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6317 add_req->ucPtrnSize);
6318 goto fail;
6319 }
6320
6321 len = 0;
6322 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6323 len += VOS_MAC_ADDR_SIZE;
6324 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6325 VOS_MAC_ADDR_SIZE);
6326 len += VOS_MAC_ADDR_SIZE;
6327 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6328 len += 2;
6329
6330 /*
6331 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6332 * ------------------------------------------------------------
6333 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6334 * ------------------------------------------------------------
6335 */
6336 vos_mem_copy(&add_req->ucPattern[len],
6337 nla_data(tb[PARAM_IP_PACKET]),
6338 add_req->ucPtrnSize);
6339 add_req->ucPtrnSize += len;
6340
6341 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6342 add_req->ucPattern, add_req->ucPtrnSize);
6343
6344 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6345 if (ret)
6346 {
6347 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6348 goto fail;
6349 }
6350 add_req->ucPtrnId = pattern_id;
6351 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6352
6353 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6354 if (!HAL_STATUS_SUCCESS(status))
6355 {
6356 hddLog(LOGE,
6357 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6358 goto fail;
6359 }
6360
6361 EXIT();
6362 vos_mem_free(add_req);
6363 return 0;
6364
6365fail:
6366 vos_mem_free(add_req);
6367 return -EINVAL;
6368}
6369
6370/**
6371 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6372 * @adapter: adapter pointer
6373 * @hdd_ctx: hdd context
6374 * @tb: nl attributes
6375 *
6376 * This function reads the NL attributes and forms a DelTxPtrn message
6377 * posts it to SME.
6378 *
6379 */
6380static int
6381wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6382 struct nlattr **tb)
6383{
6384 struct sSirDelPeriodicTxPtrn *del_req;
6385 eHalStatus status;
6386 uint32_t request_id, ret;
6387 uint8_t pattern_id = 0;
6388
6389 /* Parse and fetch request Id */
6390 if (!tb[PARAM_REQUEST_ID])
6391 {
6392 hddLog(LOGE, FL("attr request id failed"));
6393 return -EINVAL;
6394 }
6395 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6396 if (request_id == 0)
6397 {
6398 hddLog(LOGE, FL("request_id cannot be zero"));
6399 return -EINVAL;
6400 }
6401
6402 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6403 if (ret)
6404 {
6405 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6406 return -EINVAL;
6407 }
6408
6409 del_req = vos_mem_malloc(sizeof(*del_req));
6410 if (!del_req)
6411 {
6412 hddLog(LOGE, FL("memory allocation failed"));
6413 return -ENOMEM;
6414 }
6415
6416 vos_mem_set(del_req, sizeof(*del_req), 0);
6417 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6418 VOS_MAC_ADDR_SIZE);
6419 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6420 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6421 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6422 request_id, pattern_id, del_req->ucPatternIdBitmap);
6423
6424 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6425 if (!HAL_STATUS_SUCCESS(status))
6426 {
6427 hddLog(LOGE,
6428 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6429 goto fail;
6430 }
6431
6432 EXIT();
6433 vos_mem_free(del_req);
6434 return 0;
6435
6436fail:
6437 vos_mem_free(del_req);
6438 return -EINVAL;
6439}
6440
6441
6442/**
6443 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6444 * @wiphy: Pointer to wireless phy
6445 * @wdev: Pointer to wireless device
6446 * @data: Pointer to data
6447 * @data_len: Data length
6448 *
6449 * Return: 0 on success, negative errno on failure
6450 */
6451static int
6452__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6453 struct wireless_dev *wdev,
6454 const void *data,
6455 int data_len)
6456{
6457 struct net_device *dev = wdev->netdev;
6458 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6459 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6460 struct nlattr *tb[PARAM_MAX + 1];
6461 uint8_t control;
6462 int ret;
6463 static const struct nla_policy policy[PARAM_MAX + 1] =
6464 {
6465 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6466 [PARAM_CONTROL] = { .type = NLA_U32 },
6467 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
6468 .len = VOS_MAC_ADDR_SIZE },
6469 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
6470 .len = VOS_MAC_ADDR_SIZE },
6471 [PARAM_PERIOD] = { .type = NLA_U32 },
6472 };
6473
6474 ENTER();
6475
6476 ret = wlan_hdd_validate_context(hdd_ctx);
6477 if (0 != ret)
6478 {
6479 hddLog(LOGE, FL("HDD context is not valid"));
6480 return ret;
6481 }
6482
6483 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
6484 {
6485 hddLog(LOGE,
6486 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
6487 return -ENOTSUPP;
6488 }
6489
6490 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
6491 {
6492 hddLog(LOGE, FL("Invalid ATTR"));
6493 return -EINVAL;
6494 }
6495
6496 if (!tb[PARAM_CONTROL])
6497 {
6498 hddLog(LOGE, FL("attr control failed"));
6499 return -EINVAL;
6500 }
6501 control = nla_get_u32(tb[PARAM_CONTROL]);
6502 hddLog(LOG1, FL("Control: %d"), control);
6503
6504 if (control == WLAN_START_OFFLOADED_PACKETS)
6505 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
6506 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
6507 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
6508 else
6509 {
6510 hddLog(LOGE, FL("Invalid control: %d"), control);
6511 return -EINVAL;
6512 }
6513}
6514
6515/*
6516 * done with short names for the global vendor params
6517 * used by __wlan_hdd_cfg80211_offloaded_packets()
6518 */
6519#undef PARAM_MAX
6520#undef PARAM_REQUEST_ID
6521#undef PARAM_CONTROL
6522#undef PARAM_IP_PACKET
6523#undef PARAM_SRC_MAC_ADDR
6524#undef PARAM_DST_MAC_ADDR
6525#undef PARAM_PERIOD
6526
6527/**
6528 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
6529 * @wiphy: wiphy structure pointer
6530 * @wdev: Wireless device structure pointer
6531 * @data: Pointer to the data received
6532 * @data_len: Length of @data
6533 *
6534 * Return: 0 on success; errno on failure
6535 */
6536static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6537 struct wireless_dev *wdev,
6538 const void *data,
6539 int data_len)
6540{
6541 int ret = 0;
6542
6543 vos_ssr_protect(__func__);
6544 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
6545 wdev, data, data_len);
6546 vos_ssr_unprotect(__func__);
6547
6548 return ret;
6549}
6550#endif
6551
Deepthi Gowriae6a1662015-10-12 12:59:37 +05306552static const struct
6553nla_policy
6554qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306555 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6556 .type = NLA_BINARY,
6557 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05306558};
6559
6560/**
6561 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
6562 * get link properties like nss, rate flags and operating frequency for
6563 * the connection with the given peer.
6564 * @wiphy: WIPHY structure pointer
6565 * @wdev: Wireless device structure pointer
6566 * @data: Pointer to the data received
6567 * @data_len: Length of the data received
6568 *
6569 * This function return the above link properties on success.
6570 *
6571 * Return: 0 on success and errno on failure
6572 */
6573static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
6574 struct wireless_dev *wdev,
6575 const void *data,
6576 int data_len)
6577{
6578 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6579 struct net_device *dev = wdev->netdev;
6580 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6581 hdd_station_ctx_t *hdd_sta_ctx;
6582 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
6583 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
6584 uint32_t sta_id;
6585 struct sk_buff *reply_skb;
6586 uint32_t rate_flags = 0;
6587 uint8_t nss;
6588 uint8_t final_rate_flags = 0;
6589 uint32_t freq;
6590 v_CONTEXT_t pVosContext = NULL;
6591 ptSapContext pSapCtx = NULL;
6592
6593 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
6594 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
6595 return -EINVAL;
6596 }
6597
6598 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6599 qca_wlan_vendor_attr_policy)) {
6600 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
6601 return -EINVAL;
6602 }
6603
6604 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6605 hddLog(VOS_TRACE_LEVEL_ERROR,
6606 FL("Attribute peerMac not provided for mode=%d"),
6607 adapter->device_mode);
6608 return -EINVAL;
6609 }
6610
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05306611 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
6612 hddLog(VOS_TRACE_LEVEL_ERROR,
6613 FL("Attribute peerMac is invalid=%d"),
6614 adapter->device_mode);
6615 return -EINVAL;
6616 }
6617
Deepthi Gowriae6a1662015-10-12 12:59:37 +05306618 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6619 sizeof(peer_mac));
6620 hddLog(VOS_TRACE_LEVEL_INFO,
6621 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
6622 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
6623
6624 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
6625 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
6626 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
6627 if ((hdd_sta_ctx->conn_info.connState !=
6628 eConnectionState_Associated) ||
6629 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
6630 VOS_MAC_ADDRESS_LEN)) {
6631 hddLog(VOS_TRACE_LEVEL_ERROR,
6632 FL("Not Associated to mac "MAC_ADDRESS_STR),
6633 MAC_ADDR_ARRAY(peer_mac));
6634 return -EINVAL;
6635 }
6636
6637 nss = 1; //pronto supports only one spatial stream
6638 freq = vos_chan_to_freq(
6639 hdd_sta_ctx->conn_info.operationChannel);
6640 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
6641
6642 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
6643 adapter->device_mode == WLAN_HDD_SOFTAP) {
6644
6645 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
6646 pSapCtx = VOS_GET_SAP_CB(pVosContext);
6647 if(pSapCtx == NULL){
6648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6649 FL("psapCtx is NULL"));
6650 return -ENOENT;
6651 }
6652
6653
6654 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
6655 if (pSapCtx->aStaInfo[sta_id].isUsed &&
6656 !vos_is_macaddr_broadcast(
6657 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
6658 vos_mem_compare(
6659 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
6660 peer_mac, VOS_MAC_ADDRESS_LEN))
6661 break;
6662 }
6663
6664 if (WLAN_MAX_STA_COUNT == sta_id) {
6665 hddLog(VOS_TRACE_LEVEL_ERROR,
6666 FL("No active peer with mac="MAC_ADDRESS_STR),
6667 MAC_ADDR_ARRAY(peer_mac));
6668 return -EINVAL;
6669 }
6670
6671 nss = 1; //pronto supports only one spatial stream
6672 freq = vos_chan_to_freq(
6673 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
6674 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
6675 } else {
6676 hddLog(VOS_TRACE_LEVEL_ERROR,
6677 FL("Not Associated! with mac"MAC_ADDRESS_STR),
6678 MAC_ADDR_ARRAY(peer_mac));
6679 return -EINVAL;
6680 }
6681
6682 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
6683 if (rate_flags & eHAL_TX_RATE_VHT80) {
6684 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
6685 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
6686 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
6687 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
6688 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6689 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
6690 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
6691 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
6692 final_rate_flags |= RATE_INFO_FLAGS_MCS;
6693 if (rate_flags & eHAL_TX_RATE_HT40)
6694 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6695 }
6696
6697 if (rate_flags & eHAL_TX_RATE_SGI) {
6698 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
6699 final_rate_flags |= RATE_INFO_FLAGS_MCS;
6700 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
6701 }
6702 }
6703
6704 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6705 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
6706
6707 if (NULL == reply_skb) {
6708 hddLog(VOS_TRACE_LEVEL_ERROR,
6709 FL("getLinkProperties: skb alloc failed"));
6710 return -EINVAL;
6711 }
6712
6713 if (nla_put_u8(reply_skb,
6714 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
6715 nss) ||
6716 nla_put_u8(reply_skb,
6717 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
6718 final_rate_flags) ||
6719 nla_put_u32(reply_skb,
6720 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
6721 freq)) {
6722 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
6723 kfree_skb(reply_skb);
6724 return -EINVAL;
6725 }
6726
6727 return cfg80211_vendor_cmd_reply(reply_skb);
6728}
6729
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05306730#define BEACON_MISS_THRESH_2_4 \
6731 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
6732#define BEACON_MISS_THRESH_5_0 \
6733 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05306734#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
6735#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
6736#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
6737#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05306738#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
6739 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05306740
6741/**
6742 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
6743 * vendor command
6744 *
6745 * @wiphy: wiphy device pointer
6746 * @wdev: wireless device pointer
6747 * @data: Vendor command data buffer
6748 * @data_len: Buffer length
6749 *
6750 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
6751 *
6752 * Return: EOK or other error codes.
6753 */
6754
6755static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
6756 struct wireless_dev *wdev,
6757 const void *data,
6758 int data_len)
6759{
6760 struct net_device *dev = wdev->netdev;
6761 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6762 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6763 hdd_station_ctx_t *pHddStaCtx;
6764 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
6765 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05306766 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05306767 eHalStatus status;
6768 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05306769 uint8_t hb_thresh_val;
6770
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05306771 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
6772 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
6773 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05306774 [PARAM_GUARD_TIME] = { .type = NLA_U32},
6775 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
6776 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05306777 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
6778 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05306779 };
6780
6781 ENTER();
6782
6783 if (VOS_FTM_MODE == hdd_get_conparam()) {
6784 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6785 return -EINVAL;
6786 }
6787
6788 ret_val = wlan_hdd_validate_context(pHddCtx);
6789 if (ret_val) {
6790 return ret_val;
6791 }
6792
6793 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6794
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05306795 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
6796 hddLog(LOGE, FL("Invalid ATTR"));
6797 return -EINVAL;
6798 }
6799
6800 /* check the Wifi Capability */
6801 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
6802 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
6803 {
6804 hddLog(VOS_TRACE_LEVEL_ERROR,
6805 FL("WIFICONFIG not supported by Firmware"));
6806 return -EINVAL;
6807 }
6808
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05306809 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
6810 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
6811 modifyRoamParamsReq.value =
6812 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
6813
6814 if (eHAL_STATUS_SUCCESS !=
6815 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
6816 {
6817 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
6818 ret_val = -EINVAL;
6819 }
6820 return ret_val;
6821 }
6822
6823 /* Moved this down in order to provide provision to set beacon
6824 * miss penalty count irrespective of connection state.
6825 */
6826 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6827 hddLog(LOGE, FL("Not in Connected state!"));
6828 return -ENOTSUPP;
6829 }
6830
6831 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05306832
6833 if (!pReq) {
6834 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
6835 "%s: Not able to allocate memory for tSetWifiConfigParams",
6836 __func__);
6837 return eHAL_STATUS_E_MALLOC_FAILED;
6838 }
6839
6840 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
6841
6842 pReq->sessionId = pAdapter->sessionId;
6843 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6844
6845 if (tb[PARAM_MODULATED_DTIM]) {
6846 pReq->paramValue = nla_get_u32(
6847 tb[PARAM_MODULATED_DTIM]);
6848 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
6849 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05306850 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05306851 hdd_set_pwrparams(pHddCtx);
6852 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
6853 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
6854
6855 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
6856 iw_full_power_cbfn, pAdapter,
6857 eSME_FULL_PWR_NEEDED_BY_HDD);
6858 }
6859 else
6860 {
6861 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
6862 }
6863 }
6864
6865 if (tb[PARAM_STATS_AVG_FACTOR]) {
6866 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
6867 pReq->paramValue = nla_get_u16(
6868 tb[PARAM_STATS_AVG_FACTOR]);
6869 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
6870 pReq->paramType, pReq->paramValue);
6871 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
6872
6873 if (eHAL_STATUS_SUCCESS != status)
6874 {
6875 vos_mem_free(pReq);
6876 pReq = NULL;
6877 ret_val = -EPERM;
6878 return ret_val;
6879 }
6880 }
6881
6882
6883 if (tb[PARAM_GUARD_TIME]) {
6884 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
6885 pReq->paramValue = nla_get_u32(
6886 tb[PARAM_GUARD_TIME]);
6887 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
6888 pReq->paramType, pReq->paramValue);
6889 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
6890
6891 if (eHAL_STATUS_SUCCESS != status)
6892 {
6893 vos_mem_free(pReq);
6894 pReq = NULL;
6895 ret_val = -EPERM;
6896 return ret_val;
6897 }
6898
6899 }
6900
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05306901 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
6902 hb_thresh_val = nla_get_u8(
6903 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
6904
6905 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
6906 hb_thresh_val);
6907 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6908 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
6909 NULL, eANI_BOOLEAN_FALSE);
6910
6911 status = sme_update_hb_threshold(
6912 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
6913 WNI_CFG_HEART_BEAT_THRESHOLD,
6914 hb_thresh_val, eCSR_BAND_24);
6915 if (eHAL_STATUS_SUCCESS != status) {
6916 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
6917 vos_mem_free(pReq);
6918 pReq = NULL;
6919 return -EPERM;
6920 }
6921 }
6922
6923 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
6924 hb_thresh_val = nla_get_u8(
6925 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
6926
6927 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
6928 hb_thresh_val);
6929 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6930 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
6931 NULL, eANI_BOOLEAN_FALSE);
6932
6933 status = sme_update_hb_threshold(
6934 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
6935 WNI_CFG_HEART_BEAT_THRESHOLD,
6936 hb_thresh_val, eCSR_BAND_5G);
6937 if (eHAL_STATUS_SUCCESS != status) {
6938 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
6939 vos_mem_free(pReq);
6940 pReq = NULL;
6941 return -EPERM;
6942 }
6943 }
6944
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05306945 EXIT();
6946 return ret_val;
6947}
6948
6949/**
6950 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
6951 * vendor command
6952 *
6953 * @wiphy: wiphy device pointer
6954 * @wdev: wireless device pointer
6955 * @data: Vendor command data buffer
6956 * @data_len: Buffer length
6957 *
6958 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
6959 *
6960 * Return: EOK or other error codes.
6961 */
6962static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
6963 struct wireless_dev *wdev,
6964 const void *data,
6965 int data_len)
6966{
6967 int ret;
6968
6969 vos_ssr_protect(__func__);
6970 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
6971 data, data_len);
6972 vos_ssr_unprotect(__func__);
6973
6974 return ret;
6975}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05306976
6977/*
6978 * define short names for the global vendor params
6979 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
6980 */
6981#define STATS_SET_INVALID \
6982 QCA_ATTR_NUD_STATS_SET_INVALID
6983#define STATS_SET_START \
6984 QCA_ATTR_NUD_STATS_SET_START
6985#define STATS_GW_IPV4 \
6986 QCA_ATTR_NUD_STATS_GW_IPV4
6987#define STATS_SET_MAX \
6988 QCA_ATTR_NUD_STATS_SET_MAX
6989
6990const struct nla_policy
6991qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
6992{
6993 [STATS_SET_START] = {.type = NLA_FLAG },
6994 [STATS_GW_IPV4] = {.type = NLA_U32 },
6995};
6996
6997/**
6998 * hdd_set_nud_stats_cb() - hdd callback api to get status
6999 * @data: pointer to adapter
7000 * @rsp: status
7001 *
7002 * Return: None
7003 */
7004static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
7005{
7006
7007 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7008
7009 if (NULL == adapter)
7010 return;
7011
7012 if (VOS_STATUS_SUCCESS == rsp) {
7013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7014 "%s success received STATS_SET_START", __func__);
7015 } else {
7016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7017 "%s STATS_SET_START Failed!!", __func__);
7018 }
7019 return;
7020}
7021
7022/**
7023 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7024 * @wiphy: pointer to wireless wiphy structure.
7025 * @wdev: pointer to wireless_dev structure.
7026 * @data: pointer to apfind configuration data.
7027 * @data_len: the length in byte of apfind data.
7028 *
7029 * This is called when wlan driver needs to send arp stats to
7030 * firmware.
7031 *
7032 * Return: An error code or 0 on success.
7033 */
7034static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7035 struct wireless_dev *wdev,
7036 const void *data, int data_len)
7037{
7038 struct nlattr *tb[STATS_SET_MAX + 1];
7039 struct net_device *dev = wdev->netdev;
7040 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7041 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05307042 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307043 setArpStatsParams arp_stats_params;
7044 int err = 0;
7045
7046 ENTER();
7047
7048 err = wlan_hdd_validate_context(hdd_ctx);
7049 if (0 != err)
7050 return err;
7051
7052 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
7053 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7054 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
7055 return -EINVAL;
7056 }
7057
7058 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
7059 qca_wlan_vendor_set_nud_stats);
7060 if (err)
7061 {
7062 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7063 "%s STATS_SET_START ATTR", __func__);
7064 return err;
7065 }
7066
7067 if (tb[STATS_SET_START])
7068 {
7069 if (!tb[STATS_GW_IPV4]) {
7070 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7071 "%s STATS_SET_START CMD", __func__);
7072 return -EINVAL;
7073 }
7074 arp_stats_params.flag = true;
7075 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
7076 } else {
7077 arp_stats_params.flag = false;
7078 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05307079 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307080 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7081 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05307082 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
7083 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307084
7085 arp_stats_params.pkt_type = 1; // ARP packet type
7086
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05307087 if (arp_stats_params.flag) {
7088 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
7089 WLANTL_SetARPFWDatapath(pVosContext, true);
7090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7091 "%s Set FW in data path for ARP with tgt IP :%d",
7092 __func__, hdd_ctx->track_arp_ip);
7093 }
7094 else {
7095 WLANTL_SetARPFWDatapath(pVosContext, false);
7096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7097 "%s Remove FW from data path", __func__);
7098 }
7099
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307100 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
7101 arp_stats_params.data_ctx = adapter;
7102
7103 if (eHAL_STATUS_SUCCESS !=
7104 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
7105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7106 "%s STATS_SET_START CMD Failed!!", __func__);
7107 return -EINVAL;
7108 }
7109
7110 EXIT();
7111
7112 return err;
7113}
7114
7115/**
7116 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7117 * @wiphy: pointer to wireless wiphy structure.
7118 * @wdev: pointer to wireless_dev structure.
7119 * @data: pointer to apfind configuration data.
7120 * @data_len: the length in byte of apfind data.
7121 *
7122 * This is called when wlan driver needs to send arp stats to
7123 * firmware.
7124 *
7125 * Return: An error code or 0 on success.
7126 */
7127static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7128 struct wireless_dev *wdev,
7129 const void *data, int data_len)
7130{
7131 int ret;
7132
7133 vos_ssr_protect(__func__);
7134 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
7135 vos_ssr_unprotect(__func__);
7136
7137 return ret;
7138}
7139#undef STATS_SET_INVALID
7140#undef STATS_SET_START
7141#undef STATS_GW_IPV4
7142#undef STATS_SET_MAX
7143
7144/*
7145 * define short names for the global vendor params
7146 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7147 */
7148#define STATS_GET_INVALID \
7149 QCA_ATTR_NUD_STATS_SET_INVALID
7150#define COUNT_FROM_NETDEV \
7151 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
7152#define COUNT_TO_LOWER_MAC \
7153 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
7154#define RX_COUNT_BY_LOWER_MAC \
7155 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
7156#define COUNT_TX_SUCCESS \
7157 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
7158#define RSP_RX_COUNT_BY_LOWER_MAC \
7159 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
7160#define RSP_RX_COUNT_BY_UPPER_MAC \
7161 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
7162#define RSP_COUNT_TO_NETDEV \
7163 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
7164#define RSP_COUNT_OUT_OF_ORDER_DROP \
7165 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
7166#define AP_LINK_ACTIVE \
7167 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
7168#define AP_LINK_DAD \
7169 QCA_ATTR_NUD_STATS_AP_LINK_DAD
7170#define STATS_GET_MAX \
7171 QCA_ATTR_NUD_STATS_GET_MAX
7172
7173const struct nla_policy
7174qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
7175{
7176 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
7177 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
7178 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
7179 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
7180 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
7181 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
7182 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
7183 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
7184 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
7185 [AP_LINK_DAD] = {.type = NLA_FLAG },
7186};
7187
7188static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
7189{
7190
7191 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7192 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7193 struct hdd_nud_stats_context *context;
7194 int status;
7195
7196 ENTER();
7197
7198 if (NULL == adapter)
7199 return;
7200
7201 status = wlan_hdd_validate_context(hdd_ctx);
7202 if (0 != status) {
7203 return;
7204 }
7205
7206 if (!rsp) {
7207 hddLog(LOGE, FL("data is null"));
7208 return;
7209 }
7210
7211 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
7212 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
7213 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
7214 adapter->dad |= rsp->dad;
7215
7216 spin_lock(&hdd_context_lock);
7217 context = &hdd_ctx->nud_stats_context;
7218 complete(&context->response_event);
7219 spin_unlock(&hdd_context_lock);
7220
7221 return;
7222}
7223static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
7224 struct wireless_dev *wdev,
7225 const void *data, int data_len)
7226{
7227 int err = 0;
7228 unsigned long rc;
7229 struct hdd_nud_stats_context *context;
7230 struct net_device *dev = wdev->netdev;
7231 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7232 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7233 getArpStatsParams arp_stats_params;
7234 struct sk_buff *skb;
7235
7236 ENTER();
7237
7238 err = wlan_hdd_validate_context(hdd_ctx);
7239 if (0 != err)
7240 return err;
7241
7242 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
7243 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
7244 arp_stats_params.data_ctx = adapter;
7245
7246 spin_lock(&hdd_context_lock);
7247 context = &hdd_ctx->nud_stats_context;
7248 INIT_COMPLETION(context->response_event);
7249 spin_unlock(&hdd_context_lock);
7250
7251 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
7252 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7253 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
7254 return -EINVAL;
7255 }
7256
7257 if (eHAL_STATUS_SUCCESS !=
7258 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
7259 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7260 "%s STATS_SET_START CMD Failed!!", __func__);
7261 return -EINVAL;
7262 }
7263
7264 rc = wait_for_completion_timeout(&context->response_event,
7265 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
7266 if (!rc)
7267 {
7268 hddLog(LOGE,
7269 FL("Target response timed out request "));
7270 return -ETIMEDOUT;
7271 }
7272
7273 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7274 WLAN_NUD_STATS_LEN);
7275 if (!skb)
7276 {
7277 hddLog(VOS_TRACE_LEVEL_ERROR,
7278 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
7279 __func__);
7280 return -ENOMEM;
7281 }
7282
7283 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
7284 adapter->hdd_stats.hddArpStats.txCount) ||
7285 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
7286 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
7287 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
7288 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
7289 nla_put_u16(skb, COUNT_TX_SUCCESS,
7290 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
7291 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
7292 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
7293 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
7294 adapter->hdd_stats.hddArpStats.rxCount) ||
7295 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
7296 adapter->hdd_stats.hddArpStats.rxDelivered) ||
7297 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
7298 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
7299 hddLog(LOGE, FL("nla put fail"));
7300 kfree_skb(skb);
7301 return -EINVAL;
7302 }
7303 if (adapter->con_status)
7304 nla_put_flag(skb, AP_LINK_ACTIVE);
7305 if (adapter->dad)
7306 nla_put_flag(skb, AP_LINK_DAD);
7307
7308 cfg80211_vendor_cmd_reply(skb);
7309 return err;
7310}
7311
7312static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
7313 struct wireless_dev *wdev,
7314 const void *data, int data_len)
7315{
7316 int ret;
7317
7318 vos_ssr_protect(__func__);
7319 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
7320 vos_ssr_unprotect(__func__);
7321
7322 return ret;
7323}
7324
7325#undef QCA_ATTR_NUD_STATS_SET_INVALID
7326#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
7327#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
7328#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
7329#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
7330#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
7331#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
7332#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
7333#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
7334#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
7335#undef QCA_ATTR_NUD_STATS_GET_MAX
7336
7337
7338
Kapil Guptaee33bf12016-12-20 18:27:37 +05307339#ifdef WLAN_FEATURE_APFIND
7340/**
7341 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
7342 * @wiphy: pointer to wireless wiphy structure.
7343 * @wdev: pointer to wireless_dev structure.
7344 * @data: pointer to apfind configuration data.
7345 * @data_len: the length in byte of apfind data.
7346 *
7347 * This is called when wlan driver needs to send APFIND configurations to
7348 * firmware.
7349 *
7350 * Return: An error code or 0 on success.
7351 */
7352static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
7353 struct wireless_dev *wdev,
7354 const void *data, int data_len)
7355{
7356 struct sme_ap_find_request_req apfind_req;
7357 VOS_STATUS status;
7358 int ret_val;
7359 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7360
7361 ENTER();
7362
7363 ret_val = wlan_hdd_validate_context(hdd_ctx);
7364 if (ret_val)
7365 return ret_val;
7366
7367 if (VOS_FTM_MODE == hdd_get_conparam()) {
7368 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7369 return -EPERM;
7370 }
7371
7372 apfind_req.request_data_len = data_len;
7373 apfind_req.request_data = data;
7374
7375 status = sme_apfind_set_cmd(&apfind_req);
7376 if (VOS_STATUS_SUCCESS != status) {
7377 ret_val = -EIO;
7378 }
7379 return ret_val;
7380}
7381
7382/**
7383 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
7384 * @wiphy: pointer to wireless wiphy structure.
7385 * @wdev: pointer to wireless_dev structure.
7386 * @data: pointer to apfind configuration data.
7387 * @data_len: the length in byte of apfind data.
7388 *
7389 * This is called when wlan driver needs to send APFIND configurations to
7390 * firmware.
7391 *
7392 * Return: An error code or 0 on success.
7393 */
7394static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
7395 struct wireless_dev *wdev,
7396 const void *data, int data_len)
7397{
7398 int ret;
7399
7400 vos_ssr_protect(__func__);
7401 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
7402 vos_ssr_unprotect(__func__);
7403
7404 return ret;
7405}
7406#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307407const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7408{
Mukul Sharma2a271632014-10-13 14:59:01 +05307409 {
7410 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7411 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7412 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7413 WIPHY_VENDOR_CMD_NEED_NETDEV |
7414 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307415 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307416 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307417
7418 {
7419 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7420 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7421 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7422 WIPHY_VENDOR_CMD_NEED_NETDEV |
7423 WIPHY_VENDOR_CMD_NEED_RUNNING,
7424 .doit = wlan_hdd_cfg80211_nan_request
7425 },
7426
Sunil Duttc69bccb2014-05-26 21:30:20 +05307427#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7428 {
7429 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7430 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7431 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7432 WIPHY_VENDOR_CMD_NEED_NETDEV |
7433 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307434 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307435 },
7436
7437 {
7438 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7439 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7440 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7441 WIPHY_VENDOR_CMD_NEED_NETDEV |
7442 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307443 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307444 },
7445
7446 {
7447 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7448 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7449 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7450 WIPHY_VENDOR_CMD_NEED_NETDEV |
7451 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307452 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307453 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307454#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307455#ifdef WLAN_FEATURE_EXTSCAN
7456 {
7457 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7458 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7459 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7460 WIPHY_VENDOR_CMD_NEED_NETDEV |
7461 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307462 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307463 },
7464 {
7465 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7466 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
7467 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7468 WIPHY_VENDOR_CMD_NEED_NETDEV |
7469 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307470 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05307471 },
7472 {
7473 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7474 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
7475 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7476 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307477 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05307478 },
7479 {
7480 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7481 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
7482 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7483 WIPHY_VENDOR_CMD_NEED_NETDEV |
7484 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307485 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05307486 },
7487 {
7488 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7489 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
7490 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7491 WIPHY_VENDOR_CMD_NEED_NETDEV |
7492 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307493 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05307494 },
7495 {
7496 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7497 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
7498 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7499 WIPHY_VENDOR_CMD_NEED_NETDEV |
7500 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307501 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307502 },
7503 {
7504 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7505 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
7506 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7507 WIPHY_VENDOR_CMD_NEED_NETDEV |
7508 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307509 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307510 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307511#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307512/*EXT TDLS*/
7513 {
7514 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7515 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
7516 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7517 WIPHY_VENDOR_CMD_NEED_NETDEV |
7518 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307519 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05307520 },
7521 {
7522 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7523 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
7524 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7525 WIPHY_VENDOR_CMD_NEED_NETDEV |
7526 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307527 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05307528 },
7529 {
7530 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7531 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
7532 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7533 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307534 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05307535 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05307536 {
7537 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7538 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
7539 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7540 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307541 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05307542 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05307543 {
7544 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7545 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
7546 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7547 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307548 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05307549 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307550 {
7551 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7552 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
7553 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7554 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307555 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307556 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307557 {
7558 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7559 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
7560 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7561 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307562 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307563 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307564 {
7565 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05307566 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
7567 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7568 WIPHY_VENDOR_CMD_NEED_NETDEV |
7569 WIPHY_VENDOR_CMD_NEED_RUNNING,
7570 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
7571 },
7572 {
7573 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307574 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
7575 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7576 WIPHY_VENDOR_CMD_NEED_NETDEV |
7577 WIPHY_VENDOR_CMD_NEED_RUNNING,
7578 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05307579 },
7580 {
7581 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7582 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
7583 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7584 WIPHY_VENDOR_CMD_NEED_NETDEV,
7585 .doit = wlan_hdd_cfg80211_wifi_logger_start
7586 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05307587 {
7588 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7589 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
7590 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7591 WIPHY_VENDOR_CMD_NEED_NETDEV|
7592 WIPHY_VENDOR_CMD_NEED_RUNNING,
7593 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05307594 },
7595 {
7596 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7597 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
7598 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7599 WIPHY_VENDOR_CMD_NEED_NETDEV |
7600 WIPHY_VENDOR_CMD_NEED_RUNNING,
7601 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307602 },
7603 {
7604 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7605 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
7606 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7607 WIPHY_VENDOR_CMD_NEED_NETDEV |
7608 WIPHY_VENDOR_CMD_NEED_RUNNING,
7609 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307610 },
7611#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7612 {
7613 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7614 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
7615 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7616 WIPHY_VENDOR_CMD_NEED_NETDEV |
7617 WIPHY_VENDOR_CMD_NEED_RUNNING,
7618 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307619 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307620#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307621 {
7622 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7623 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
7624 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7625 WIPHY_VENDOR_CMD_NEED_NETDEV |
7626 WIPHY_VENDOR_CMD_NEED_RUNNING,
7627 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307628 },
7629 {
7630 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7631 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
7632 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7633 WIPHY_VENDOR_CMD_NEED_NETDEV |
7634 WIPHY_VENDOR_CMD_NEED_RUNNING,
7635 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05307636 },
7637#ifdef WLAN_FEATURE_APFIND
7638 {
7639 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7640 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
7641 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7642 WIPHY_VENDOR_CMD_NEED_NETDEV,
7643 .doit = wlan_hdd_cfg80211_apfind_cmd
7644 },
7645#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307646 {
7647 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7648 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
7649 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7650 WIPHY_VENDOR_CMD_NEED_NETDEV |
7651 WIPHY_VENDOR_CMD_NEED_RUNNING,
7652 .doit = wlan_hdd_cfg80211_set_nud_stats
7653 },
7654 {
7655 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7656 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
7657 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7658 WIPHY_VENDOR_CMD_NEED_NETDEV |
7659 WIPHY_VENDOR_CMD_NEED_RUNNING,
7660 .doit = wlan_hdd_cfg80211_get_nud_stats
7661 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307662};
7663
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007664/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307665static const
7666struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007667{
7668#ifdef FEATURE_WLAN_CH_AVOID
7669 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05307670 .vendor_id = QCA_NL80211_VENDOR_ID,
7671 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007672 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307673#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
7674#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7675 {
7676 /* Index = 1*/
7677 .vendor_id = QCA_NL80211_VENDOR_ID,
7678 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
7679 },
7680 {
7681 /* Index = 2*/
7682 .vendor_id = QCA_NL80211_VENDOR_ID,
7683 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
7684 },
7685 {
7686 /* Index = 3*/
7687 .vendor_id = QCA_NL80211_VENDOR_ID,
7688 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
7689 },
7690 {
7691 /* Index = 4*/
7692 .vendor_id = QCA_NL80211_VENDOR_ID,
7693 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
7694 },
7695 {
7696 /* Index = 5*/
7697 .vendor_id = QCA_NL80211_VENDOR_ID,
7698 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
7699 },
7700 {
7701 /* Index = 6*/
7702 .vendor_id = QCA_NL80211_VENDOR_ID,
7703 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
7704 },
7705#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307706#ifdef WLAN_FEATURE_EXTSCAN
7707 {
7708 .vendor_id = QCA_NL80211_VENDOR_ID,
7709 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
7710 },
7711 {
7712 .vendor_id = QCA_NL80211_VENDOR_ID,
7713 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
7714 },
7715 {
7716 .vendor_id = QCA_NL80211_VENDOR_ID,
7717 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
7718 },
7719 {
7720 .vendor_id = QCA_NL80211_VENDOR_ID,
7721 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
7722 },
7723 {
7724 .vendor_id = QCA_NL80211_VENDOR_ID,
7725 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
7726 },
7727 {
7728 .vendor_id = QCA_NL80211_VENDOR_ID,
7729 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
7730 },
7731 {
7732 .vendor_id = QCA_NL80211_VENDOR_ID,
7733 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
7734 },
7735 {
7736 .vendor_id = QCA_NL80211_VENDOR_ID,
7737 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
7738 },
7739 {
7740 .vendor_id = QCA_NL80211_VENDOR_ID,
7741 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
7742 },
7743 {
7744 .vendor_id = QCA_NL80211_VENDOR_ID,
7745 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
7746 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307747#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307748/*EXT TDLS*/
7749 {
7750 .vendor_id = QCA_NL80211_VENDOR_ID,
7751 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
7752 },
c_manjeecfd1efb2015-09-25 19:32:34 +05307753 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
7754 .vendor_id = QCA_NL80211_VENDOR_ID,
7755 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
7756 },
7757
Srinivas Dasari030bad32015-02-18 23:23:54 +05307758
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05307759 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05307760 .vendor_id = QCA_NL80211_VENDOR_ID,
7761 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
7762 },
7763
Sushant Kaushik084f6592015-09-10 13:11:56 +05307764 {
7765 .vendor_id = QCA_NL80211_VENDOR_ID,
7766 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307767 },
7768 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
7769 .vendor_id = QCA_NL80211_VENDOR_ID,
7770 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
7771 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05307772 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
7773 .vendor_id = QCA_NL80211_VENDOR_ID,
7774 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
7775 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307776 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
7777 .vendor_id = QCA_NL80211_VENDOR_ID,
7778 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
7779 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007780};
7781
Jeff Johnson295189b2012-06-20 16:38:30 -07007782/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307783 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307784 * This function is called by hdd_wlan_startup()
7785 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307786 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07007787 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307788struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07007789{
7790 struct wiphy *wiphy;
7791 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307792 /*
7793 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07007794 */
7795 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
7796
7797 if (!wiphy)
7798 {
7799 /* Print error and jump into err label and free the memory */
7800 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
7801 return NULL;
7802 }
7803
Sunil Duttc69bccb2014-05-26 21:30:20 +05307804
Jeff Johnson295189b2012-06-20 16:38:30 -07007805 return wiphy;
7806}
7807
Anurag Chouhan343af7e2016-12-16 13:11:19 +05307808#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
7809 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
7810/**
7811 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
7812 * @wiphy: pointer to wiphy
7813 * @config: pointer to config
7814 *
7815 * Return: None
7816 */
7817static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
7818 hdd_config_t *config)
7819{
7820 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
7821 if (config->max_sched_scan_plan_interval)
7822 wiphy->max_sched_scan_plan_interval =
7823 config->max_sched_scan_plan_interval;
7824 if (config->max_sched_scan_plan_iterations)
7825 wiphy->max_sched_scan_plan_iterations =
7826 config->max_sched_scan_plan_iterations;
7827}
7828#else
7829static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
7830 hdd_config_t *config)
7831{
7832}
7833#endif
7834
Jeff Johnson295189b2012-06-20 16:38:30 -07007835/*
7836 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307837 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07007838 * private ioctl to change the band value
7839 */
7840int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
7841{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307842 int i, j;
7843 eNVChannelEnabledType channelEnabledState;
7844
Jeff Johnsone7245742012-09-05 17:12:55 -07007845 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307846
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307847 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007848 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307849
7850 if (NULL == wiphy->bands[i])
7851 {
7852 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
7853 __func__, i);
7854 continue;
7855 }
7856
7857 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7858 {
7859 struct ieee80211_supported_band *band = wiphy->bands[i];
7860
7861 channelEnabledState = vos_nv_getChannelEnabledState(
7862 band->channels[j].hw_value);
7863
7864 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
7865 {
Abhishek Singh678227a2014-11-04 10:52:38 +05307866 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307867 continue;
7868 }
7869 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
7870 {
7871 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7872 continue;
7873 }
7874
7875 if (NV_CHANNEL_DISABLE == channelEnabledState ||
7876 NV_CHANNEL_INVALID == channelEnabledState)
7877 {
7878 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7879 }
7880 else if (NV_CHANNEL_DFS == channelEnabledState)
7881 {
7882 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7883 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
7884 }
7885 else
7886 {
7887 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
7888 |IEEE80211_CHAN_RADAR);
7889 }
7890 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007891 }
7892 return 0;
7893}
7894/*
7895 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307896 * This function is called by hdd_wlan_startup()
7897 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07007898 * This function is used to initialize and register wiphy structure.
7899 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307900int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007901 struct wiphy *wiphy,
7902 hdd_config_t *pCfg
7903 )
7904{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307905 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307906 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7907
Jeff Johnsone7245742012-09-05 17:12:55 -07007908 ENTER();
7909
Jeff Johnson295189b2012-06-20 16:38:30 -07007910 /* Now bind the underlying wlan device with wiphy */
7911 set_wiphy_dev(wiphy, dev);
7912
7913 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007914
Kiet Lam6c583332013-10-14 05:37:09 +05307915#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007916 /* the flag for the other case would be initialzed in
7917 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05307918#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7919 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
7920#else
Amar Singhal0a402232013-10-11 20:57:16 -07007921 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05307922#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05307923#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007924
Amar Singhalfddc28c2013-09-05 13:03:40 -07007925 /* This will disable updating of NL channels from passive to
7926 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307927#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7928 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
7929#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07007930 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307931#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07007932
Amar Singhala49cbc52013-10-08 18:37:44 -07007933
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007934#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07007935 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
7936 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
7937 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07007938 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307939#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05307940 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307941#else
7942 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
7943#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007944#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007945
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007946#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007947 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08007948#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007949 || pCfg->isFastRoamIniFeatureEnabled
7950#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007951#ifdef FEATURE_WLAN_ESE
7952 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007953#endif
7954 )
7955 {
7956 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
7957 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08007958#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007959#ifdef FEATURE_WLAN_TDLS
7960 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
7961 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
7962#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307963#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05307964 if (pCfg->configPNOScanSupport)
7965 {
7966 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
7967 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
7968 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
7969 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
7970 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307971#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007972
Abhishek Singh10d85972015-04-17 10:27:23 +05307973#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7974 wiphy->features |= NL80211_FEATURE_HT_IBSS;
7975#endif
7976
Amar Singhalfddc28c2013-09-05 13:03:40 -07007977#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007978 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
7979 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07007980 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007981 driver need to determine what to do with both
7982 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07007983
7984 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07007985#else
7986 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007987#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007988
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307989 wiphy->max_scan_ssids = MAX_SCAN_SSID;
7990
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05307991 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07007992
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307993 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
7994
Jeff Johnson295189b2012-06-20 16:38:30 -07007995 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05307996 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
7997 | BIT(NL80211_IFTYPE_ADHOC)
7998 | BIT(NL80211_IFTYPE_P2P_CLIENT)
7999 | BIT(NL80211_IFTYPE_P2P_GO)
8000 | BIT(NL80211_IFTYPE_AP);
8001
8002 if (VOS_MONITOR_MODE == hdd_get_conparam())
8003 {
8004 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
8005 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008006
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308007 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008008 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308009#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8010 if( pCfg->enableMCC )
8011 {
8012 /* Currently, supports up to two channels */
8013 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008014
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308015 if( !pCfg->allowMCCGODiffBI )
8016 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008017
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308018 }
8019 wiphy->iface_combinations = &wlan_hdd_iface_combination;
8020 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008021#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308022 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008023
Jeff Johnson295189b2012-06-20 16:38:30 -07008024 /* Before registering we need to update the ht capabilitied based
8025 * on ini values*/
8026 if( !pCfg->ShortGI20MhzEnable )
8027 {
8028 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8029 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008030 }
8031
8032 if( !pCfg->ShortGI40MhzEnable )
8033 {
8034 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8035 }
8036
8037 if( !pCfg->nChannelBondingMode5GHz )
8038 {
8039 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8040 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308041 /*
8042 * In case of static linked driver at the time of driver unload,
8043 * module exit doesn't happens. Module cleanup helps in cleaning
8044 * of static memory.
8045 * If driver load happens statically, at the time of driver unload,
8046 * wiphy flags don't get reset because of static memory.
8047 * It's better not to store channel in static memory.
8048 */
8049 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8050 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8051 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
8052 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
8053 {
8054 hddLog(VOS_TRACE_LEVEL_ERROR,
8055 FL("Not enough memory to allocate channels"));
8056 return -ENOMEM;
8057 }
8058 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
8059 &hdd_channels_2_4_GHZ[0],
8060 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008061
Agrawal Ashish97dec502015-11-26 20:20:58 +05308062 if (true == hdd_is_5g_supported(pHddCtx))
8063 {
8064 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8065 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8066 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8067 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8068 {
8069 hddLog(VOS_TRACE_LEVEL_ERROR,
8070 FL("Not enough memory to allocate channels"));
8071 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8072 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8073 return -ENOMEM;
8074 }
8075 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8076 &hdd_channels_5_GHZ[0],
8077 sizeof(hdd_channels_5_GHZ));
8078 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308079
8080 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8081 {
8082
8083 if (NULL == wiphy->bands[i])
8084 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308085 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308086 __func__, i);
8087 continue;
8088 }
8089
8090 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8091 {
8092 struct ieee80211_supported_band *band = wiphy->bands[i];
8093
8094 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8095 {
8096 // Enable social channels for P2P
8097 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8098 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8099 else
8100 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8101 continue;
8102 }
8103 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8104 {
8105 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8106 continue;
8107 }
8108 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008109 }
8110 /*Initialise the supported cipher suite details*/
8111 wiphy->cipher_suites = hdd_cipher_suites;
8112 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8113
8114 /*signal strength in mBm (100*dBm) */
8115 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8116
8117#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308118 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008119#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008120
Sunil Duttc69bccb2014-05-26 21:30:20 +05308121 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8122 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008123 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8124 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8125
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308126 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
8127
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308128 EXIT();
8129 return 0;
8130}
8131
8132/* In this function we are registering wiphy. */
8133int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8134{
8135 ENTER();
8136 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008137 if (0 > wiphy_register(wiphy))
8138 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308139 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008140 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8141 return -EIO;
8142 }
8143
8144 EXIT();
8145 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308146}
Jeff Johnson295189b2012-06-20 16:38:30 -07008147
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308148/* In this function we are updating channel list when,
8149 regulatory domain is FCC and country code is US.
8150 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8151 As per FCC smart phone is not a indoor device.
8152 GO should not opeate on indoor channels */
8153void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8154{
8155 int j;
8156 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8157 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8158 //Default counrtycode from NV at the time of wiphy initialization.
8159 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8160 &defaultCountryCode[0]))
8161 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008162 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308163 }
8164 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8165 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308166 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8167 {
8168 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8169 return;
8170 }
8171 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8172 {
8173 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8174 // Mark UNII -1 band channel as passive
8175 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8176 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8177 }
8178 }
8179}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308180/* This function registers for all frame which supplicant is interested in */
8181void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008182{
Jeff Johnson295189b2012-06-20 16:38:30 -07008183 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8184 /* Register for all P2P action, public action etc frames */
8185 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008186 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308187 /* Register frame indication call back */
8188 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008189 /* Right now we are registering these frame when driver is getting
8190 initialized. Once we will move to 2.6.37 kernel, in which we have
8191 frame register ops, we will move this code as a part of that */
8192 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308193 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008194 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8195
8196 /* GAS Initial Response */
8197 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8198 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308199
Jeff Johnson295189b2012-06-20 16:38:30 -07008200 /* GAS Comeback Request */
8201 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8202 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8203
8204 /* GAS Comeback Response */
8205 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8206 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8207
8208 /* P2P Public Action */
8209 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308210 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008211 P2P_PUBLIC_ACTION_FRAME_SIZE );
8212
8213 /* P2P Action */
8214 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8215 (v_U8_t*)P2P_ACTION_FRAME,
8216 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008217
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308218 /* WNM BSS Transition Request frame */
8219 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8220 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8221 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008222
8223 /* WNM-Notification */
8224 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8225 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8226 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008227}
8228
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308229void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008230{
Jeff Johnson295189b2012-06-20 16:38:30 -07008231 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8232 /* Register for all P2P action, public action etc frames */
8233 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8234
Jeff Johnsone7245742012-09-05 17:12:55 -07008235 ENTER();
8236
Jeff Johnson295189b2012-06-20 16:38:30 -07008237 /* Right now we are registering these frame when driver is getting
8238 initialized. Once we will move to 2.6.37 kernel, in which we have
8239 frame register ops, we will move this code as a part of that */
8240 /* GAS Initial Request */
8241
8242 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8243 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8244
8245 /* GAS Initial Response */
8246 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8247 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308248
Jeff Johnson295189b2012-06-20 16:38:30 -07008249 /* GAS Comeback Request */
8250 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8251 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8252
8253 /* GAS Comeback Response */
8254 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8255 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8256
8257 /* P2P Public Action */
8258 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308259 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008260 P2P_PUBLIC_ACTION_FRAME_SIZE );
8261
8262 /* P2P Action */
8263 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8264 (v_U8_t*)P2P_ACTION_FRAME,
8265 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008266 /* WNM-Notification */
8267 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8268 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8269 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008270}
8271
8272#ifdef FEATURE_WLAN_WAPI
8273void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308274 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008275{
8276 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8277 tCsrRoamSetKey setKey;
8278 v_BOOL_t isConnected = TRUE;
8279 int status = 0;
8280 v_U32_t roamId= 0xFF;
8281 tANI_U8 *pKeyPtr = NULL;
8282 int n = 0;
8283
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308284 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8285 __func__, hdd_device_modetoString(pAdapter->device_mode),
8286 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008287
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308288 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008289 setKey.keyId = key_index; // Store Key ID
8290 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8291 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8292 setKey.paeRole = 0 ; // the PAE role
8293 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8294 {
8295 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8296 }
8297 else
8298 {
8299 isConnected = hdd_connIsConnected(pHddStaCtx);
8300 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8301 }
8302 setKey.keyLength = key_Len;
8303 pKeyPtr = setKey.Key;
8304 memcpy( pKeyPtr, key, key_Len);
8305
Arif Hussain6d2a3322013-11-17 19:50:10 -08008306 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008307 __func__, key_Len);
8308 for (n = 0 ; n < key_Len; n++)
8309 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8310 __func__,n,setKey.Key[n]);
8311
8312 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8313 if ( isConnected )
8314 {
8315 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8316 pAdapter->sessionId, &setKey, &roamId );
8317 }
8318 if ( status != 0 )
8319 {
8320 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8321 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8322 __LINE__, status );
8323 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8324 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308325 /* Need to clear any trace of key value in the memory.
8326 * Thus zero out the memory even though it is local
8327 * variable.
8328 */
8329 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008330}
8331#endif /* FEATURE_WLAN_WAPI*/
8332
8333#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308334int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008335 beacon_data_t **ppBeacon,
8336 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008337#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308338int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008339 beacon_data_t **ppBeacon,
8340 struct cfg80211_beacon_data *params,
8341 int dtim_period)
8342#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308343{
Jeff Johnson295189b2012-06-20 16:38:30 -07008344 int size;
8345 beacon_data_t *beacon = NULL;
8346 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05308347 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
8348 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07008349
Jeff Johnsone7245742012-09-05 17:12:55 -07008350 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008351 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308352 {
8353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8354 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008355 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308356 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008357
8358 old = pAdapter->sessionCtx.ap.beacon;
8359
8360 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308361 {
8362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8363 FL("session(%d) old and new heads points to NULL"),
8364 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008365 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308366 }
8367
8368 if (params->tail && !params->tail_len)
8369 {
8370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8371 FL("tail_len is zero but tail is not NULL"));
8372 return -EINVAL;
8373 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008374
Jeff Johnson295189b2012-06-20 16:38:30 -07008375#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8376 /* Kernel 3.0 is not updating dtim_period for set beacon */
8377 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308378 {
8379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8380 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008381 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308382 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008383#endif
8384
Kapil Gupta137ef892016-12-13 19:38:00 +05308385 if (params->head)
8386 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008387 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308388 head = params->head;
8389 } else
8390 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008391 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308392 head = old->head;
8393 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008394
Kapil Gupta137ef892016-12-13 19:38:00 +05308395 if (params->tail || !old)
8396 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008397 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308398 tail = params->tail;
8399 } else
8400 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008401 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308402 tail = old->tail;
8403 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008404
Kapil Gupta137ef892016-12-13 19:38:00 +05308405 if (params->proberesp_ies || !old)
8406 {
8407 proberesp_ies_len = params->proberesp_ies_len;
8408 proberesp_ies = params->proberesp_ies;
8409 } else
8410 {
8411 proberesp_ies_len = old->proberesp_ies_len;
8412 proberesp_ies = old->proberesp_ies;
8413 }
8414
8415 if (params->assocresp_ies || !old)
8416 {
8417 assocresp_ies_len = params->assocresp_ies_len;
8418 assocresp_ies = params->assocresp_ies;
8419 } else
8420 {
8421 assocresp_ies_len = old->assocresp_ies_len;
8422 assocresp_ies = old->assocresp_ies;
8423 }
8424
8425 size = sizeof(beacon_data_t) + head_len + tail_len +
8426 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07008427
8428 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008429 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308430 {
8431 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8432 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008433 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308434 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008435
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008436#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05308437 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07008438 beacon->dtim_period = params->dtim_period;
8439 else
8440 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008441#else
Kapil Gupta137ef892016-12-13 19:38:00 +05308442 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008443 beacon->dtim_period = dtim_period;
8444 else
8445 beacon->dtim_period = old->dtim_period;
8446#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308447
Jeff Johnson295189b2012-06-20 16:38:30 -07008448 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8449 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308450 beacon->proberesp_ies = beacon->tail + tail_len;
8451 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
8452
Jeff Johnson295189b2012-06-20 16:38:30 -07008453 beacon->head_len = head_len;
8454 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05308455 beacon->proberesp_ies_len = proberesp_ies_len;
8456 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07008457
c_manjee527ecac2017-01-25 12:25:27 +05308458 if (head && head_len)
8459 memcpy(beacon->head, head, head_len);
8460 if (tail && tail_len)
8461 memcpy(beacon->tail, tail, tail_len);
8462 if (proberesp_ies && proberesp_ies_len)
8463 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
8464 if (assocresp_ies && assocresp_ies_len)
8465 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008466
8467 *ppBeacon = beacon;
8468
8469 kfree(old);
8470
8471 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008472}
Jeff Johnson295189b2012-06-20 16:38:30 -07008473
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308474v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
8475#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
8476 const v_U8_t *pIes,
8477#else
8478 v_U8_t *pIes,
8479#endif
8480 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008481{
8482 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308483 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07008484 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308485
Jeff Johnson295189b2012-06-20 16:38:30 -07008486 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308487 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008488 elem_id = ptr[0];
8489 elem_len = ptr[1];
8490 left -= 2;
8491 if(elem_len > left)
8492 {
8493 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008494 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008495 eid,elem_len,left);
8496 return NULL;
8497 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308498 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008499 {
8500 return ptr;
8501 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308502
Jeff Johnson295189b2012-06-20 16:38:30 -07008503 left -= elem_len;
8504 ptr += (elem_len + 2);
8505 }
8506 return NULL;
8507}
8508
Jeff Johnson295189b2012-06-20 16:38:30 -07008509/* Check if rate is 11g rate or not */
8510static int wlan_hdd_rate_is_11g(u8 rate)
8511{
Sanjay Devnani28322e22013-06-21 16:13:40 -07008512 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008513 u8 i;
8514 for (i = 0; i < 8; i++)
8515 {
8516 if(rate == gRateArray[i])
8517 return TRUE;
8518 }
8519 return FALSE;
8520}
8521
8522/* Check for 11g rate and set proper 11g only mode */
8523static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
8524 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
8525{
8526 u8 i, num_rates = pIe[0];
8527
8528 pIe += 1;
8529 for ( i = 0; i < num_rates; i++)
8530 {
8531 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
8532 {
8533 /* If rate set have 11g rate than change the mode to 11G */
8534 *pSapHw_mode = eSAP_DOT11_MODE_11g;
8535 if (pIe[i] & BASIC_RATE_MASK)
8536 {
8537 /* If we have 11g rate as basic rate, it means mode
8538 is 11g only mode.
8539 */
8540 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
8541 *pCheckRatesfor11g = FALSE;
8542 }
8543 }
8544 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
8545 {
8546 *require_ht = TRUE;
8547 }
8548 }
8549 return;
8550}
8551
8552static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
8553{
8554 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8555 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8556 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8557 u8 checkRatesfor11g = TRUE;
8558 u8 require_ht = FALSE;
8559 u8 *pIe=NULL;
8560
8561 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
8562
8563 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
8564 pBeacon->head_len, WLAN_EID_SUPP_RATES);
8565 if (pIe != NULL)
8566 {
8567 pIe += 1;
8568 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8569 &pConfig->SapHw_mode);
8570 }
8571
8572 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8573 WLAN_EID_EXT_SUPP_RATES);
8574 if (pIe != NULL)
8575 {
8576
8577 pIe += 1;
8578 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8579 &pConfig->SapHw_mode);
8580 }
8581
8582 if( pConfig->channel > 14 )
8583 {
8584 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
8585 }
8586
8587 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8588 WLAN_EID_HT_CAPABILITY);
8589
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308590 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008591 {
8592 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
8593 if(require_ht)
8594 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
8595 }
8596}
8597
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308598static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
8599 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
8600{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008601 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308602 v_U8_t *pIe = NULL;
8603 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8604
8605 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
8606 pBeacon->tail, pBeacon->tail_len);
8607
8608 if (pIe)
8609 {
8610 ielen = pIe[1] + 2;
8611 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8612 {
8613 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
8614 }
8615 else
8616 {
8617 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
8618 return -EINVAL;
8619 }
8620 *total_ielen += ielen;
8621 }
8622 return 0;
8623}
8624
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008625static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
8626 v_U8_t *genie, v_U8_t *total_ielen)
8627{
8628 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8629 int left = pBeacon->tail_len;
8630 v_U8_t *ptr = pBeacon->tail;
8631 v_U8_t elem_id, elem_len;
8632 v_U16_t ielen = 0;
8633
8634 if ( NULL == ptr || 0 == left )
8635 return;
8636
8637 while (left >= 2)
8638 {
8639 elem_id = ptr[0];
8640 elem_len = ptr[1];
8641 left -= 2;
8642 if (elem_len > left)
8643 {
8644 hddLog( VOS_TRACE_LEVEL_ERROR,
8645 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
8646 elem_id, elem_len, left);
8647 return;
8648 }
8649 if (IE_EID_VENDOR == elem_id)
8650 {
8651 /* skipping the VSIE's which we don't want to include or
8652 * it will be included by existing code
8653 */
8654 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
8655#ifdef WLAN_FEATURE_WFD
8656 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
8657#endif
8658 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8659 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8660 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
8661 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8662 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
8663 {
8664 ielen = ptr[1] + 2;
8665 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8666 {
8667 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
8668 *total_ielen += ielen;
8669 }
8670 else
8671 {
8672 hddLog( VOS_TRACE_LEVEL_ERROR,
8673 "IE Length is too big "
8674 "IEs eid=%d elem_len=%d total_ie_lent=%d",
8675 elem_id, elem_len, *total_ielen);
8676 }
8677 }
8678 }
8679
8680 left -= elem_len;
8681 ptr += (elem_len + 2);
8682 }
8683 return;
8684}
8685
Kapil Gupta137ef892016-12-13 19:38:00 +05308686int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008687{
8688 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308689 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008690 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07008691 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05308692 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008693
8694 genie = vos_mem_malloc(MAX_GENIE_LEN);
8695
8696 if(genie == NULL) {
8697
8698 return -ENOMEM;
8699 }
8700
Kapil Gupta137ef892016-12-13 19:38:00 +05308701 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308702 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8703 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008704 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308705 hddLog(LOGE,
8706 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308707 ret = -EINVAL;
8708 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008709 }
8710
8711#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308712 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8713 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
8714 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308715 hddLog(LOGE,
8716 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308717 ret = -EINVAL;
8718 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008719 }
8720#endif
8721
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308722 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8723 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008724 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308725 hddLog(LOGE,
8726 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308727 ret = -EINVAL;
8728 goto done;
8729 }
8730
8731 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
8732 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008733 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07008734 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008735
8736 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8737 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
8738 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
8739 {
8740 hddLog(LOGE,
8741 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008742 ret = -EINVAL;
8743 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008744 }
8745
8746 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8747 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
8748 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8749 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8750 ==eHAL_STATUS_FAILURE)
8751 {
8752 hddLog(LOGE,
8753 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008754 ret = -EINVAL;
8755 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008756 }
8757
8758 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05308759 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008760 {
Kapil Gupta137ef892016-12-13 19:38:00 +05308761 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07008762 u8 probe_rsp_ie_len[3] = {0};
8763 u8 counter = 0;
8764 /* Check Probe Resp Length if it is greater then 255 then Store
8765 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
8766 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
8767 Store More then 255 bytes into One Variable.
8768 */
8769 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
8770 {
8771 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
8772 {
8773 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
8774 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
8775 }
8776 else
8777 {
8778 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
8779 rem_probe_resp_ie_len = 0;
8780 }
8781 }
8782
8783 rem_probe_resp_ie_len = 0;
8784
8785 if (probe_rsp_ie_len[0] > 0)
8786 {
8787 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8788 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05308789 (tANI_U8*)&pBeacon->
8790 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07008791 probe_rsp_ie_len[0], NULL,
8792 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8793 {
8794 hddLog(LOGE,
8795 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008796 ret = -EINVAL;
8797 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008798 }
8799 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
8800 }
8801
8802 if (probe_rsp_ie_len[1] > 0)
8803 {
8804 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8805 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +05308806 (tANI_U8*)&pBeacon->
8807 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07008808 probe_rsp_ie_len[1], NULL,
8809 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8810 {
8811 hddLog(LOGE,
8812 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008813 ret = -EINVAL;
8814 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008815 }
8816 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
8817 }
8818
8819 if (probe_rsp_ie_len[2] > 0)
8820 {
8821 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8822 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +05308823 (tANI_U8*)&pBeacon->
8824 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07008825 probe_rsp_ie_len[2], NULL,
8826 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8827 {
8828 hddLog(LOGE,
8829 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008830 ret = -EINVAL;
8831 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008832 }
8833 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
8834 }
8835
8836 if (probe_rsp_ie_len[1] == 0 )
8837 {
8838 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8839 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8840 eANI_BOOLEAN_FALSE) )
8841 {
8842 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008843 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008844 }
8845 }
8846
8847 if (probe_rsp_ie_len[2] == 0 )
8848 {
8849 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8850 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8851 eANI_BOOLEAN_FALSE) )
8852 {
8853 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008854 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008855 }
8856 }
8857
8858 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8859 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
8860 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8861 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8862 == eHAL_STATUS_FAILURE)
8863 {
8864 hddLog(LOGE,
8865 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008866 ret = -EINVAL;
8867 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008868 }
8869 }
8870 else
8871 {
8872 // Reset WNI_CFG_PROBE_RSP Flags
8873 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
8874
8875 hddLog(VOS_TRACE_LEVEL_INFO,
8876 "%s: No Probe Response IE received in set beacon",
8877 __func__);
8878 }
8879
8880 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05308881 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008882 {
8883 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05308884 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
8885 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07008886 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8887 {
8888 hddLog(LOGE,
8889 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008890 ret = -EINVAL;
8891 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008892 }
8893
8894 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8895 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
8896 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8897 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8898 == eHAL_STATUS_FAILURE)
8899 {
8900 hddLog(LOGE,
8901 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008902 ret = -EINVAL;
8903 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008904 }
8905 }
8906 else
8907 {
8908 hddLog(VOS_TRACE_LEVEL_INFO,
8909 "%s: No Assoc Response IE received in set beacon",
8910 __func__);
8911
8912 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8913 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8914 eANI_BOOLEAN_FALSE) )
8915 {
8916 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008917 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008918 }
8919 }
8920
Jeff Johnsone7245742012-09-05 17:12:55 -07008921done:
Jeff Johnson295189b2012-06-20 16:38:30 -07008922 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308923 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008924}
Jeff Johnson295189b2012-06-20 16:38:30 -07008925
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308926/*
Jeff Johnson295189b2012-06-20 16:38:30 -07008927 * FUNCTION: wlan_hdd_validate_operation_channel
8928 * called by wlan_hdd_cfg80211_start_bss() and
8929 * wlan_hdd_cfg80211_set_channel()
8930 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308931 * channel list.
8932 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07008933VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008934{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308935
Jeff Johnson295189b2012-06-20 16:38:30 -07008936 v_U32_t num_ch = 0;
8937 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8938 u32 indx = 0;
8939 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308940 v_U8_t fValidChannel = FALSE, count = 0;
8941 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308942
Jeff Johnson295189b2012-06-20 16:38:30 -07008943 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8944
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308945 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008946 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308947 /* Validate the channel */
8948 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008949 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308950 if ( channel == rfChannels[count].channelNum )
8951 {
8952 fValidChannel = TRUE;
8953 break;
8954 }
8955 }
8956 if (fValidChannel != TRUE)
8957 {
8958 hddLog(VOS_TRACE_LEVEL_ERROR,
8959 "%s: Invalid Channel [%d]", __func__, channel);
8960 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008961 }
8962 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308963 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008964 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308965 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8966 valid_ch, &num_ch))
8967 {
8968 hddLog(VOS_TRACE_LEVEL_ERROR,
8969 "%s: failed to get valid channel list", __func__);
8970 return VOS_STATUS_E_FAILURE;
8971 }
8972 for (indx = 0; indx < num_ch; indx++)
8973 {
8974 if (channel == valid_ch[indx])
8975 {
8976 break;
8977 }
8978 }
8979
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308980 if (indx >= num_ch)
8981 {
8982 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
8983 {
8984 eCsrBand band;
8985 unsigned int freq;
8986
8987 sme_GetFreqBand(hHal, &band);
8988
8989 if (eCSR_BAND_5G == band)
8990 {
8991#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8992 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8993 {
8994 freq = ieee80211_channel_to_frequency(channel,
8995 IEEE80211_BAND_2GHZ);
8996 }
8997 else
8998 {
8999 freq = ieee80211_channel_to_frequency(channel,
9000 IEEE80211_BAND_5GHZ);
9001 }
9002#else
9003 freq = ieee80211_channel_to_frequency(channel);
9004#endif
9005 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
9006 return VOS_STATUS_SUCCESS;
9007 }
9008 }
9009
9010 hddLog(VOS_TRACE_LEVEL_ERROR,
9011 "%s: Invalid Channel [%d]", __func__, channel);
9012 return VOS_STATUS_E_FAILURE;
9013 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009014 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309015
Jeff Johnson295189b2012-06-20 16:38:30 -07009016 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309017
Jeff Johnson295189b2012-06-20 16:38:30 -07009018}
9019
Viral Modi3a32cc52013-02-08 11:14:52 -08009020/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309021 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009022 * This function is used to set the channel number
9023 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309024static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009025 struct ieee80211_channel *chan,
9026 enum nl80211_channel_type channel_type
9027 )
9028{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309029 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08009030 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07009031 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08009032 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309033 hdd_context_t *pHddCtx;
9034 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009035
9036 ENTER();
9037
9038 if( NULL == dev )
9039 {
9040 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009041 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009042 return -ENODEV;
9043 }
9044 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309045
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309046 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9047 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
9048 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08009049 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309050 "%s: device_mode = %s (%d) freq = %d", __func__,
9051 hdd_device_modetoString(pAdapter->device_mode),
9052 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309053
9054 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9055 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309056 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08009057 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309058 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009059 }
9060
9061 /*
9062 * Do freq to chan conversion
9063 * TODO: for 11a
9064 */
9065
9066 channel = ieee80211_frequency_to_channel(freq);
9067
9068 /* Check freq range */
9069 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
9070 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
9071 {
9072 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009073 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08009074 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
9075 WNI_CFG_CURRENT_CHANNEL_STAMAX);
9076 return -EINVAL;
9077 }
9078
9079 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9080
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05309081 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
9082 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08009083 {
9084 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
9085 {
9086 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009087 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08009088 return -EINVAL;
9089 }
9090 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9091 "%s: set channel to [%d] for device mode =%d",
9092 __func__, channel,pAdapter->device_mode);
9093 }
9094 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009095 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009096 )
9097 {
9098 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9099 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9100 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9101
9102 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9103 {
9104 /* Link is up then return cant set channel*/
9105 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009106 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009107 return -EINVAL;
9108 }
9109
9110 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9111 pHddStaCtx->conn_info.operationChannel = channel;
9112 pRoamProfile->ChannelInfo.ChannelList =
9113 &pHddStaCtx->conn_info.operationChannel;
9114 }
9115 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009116 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009117 )
9118 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309119 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9120 {
9121 if(VOS_STATUS_SUCCESS !=
9122 wlan_hdd_validate_operation_channel(pAdapter,channel))
9123 {
9124 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009125 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309126 return -EINVAL;
9127 }
9128 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9129 }
9130 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009131 {
9132 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9133
9134 /* If auto channel selection is configured as enable/ 1 then ignore
9135 channel set by supplicant
9136 */
9137 if ( cfg_param->apAutoChannelSelection )
9138 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309139 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9140 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009141 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309142 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9143 __func__, hdd_device_modetoString(pAdapter->device_mode),
9144 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009145 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309146 else
9147 {
9148 if(VOS_STATUS_SUCCESS !=
9149 wlan_hdd_validate_operation_channel(pAdapter,channel))
9150 {
9151 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009152 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309153 return -EINVAL;
9154 }
9155 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9156 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009157 }
9158 }
9159 else
9160 {
9161 hddLog(VOS_TRACE_LEVEL_FATAL,
9162 "%s: Invalid device mode failed to set valid channel", __func__);
9163 return -EINVAL;
9164 }
9165 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309166 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009167}
9168
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309169static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9170 struct net_device *dev,
9171 struct ieee80211_channel *chan,
9172 enum nl80211_channel_type channel_type
9173 )
9174{
9175 int ret;
9176
9177 vos_ssr_protect(__func__);
9178 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9179 vos_ssr_unprotect(__func__);
9180
9181 return ret;
9182}
9183
Anurag Chouhan83026002016-12-13 22:46:21 +05309184#ifdef DHCP_SERVER_OFFLOAD
9185void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
9186 VOS_STATUS status)
9187{
9188 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
9189
9190 ENTER();
9191
9192 if (NULL == adapter)
9193 {
9194 hddLog(VOS_TRACE_LEVEL_ERROR,
9195 "%s: adapter is NULL",__func__);
9196 return;
9197 }
9198
9199 adapter->dhcp_status.dhcp_offload_status = status;
9200 vos_event_set(&adapter->dhcp_status.vos_event);
9201 return;
9202}
9203
9204/**
9205 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
9206 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309207 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +05309208 *
9209 * Return: None
9210 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309211VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
9212 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +05309213{
9214 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
9215 sir_dhcp_srv_offload_info dhcp_srv_info;
9216 tANI_U8 num_entries = 0;
9217 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
9218 tANI_U8 num;
9219 tANI_U32 temp;
9220 VOS_STATUS ret;
9221
9222 ENTER();
9223
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309224 if (!re_init) {
9225 ret = wlan_hdd_validate_context(hdd_ctx);
9226 if (0 != ret)
9227 return VOS_STATUS_E_INVAL;
9228 }
Anurag Chouhan83026002016-12-13 22:46:21 +05309229
9230 /* Prepare the request to send to SME */
9231 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
9232 if (NULL == dhcp_srv_info) {
9233 hddLog(VOS_TRACE_LEVEL_ERROR,
9234 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
9235 return VOS_STATUS_E_NOMEM;
9236 }
9237
9238 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
9239
9240 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
9241 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
9242 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
9243 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
9244 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
9245 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
9246
9247 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
9248 srv_ip,
9249 &num_entries,
Anurag Chouhanac145c22016-11-22 16:51:47 +05309250 IPADDR_NUM_ENTRIES, ".");
Anurag Chouhan83026002016-12-13 22:46:21 +05309251 if (num_entries != IPADDR_NUM_ENTRIES) {
9252 hddLog(VOS_TRACE_LEVEL_ERROR,
9253 "%s: incorrect IP address (%s) assigned for DHCP server!",
9254 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9255 vos_mem_free(dhcp_srv_info);
9256 return VOS_STATUS_E_FAILURE;
9257 }
9258
9259 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
9260 hddLog(VOS_TRACE_LEVEL_ERROR,
9261 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
9262 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9263 vos_mem_free(dhcp_srv_info);
9264 return VOS_STATUS_E_FAILURE;
9265 }
9266
9267 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
9268 hddLog(VOS_TRACE_LEVEL_ERROR,
9269 "%s: invalid IP address (%s)! The last field must be less than 100!",
9270 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
9271 vos_mem_free(dhcp_srv_info);
9272 return VOS_STATUS_E_FAILURE;
9273 }
9274
9275 for (num = 0; num < num_entries; num++) {
9276 temp = srv_ip[num];
9277 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
9278 }
9279
9280 if (eHAL_STATUS_SUCCESS !=
9281 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
9282 hddLog(VOS_TRACE_LEVEL_ERROR,
9283 "%s: sme_set_dhcp_srv_offload fail!", __func__);
9284 vos_mem_free(dhcp_srv_info);
9285 return VOS_STATUS_E_FAILURE;
9286 }
9287
9288 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9289 "%s: enable DHCP Server offload successfully!", __func__);
9290
9291 vos_mem_free(dhcp_srv_info);
9292 return 0;
9293}
9294#endif /* DHCP_SERVER_OFFLOAD */
9295
Jeff Johnson295189b2012-06-20 16:38:30 -07009296#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9297static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9298 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009299#else
9300static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9301 struct cfg80211_beacon_data *params,
9302 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309303 enum nl80211_hidden_ssid hidden_ssid,
9304 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009305#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009306{
9307 tsap_Config_t *pConfig;
9308 beacon_data_t *pBeacon = NULL;
9309 struct ieee80211_mgmt *pMgmt_frame;
9310 v_U8_t *pIe=NULL;
9311 v_U16_t capab_info;
9312 eCsrAuthType RSNAuthType;
9313 eCsrEncryptionType RSNEncryptType;
9314 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309315 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009316 tpWLAN_SAPEventCB pSapEventCallback;
9317 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -07009318 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309319 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009320 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309321 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009322 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009323 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309324 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009325 v_BOOL_t MFPCapable = VOS_FALSE;
9326 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309327 v_BOOL_t sapEnable11AC =
9328 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +05309329 u_int16_t prev_rsn_length = 0;
9330
Jeff Johnson295189b2012-06-20 16:38:30 -07009331 ENTER();
9332
Nitesh Shah9b066282017-06-06 18:05:52 +05309333 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309334 iniConfig = pHddCtx->cfg_ini;
9335
Jeff Johnson295189b2012-06-20 16:38:30 -07009336 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9337
9338 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9339
9340 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9341
9342 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9343
9344 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9345
9346 //channel is already set in the set_channel Call back
9347 //pConfig->channel = pCommitConfig->channel;
9348
9349 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309350 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009351 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9352
9353 pConfig->dtim_period = pBeacon->dtim_period;
9354
Arif Hussain6d2a3322013-11-17 19:50:10 -08009355 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009356 pConfig->dtim_period);
9357
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009358 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009359 {
9360 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009361 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309362 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9363 {
9364 tANI_BOOLEAN restartNeeded;
9365 pConfig->ieee80211d = 1;
9366 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9367 sme_setRegInfo(hHal, pConfig->countryCode);
9368 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9369 }
9370 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009371 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009372 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009373 pConfig->ieee80211d = 1;
9374 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9375 sme_setRegInfo(hHal, pConfig->countryCode);
9376 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009377 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009378 else
9379 {
9380 pConfig->ieee80211d = 0;
9381 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309382 /*
9383 * If auto channel is configured i.e. channel is 0,
9384 * so skip channel validation.
9385 */
9386 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9387 {
9388 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9389 {
9390 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009391 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309392 return -EINVAL;
9393 }
9394 }
9395 else
9396 {
9397 if(1 != pHddCtx->is_dynamic_channel_range_set)
9398 {
9399 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9400 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9401 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9402 }
9403 pHddCtx->is_dynamic_channel_range_set = 0;
9404 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009405 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009406 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009407 {
9408 pConfig->ieee80211d = 0;
9409 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309410
9411#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9412 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9413 pConfig->authType = eSAP_OPEN_SYSTEM;
9414 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9415 pConfig->authType = eSAP_SHARED_KEY;
9416 else
9417 pConfig->authType = eSAP_AUTO_SWITCH;
9418#else
9419 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9420 pConfig->authType = eSAP_OPEN_SYSTEM;
9421 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9422 pConfig->authType = eSAP_SHARED_KEY;
9423 else
9424 pConfig->authType = eSAP_AUTO_SWITCH;
9425#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009426
9427 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309428
9429 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009430 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +05309431#ifdef SAP_AUTH_OFFLOAD
9432 /* In case of sap offload, hostapd.conf is configuted with open mode and
9433 * security is configured from ini file. Due to open mode in hostapd.conf
9434 * privacy bit is set to false which will result in not sending,
9435 * data packets as encrypted.
9436 * If enable_sap_auth_offload is enabled in ini and
9437 * sap_auth_offload_sec_type is type of WPA2-PSK,
9438 * driver will set privacy bit to 1.
9439 */
9440 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
9441 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
9442 pConfig->privacy = VOS_TRUE;
9443#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009444
9445 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9446
9447 /*Set wps station to configured*/
9448 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9449
9450 if(pIe)
9451 {
9452 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
9453 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009454 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07009455 return -EINVAL;
9456 }
9457 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
9458 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009459 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07009460 /* Check 15 bit of WPS IE as it contain information for wps state
9461 * WPS state
9462 */
9463 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
9464 {
9465 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
9466 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
9467 {
9468 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
9469 }
9470 }
9471 }
9472 else
9473 {
9474 pConfig->wps_state = SAP_WPS_DISABLED;
9475 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309476 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07009477
c_hpothufe599e92014-06-16 11:38:55 +05309478 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9479 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9480 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
9481 eCSR_ENCRYPT_TYPE_NONE;
9482
Jeff Johnson295189b2012-06-20 16:38:30 -07009483 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309484 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309485 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009486 WLAN_EID_RSN);
9487 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309488 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009489 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +05309490 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
9491 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
9492 pConfig->RSNWPAReqIELength);
9493 else
9494 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
9495 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309496 /* The actual processing may eventually be more extensive than
9497 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07009498 * by the app.
9499 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309500 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009501 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9502 &RSNEncryptType,
9503 &mcRSNEncryptType,
9504 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009505 &MFPCapable,
9506 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +05309507 pConfig->RSNWPAReqIE[1]+2,
9508 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009509
9510 if( VOS_STATUS_SUCCESS == status )
9511 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309512 /* Now copy over all the security attributes you have
9513 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009514 * */
9515 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9516 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9517 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9518 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309519 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009520 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009521 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9522 }
9523 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309524
Jeff Johnson295189b2012-06-20 16:38:30 -07009525 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9526 pBeacon->tail, pBeacon->tail_len);
9527
9528 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
9529 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309530 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07009531 {
9532 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +05309533 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -07009534 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +05309535 if (pConfig->RSNWPAReqIELength <=
9536 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
9537 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
9538 pIe[1] + 2);
9539 else
9540 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
9541 pConfig->RSNWPAReqIELength);
9542
Jeff Johnson295189b2012-06-20 16:38:30 -07009543 }
9544 else
9545 {
9546 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +05309547 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
9548 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
9549 pConfig->RSNWPAReqIELength);
9550 else
9551 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
9552 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309553 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009554 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9555 &RSNEncryptType,
9556 &mcRSNEncryptType,
9557 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009558 &MFPCapable,
9559 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +05309560 pConfig->RSNWPAReqIE[1]+2,
9561 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009562
9563 if( VOS_STATUS_SUCCESS == status )
9564 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309565 /* Now copy over all the security attributes you have
9566 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009567 * */
9568 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9569 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9570 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9571 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309572 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009573 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009574 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9575 }
9576 }
9577 }
9578
Kapil Gupta137ef892016-12-13 19:38:00 +05309579 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -07009580 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
9581 return -EINVAL;
9582 }
9583
Jeff Johnson295189b2012-06-20 16:38:30 -07009584 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
9585
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009586#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009587 if (params->ssid != NULL)
9588 {
9589 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
9590 pConfig->SSIDinfo.ssid.length = params->ssid_len;
9591 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9592 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9593 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009594#else
9595 if (ssid != NULL)
9596 {
9597 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
9598 pConfig->SSIDinfo.ssid.length = ssid_len;
9599 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9600 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9601 }
9602#endif
9603
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309604 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07009605 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309606
Jeff Johnson295189b2012-06-20 16:38:30 -07009607 /* default value */
9608 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9609 pConfig->num_accept_mac = 0;
9610 pConfig->num_deny_mac = 0;
9611
9612 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9613 pBeacon->tail, pBeacon->tail_len);
9614
9615 /* pIe for black list is following form:
9616 type : 1 byte
9617 length : 1 byte
9618 OUI : 4 bytes
9619 acl type : 1 byte
9620 no of mac addr in black list: 1 byte
9621 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309622 */
9623 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009624 {
9625 pConfig->SapMacaddr_acl = pIe[6];
9626 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009627 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009628 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309629 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
9630 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009631 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9632 for (i = 0; i < pConfig->num_deny_mac; i++)
9633 {
9634 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9635 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309636 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009637 }
9638 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9639 pBeacon->tail, pBeacon->tail_len);
9640
9641 /* pIe for white list is following form:
9642 type : 1 byte
9643 length : 1 byte
9644 OUI : 4 bytes
9645 acl type : 1 byte
9646 no of mac addr in white list: 1 byte
9647 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309648 */
9649 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009650 {
9651 pConfig->SapMacaddr_acl = pIe[6];
9652 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009653 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009654 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309655 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
9656 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009657 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9658 for (i = 0; i < pConfig->num_accept_mac; i++)
9659 {
9660 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9661 acl_entry++;
9662 }
9663 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309664
Jeff Johnson295189b2012-06-20 16:38:30 -07009665 wlan_hdd_set_sapHwmode(pHostapdAdapter);
9666
Jeff Johnsone7245742012-09-05 17:12:55 -07009667#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009668 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309669 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
9670 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05309671 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
9672 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009673 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
9674 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309675 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
9676 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07009677 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309678 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07009679 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309680 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009681
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309682 /* If ACS disable and selected channel <= 14
9683 * OR
9684 * ACS enabled and ACS operating band is choosen as 2.4
9685 * AND
9686 * VHT in 2.4G Disabled
9687 * THEN
9688 * Fallback to 11N mode
9689 */
9690 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
9691 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05309692 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309693 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009694 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309695 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
9696 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009697 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
9698 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009699 }
9700#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309701
Jeff Johnson295189b2012-06-20 16:38:30 -07009702 // ht_capab is not what the name conveys,this is used for protection bitmap
9703 pConfig->ht_capab =
9704 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
9705
Kapil Gupta137ef892016-12-13 19:38:00 +05309706 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07009707 {
9708 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9709 return -EINVAL;
9710 }
9711
9712 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309713 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07009714 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
9715 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309716 pConfig->obssProtEnabled =
9717 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07009718
Chet Lanctot8cecea22014-02-11 19:09:36 -08009719#ifdef WLAN_FEATURE_11W
9720 pConfig->mfpCapable = MFPCapable;
9721 pConfig->mfpRequired = MFPRequired;
9722 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
9723 pConfig->mfpCapable, pConfig->mfpRequired);
9724#endif
9725
Arif Hussain6d2a3322013-11-17 19:50:10 -08009726 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07009727 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009728 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
9729 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
9730 (int)pConfig->channel);
9731 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
9732 pConfig->SapHw_mode, pConfig->privacy,
9733 pConfig->authType);
9734 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
9735 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
9736 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
9737 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07009738
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309739 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009740 {
9741 //Bss already started. just return.
9742 //TODO Probably it should update some beacon params.
9743 hddLog( LOGE, "Bss Already started...Ignore the request");
9744 EXIT();
9745 return 0;
9746 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309747
Agarwal Ashish51325b52014-06-16 16:50:49 +05309748 if (vos_max_concurrent_connections_reached()) {
9749 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9750 return -EINVAL;
9751 }
9752
Jeff Johnson295189b2012-06-20 16:38:30 -07009753 pConfig->persona = pHostapdAdapter->device_mode;
9754
Peng Xu2446a892014-09-05 17:21:18 +05309755 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
9756 if ( NULL != psmeConfig)
9757 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309758 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05309759 sme_GetConfigParam(hHal, psmeConfig);
9760 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309761#ifdef WLAN_FEATURE_AP_HT40_24G
9762 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
9763 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
9764 && pHddCtx->cfg_ini->apHT40_24GEnabled)
9765 {
9766 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
9767 sme_UpdateConfig (hHal, psmeConfig);
9768 }
9769#endif
Peng Xu2446a892014-09-05 17:21:18 +05309770 vos_mem_free(psmeConfig);
9771 }
Peng Xuafc34e32014-09-25 13:23:55 +05309772 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05309773
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309774 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
9775
Jeff Johnson295189b2012-06-20 16:38:30 -07009776 pSapEventCallback = hdd_hostapd_SAPEventCB;
9777 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
9778 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
9779 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009780 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309781 ret = -EINVAL;
9782 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -07009783 }
9784
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309785 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07009786 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
9787
9788 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309789
Jeff Johnson295189b2012-06-20 16:38:30 -07009790 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309791 {
9792 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009793 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07009794 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009795 VOS_ASSERT(0);
9796 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309797
Jeff Johnson295189b2012-06-20 16:38:30 -07009798 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +05309799 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
9800 VOS_STATUS_SUCCESS)
9801 {
9802 hddLog(LOGE,FL("Fail to get Softap sessionID"));
9803 VOS_ASSERT(0);
9804 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +05309805 /* Initialize WMM configuation */
9806 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309807 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009808
Anurag Chouhan83026002016-12-13 22:46:21 +05309809#ifdef DHCP_SERVER_OFFLOAD
9810 /* set dhcp server offload */
9811 if (iniConfig->enable_dhcp_srv_offload &&
9812 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05309813 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +05309814 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +05309815 if (!VOS_IS_STATUS_SUCCESS(status))
9816 {
9817 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9818 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05309819 vos_event_reset(&pHostapdState->vosEvent);
9820 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
9821 status = vos_wait_single_event(&pHostapdState->vosEvent,
9822 10000);
9823 if (!VOS_IS_STATUS_SUCCESS(status)) {
9824 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309825 ret = -EINVAL;
9826 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05309827 }
9828 }
Anurag Chouhan83026002016-12-13 22:46:21 +05309829 }
Anurag Chouhan83026002016-12-13 22:46:21 +05309830 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
9831 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
9832 {
9833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9834 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
9835 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05309836 vos_event_reset(&pHostapdState->vosEvent);
9837 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
9838 status = vos_wait_single_event(&pHostapdState->vosEvent,
9839 10000);
9840 if (!VOS_IS_STATUS_SUCCESS(status)) {
9841 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309842 ret = -EINVAL;
9843 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05309844 }
9845 }
Anurag Chouhan83026002016-12-13 22:46:21 +05309846 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +05309847#ifdef MDNS_OFFLOAD
9848 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05309849 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +05309850 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
9851 if (VOS_IS_STATUS_SUCCESS(status))
9852 {
9853 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9854 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05309855 vos_event_reset(&pHostapdState->vosEvent);
9856 if (VOS_STATUS_SUCCESS ==
9857 WLANSAP_StopBss(pHddCtx->pvosContext)) {
9858 status = vos_wait_single_event(&pHostapdState->vosEvent,
9859 10000);
9860 if (!VOS_IS_STATUS_SUCCESS(status)) {
9861 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309862 ret = -EINVAL;
9863 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05309864 }
9865 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +05309866 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +05309867 status = vos_wait_single_event(&pHostapdAdapter->
9868 mdns_status.vos_event, 2000);
9869 if (!VOS_IS_STATUS_SUCCESS(status) ||
9870 pHostapdAdapter->mdns_status.mdns_enable_status ||
9871 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
9872 pHostapdAdapter->mdns_status.mdns_resp_status)
9873 {
9874 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9875 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
9876 pHostapdAdapter->mdns_status.mdns_enable_status,
9877 pHostapdAdapter->mdns_status.mdns_fqdn_status,
9878 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05309879 vos_event_reset(&pHostapdState->vosEvent);
9880 if (VOS_STATUS_SUCCESS ==
9881 WLANSAP_StopBss(pHddCtx->pvosContext)) {
9882 status = vos_wait_single_event(&pHostapdState->vosEvent,
9883 10000);
9884 if (!VOS_IS_STATUS_SUCCESS(status)) {
9885 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309886 ret = -EINVAL;
9887 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05309888 }
9889 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +05309890 }
9891 }
9892#endif /* MDNS_OFFLOAD */
9893 } else {
9894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9895 ("DHCP Disabled ini %d, FW %d"),
9896 iniConfig->enable_dhcp_srv_offload,
9897 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +05309898 }
9899#endif /* DHCP_SERVER_OFFLOAD */
9900
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009901#ifdef WLAN_FEATURE_P2P_DEBUG
9902 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
9903 {
9904 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
9905 {
9906 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9907 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009908 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009909 }
9910 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
9911 {
9912 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9913 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009914 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009915 }
9916 }
9917#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +05309918 /* Check and restart SAP if it is on Unsafe channel */
9919 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009920
Jeff Johnson295189b2012-06-20 16:38:30 -07009921 pHostapdState->bCommit = TRUE;
9922 EXIT();
9923
9924 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +05309925error:
9926 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
9927 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009928}
9929
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009930#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309931static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309932 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009933 struct beacon_parameters *params)
9934{
9935 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309936 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309937 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009938
9939 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309940
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309941 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9942 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
9943 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309944 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
9945 hdd_device_modetoString(pAdapter->device_mode),
9946 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009947
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309948 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9949 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309950 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009951 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309952 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009953 }
9954
Agarwal Ashish51325b52014-06-16 16:50:49 +05309955 if (vos_max_concurrent_connections_reached()) {
9956 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9957 return -EINVAL;
9958 }
9959
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309960 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009961 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009962 )
9963 {
9964 beacon_data_t *old,*new;
9965
9966 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309967
Jeff Johnson295189b2012-06-20 16:38:30 -07009968 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309969 {
9970 hddLog(VOS_TRACE_LEVEL_WARN,
9971 FL("already beacon info added to session(%d)"),
9972 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009973 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309974 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009975
9976 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9977
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309978 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07009979 {
9980 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009981 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009982 return -EINVAL;
9983 }
9984
9985 pAdapter->sessionCtx.ap.beacon = new;
9986
9987 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9988 }
9989
9990 EXIT();
9991 return status;
9992}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309993
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309994static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
9995 struct net_device *dev,
9996 struct beacon_parameters *params)
9997{
9998 int ret;
9999
10000 vos_ssr_protect(__func__);
10001 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
10002 vos_ssr_unprotect(__func__);
10003
10004 return ret;
10005}
10006
10007static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010008 struct net_device *dev,
10009 struct beacon_parameters *params)
10010{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010011 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010012 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10013 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010014 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010015
10016 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010017
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010018 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10019 TRACE_CODE_HDD_CFG80211_SET_BEACON,
10020 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
10021 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10022 __func__, hdd_device_modetoString(pAdapter->device_mode),
10023 pAdapter->device_mode);
10024
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010025 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10026 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010027 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010028 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010029 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010030 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010031
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010032 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010033 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010034 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010035 {
10036 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010037
Jeff Johnson295189b2012-06-20 16:38:30 -070010038 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010039
Jeff Johnson295189b2012-06-20 16:38:30 -070010040 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010041 {
10042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10043 FL("session(%d) old and new heads points to NULL"),
10044 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010045 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010046 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010047
10048 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
10049
10050 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010051 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010052 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010053 return -EINVAL;
10054 }
10055
10056 pAdapter->sessionCtx.ap.beacon = new;
10057
10058 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
10059 }
10060
10061 EXIT();
10062 return status;
10063}
10064
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010065static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
10066 struct net_device *dev,
10067 struct beacon_parameters *params)
10068{
10069 int ret;
10070
10071 vos_ssr_protect(__func__);
10072 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
10073 vos_ssr_unprotect(__func__);
10074
10075 return ret;
10076}
10077
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010078#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10079
10080#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010081static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010082 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010083#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010084static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010085 struct net_device *dev)
10086#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010087{
10088 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070010089 hdd_context_t *pHddCtx = NULL;
10090 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010091 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010092 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010093
10094 ENTER();
10095
10096 if (NULL == pAdapter)
10097 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010099 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010100 return -ENODEV;
10101 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010102
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010103 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10104 TRACE_CODE_HDD_CFG80211_STOP_AP,
10105 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010106 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10107 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010108 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010109 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010110 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070010111 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010112
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010113 pScanInfo = &pHddCtx->scan_info;
10114
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010115 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10116 __func__, hdd_device_modetoString(pAdapter->device_mode),
10117 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010118
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010119 ret = wlan_hdd_scan_abort(pAdapter);
10120
Girish Gowli4bf7a632014-06-12 13:42:11 +053010121 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070010122 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10124 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010125
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010126 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070010127 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010128 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10129 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080010130
Jeff Johnsone7245742012-09-05 17:12:55 -070010131 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010132 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070010133 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010134 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010135 }
10136
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010137 /* Delete all associated STAs before stopping AP/P2P GO */
10138 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053010139 hdd_hostapd_stop(dev);
10140
Jeff Johnson295189b2012-06-20 16:38:30 -070010141 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010142 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010143 )
10144 {
10145 beacon_data_t *old;
10146
10147 old = pAdapter->sessionCtx.ap.beacon;
10148
10149 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010150 {
10151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10152 FL("session(%d) beacon data points to NULL"),
10153 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070010154 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010155 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010156
Jeff Johnson295189b2012-06-20 16:38:30 -070010157 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010158
10159 mutex_lock(&pHddCtx->sap_lock);
10160 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10161 {
Jeff Johnson4416a782013-03-25 14:17:50 -070010162 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010163 {
10164 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10165
10166 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10167
10168 if (!VOS_IS_STATUS_SUCCESS(status))
10169 {
10170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010171 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010172 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010173 }
10174 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010175 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010176 /* BSS stopped, clear the active sessions for this device mode */
10177 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010178 }
10179 mutex_unlock(&pHddCtx->sap_lock);
10180
10181 if(status != VOS_STATUS_SUCCESS)
10182 {
10183 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010184 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010185 return -EINVAL;
10186 }
10187
Jeff Johnson4416a782013-03-25 14:17:50 -070010188 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010189 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
10190 ==eHAL_STATUS_FAILURE)
10191 {
10192 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010193 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010194 }
10195
Jeff Johnson4416a782013-03-25 14:17:50 -070010196 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070010197 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10198 eANI_BOOLEAN_FALSE) )
10199 {
10200 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010201 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010202 }
10203
10204 // Reset WNI_CFG_PROBE_RSP Flags
10205 wlan_hdd_reset_prob_rspies(pAdapter);
10206
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010207 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
10208
Jeff Johnson295189b2012-06-20 16:38:30 -070010209 pAdapter->sessionCtx.ap.beacon = NULL;
10210 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010211#ifdef WLAN_FEATURE_P2P_DEBUG
10212 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
10213 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
10214 {
10215 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
10216 "GO got removed");
10217 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
10218 }
10219#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010220 }
10221 EXIT();
10222 return status;
10223}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010224
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010225#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10226static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
10227 struct net_device *dev)
10228{
10229 int ret;
10230
10231 vos_ssr_protect(__func__);
10232 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
10233 vos_ssr_unprotect(__func__);
10234
10235 return ret;
10236}
10237#else
10238static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
10239 struct net_device *dev)
10240{
10241 int ret;
10242
10243 vos_ssr_protect(__func__);
10244 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
10245 vos_ssr_unprotect(__func__);
10246
10247 return ret;
10248}
10249#endif
10250
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010251#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
10252
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010253static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010254 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010255 struct cfg80211_ap_settings *params)
10256{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010257 hdd_adapter_t *pAdapter;
10258 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010259 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010260
10261 ENTER();
10262
Girish Gowlib143d7a2015-02-18 19:39:55 +053010263 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010264 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053010266 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010267 return -ENODEV;
10268 }
10269
10270 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10271 if (NULL == pAdapter)
10272 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010273 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010274 "%s: HDD adapter is Null", __func__);
10275 return -ENODEV;
10276 }
10277
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010278 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10279 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
10280 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010281 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
10282 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010284 "%s: HDD adapter magic is invalid", __func__);
10285 return -ENODEV;
10286 }
10287
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010288 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
10289
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010290 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010291 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010292 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010293 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010294 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010295 }
10296
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010297 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
10298 __func__, hdd_device_modetoString(pAdapter->device_mode),
10299 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010300
10301 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010302 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010303 )
10304 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010305 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010306
10307 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010308
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010309 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010310 {
10311 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10312 FL("already beacon info added to session(%d)"),
10313 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010314 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010315 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010316
Girish Gowlib143d7a2015-02-18 19:39:55 +053010317#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10318 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10319 &new,
10320 &params->beacon);
10321#else
10322 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10323 &new,
10324 &params->beacon,
10325 params->dtim_period);
10326#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010327
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010328 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010329 {
10330 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010331 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010332 return -EINVAL;
10333 }
10334 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080010335#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070010336 wlan_hdd_cfg80211_set_channel(wiphy, dev,
10337#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
10338 params->channel, params->channel_type);
10339#else
10340 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10341#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010342#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010343 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010344 params->ssid_len, params->hidden_ssid,
10345 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010346 }
10347
10348 EXIT();
10349 return status;
10350}
10351
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010352static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10353 struct net_device *dev,
10354 struct cfg80211_ap_settings *params)
10355{
10356 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010357
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010358 vos_ssr_protect(__func__);
10359 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10360 vos_ssr_unprotect(__func__);
10361
10362 return ret;
10363}
10364
10365static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010366 struct net_device *dev,
10367 struct cfg80211_beacon_data *params)
10368{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010369 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010370 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010371 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010372
10373 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010374
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010375 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10376 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10377 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010378 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010379 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010380
10381 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10382 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010383 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010384 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010385 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010386 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010387
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010388 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010389 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010390 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010391 {
10392 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010393
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010394 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010395
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010396 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010397 {
10398 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10399 FL("session(%d) beacon data points to NULL"),
10400 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010401 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010402 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010403
10404 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10405
10406 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010407 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010408 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010409 return -EINVAL;
10410 }
10411
10412 pAdapter->sessionCtx.ap.beacon = new;
10413
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010414 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10415 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010416 }
10417
10418 EXIT();
10419 return status;
10420}
10421
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010422static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10423 struct net_device *dev,
10424 struct cfg80211_beacon_data *params)
10425{
10426 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010427
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010428 vos_ssr_protect(__func__);
10429 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10430 vos_ssr_unprotect(__func__);
10431
10432 return ret;
10433}
10434
10435#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010436
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010437static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010438 struct net_device *dev,
10439 struct bss_parameters *params)
10440{
10441 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010442 hdd_context_t *pHddCtx;
10443 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010444
10445 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010446
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010447 if (NULL == pAdapter)
10448 {
10449 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10450 "%s: HDD adapter is Null", __func__);
10451 return -ENODEV;
10452 }
10453 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010454 ret = wlan_hdd_validate_context(pHddCtx);
10455 if (0 != ret)
10456 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010457 return ret;
10458 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010459 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10460 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
10461 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010462 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10463 __func__, hdd_device_modetoString(pAdapter->device_mode),
10464 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010465
10466 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010467 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010468 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010469 {
10470 /* ap_isolate == -1 means that in change bss, upper layer doesn't
10471 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010472 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070010473 {
10474 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010475 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010476 }
10477
10478 EXIT();
10479 return 0;
10480}
10481
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010482static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
10483 struct net_device *dev,
10484 struct bss_parameters *params)
10485{
10486 int ret;
10487
10488 vos_ssr_protect(__func__);
10489 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
10490 vos_ssr_unprotect(__func__);
10491
10492 return ret;
10493}
Kiet Lam10841362013-11-01 11:36:50 +053010494/* FUNCTION: wlan_hdd_change_country_code_cd
10495* to wait for contry code completion
10496*/
10497void* wlan_hdd_change_country_code_cb(void *pAdapter)
10498{
10499 hdd_adapter_t *call_back_pAdapter = pAdapter;
10500 complete(&call_back_pAdapter->change_country_code);
10501 return NULL;
10502}
10503
Jeff Johnson295189b2012-06-20 16:38:30 -070010504/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010505 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070010506 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
10507 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010508int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010509 struct net_device *ndev,
10510 enum nl80211_iftype type,
10511 u32 *flags,
10512 struct vif_params *params
10513 )
10514{
10515 struct wireless_dev *wdev;
10516 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010517 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070010518 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010519 tCsrRoamProfile *pRoamProfile = NULL;
10520 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010521 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010522 eMib_dot11DesiredBssType connectedBssType;
10523 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010524 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010525
10526 ENTER();
10527
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010528 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010529 {
10530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10531 "%s: Adapter context is null", __func__);
10532 return VOS_STATUS_E_FAILURE;
10533 }
10534
10535 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10536 if (!pHddCtx)
10537 {
10538 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10539 "%s: HDD context is null", __func__);
10540 return VOS_STATUS_E_FAILURE;
10541 }
10542
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010543 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10544 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
10545 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010546 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010547 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010548 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010549 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010550 }
10551
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010552 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10553 __func__, hdd_device_modetoString(pAdapter->device_mode),
10554 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010555
Agarwal Ashish51325b52014-06-16 16:50:49 +053010556 if (vos_max_concurrent_connections_reached()) {
10557 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10558 return -EINVAL;
10559 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010560 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070010561 wdev = ndev->ieee80211_ptr;
10562
10563#ifdef WLAN_BTAMP_FEATURE
10564 if((NL80211_IFTYPE_P2P_CLIENT == type)||
10565 (NL80211_IFTYPE_ADHOC == type)||
10566 (NL80211_IFTYPE_AP == type)||
10567 (NL80211_IFTYPE_P2P_GO == type))
10568 {
10569 pHddCtx->isAmpAllowed = VOS_FALSE;
10570 // stop AMP traffic
10571 status = WLANBAP_StopAmp();
10572 if(VOS_STATUS_SUCCESS != status )
10573 {
10574 pHddCtx->isAmpAllowed = VOS_TRUE;
10575 hddLog(VOS_TRACE_LEVEL_FATAL,
10576 "%s: Failed to stop AMP", __func__);
10577 return -EINVAL;
10578 }
10579 }
10580#endif //WLAN_BTAMP_FEATURE
10581 /* Reset the current device mode bit mask*/
10582 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10583
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053010584 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
10585 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
10586 (type == NL80211_IFTYPE_P2P_GO)))
10587 {
10588 /* Notify Mode change in case of concurrency.
10589 * Below function invokes TDLS teardown Functionality Since TDLS is
10590 * not Supported in case of concurrency i.e Once P2P session
10591 * is detected disable offchannel and teardown TDLS links
10592 */
10593 hddLog(LOG1,
10594 FL("Device mode = %d Interface type = %d"),
10595 pAdapter->device_mode, type);
10596 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
10597 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053010598
Jeff Johnson295189b2012-06-20 16:38:30 -070010599 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010600 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070010601 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010602 )
10603 {
10604 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010605 if (!pWextState)
10606 {
10607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10608 "%s: pWextState is null", __func__);
10609 return VOS_STATUS_E_FAILURE;
10610 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010611 pRoamProfile = &pWextState->roamProfile;
10612 LastBSSType = pRoamProfile->BSSType;
10613
10614 switch (type)
10615 {
10616 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010617 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010618 hddLog(VOS_TRACE_LEVEL_INFO,
10619 "%s: setting interface Type to INFRASTRUCTURE", __func__);
10620 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010621#ifdef WLAN_FEATURE_11AC
10622 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
10623 {
10624 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
10625 }
10626#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010627 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070010628 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010629 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010630 //Check for sub-string p2p to confirm its a p2p interface
10631 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010632 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053010633#ifdef FEATURE_WLAN_TDLS
10634 mutex_lock(&pHddCtx->tdls_lock);
10635 wlan_hdd_tdls_exit(pAdapter, TRUE);
10636 mutex_unlock(&pHddCtx->tdls_lock);
10637#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010638 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10639 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10640 }
10641 else
10642 {
10643 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010644 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010645 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010646 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053010647
Jeff Johnson295189b2012-06-20 16:38:30 -070010648 case NL80211_IFTYPE_ADHOC:
10649 hddLog(VOS_TRACE_LEVEL_INFO,
10650 "%s: setting interface Type to ADHOC", __func__);
10651 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
10652 pRoamProfile->phyMode =
10653 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070010654 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010655 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053010656 hdd_set_ibss_ops( pAdapter );
10657 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053010658
10659 status = hdd_sta_id_hash_attach(pAdapter);
10660 if (VOS_STATUS_SUCCESS != status) {
10661 hddLog(VOS_TRACE_LEVEL_ERROR,
10662 FL("Failed to initialize hash for IBSS"));
10663 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010664 break;
10665
10666 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010667 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010668 {
10669 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10670 "%s: setting interface Type to %s", __func__,
10671 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
10672
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010673 //Cancel any remain on channel for GO mode
10674 if (NL80211_IFTYPE_P2P_GO == type)
10675 {
10676 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
10677 }
Mohit Khanna0f232092012-09-11 14:46:08 -070010678 if (NL80211_IFTYPE_AP == type)
10679 {
10680 /* As Loading WLAN Driver one interface being created for p2p device
10681 * address. This will take one HW STA and the max number of clients
10682 * that can connect to softAP will be reduced by one. so while changing
10683 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
10684 * interface as it is not required in SoftAP mode.
10685 */
10686
10687 // Get P2P Adapter
10688 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
10689
10690 if (pP2pAdapter)
10691 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010692 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053010693 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070010694 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
10695 }
10696 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053010697 //Disable IMPS & BMPS for SAP/GO
10698 if(VOS_STATUS_E_FAILURE ==
10699 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
10700 {
10701 //Fail to Exit BMPS
10702 VOS_ASSERT(0);
10703 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053010704
10705 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
10706
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010707#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070010708
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010709 /* A Mutex Lock is introduced while changing the mode to
10710 * protect the concurrent access for the Adapters by TDLS
10711 * module.
10712 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010713 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010714#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010715 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053010716 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010717 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070010718 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10719 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010720#ifdef FEATURE_WLAN_TDLS
10721 mutex_unlock(&pHddCtx->tdls_lock);
10722#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010723 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
10724 (pConfig->apRandomBssidEnabled))
10725 {
10726 /* To meet Android requirements create a randomized
10727 MAC address of the form 02:1A:11:Fx:xx:xx */
10728 get_random_bytes(&ndev->dev_addr[3], 3);
10729 ndev->dev_addr[0] = 0x02;
10730 ndev->dev_addr[1] = 0x1A;
10731 ndev->dev_addr[2] = 0x11;
10732 ndev->dev_addr[3] |= 0xF0;
10733 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
10734 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080010735 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
10736 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010737 }
10738
Jeff Johnson295189b2012-06-20 16:38:30 -070010739 hdd_set_ap_ops( pAdapter->dev );
10740
Kiet Lam10841362013-11-01 11:36:50 +053010741 /* This is for only SAP mode where users can
10742 * control country through ini.
10743 * P2P GO follows station country code
10744 * acquired during the STA scanning. */
10745 if((NL80211_IFTYPE_AP == type) &&
10746 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
10747 {
10748 int status = 0;
10749 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
10750 "%s: setting country code from INI ", __func__);
10751 init_completion(&pAdapter->change_country_code);
10752 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
10753 (void *)(tSmeChangeCountryCallback)
10754 wlan_hdd_change_country_code_cb,
10755 pConfig->apCntryCode, pAdapter,
10756 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010757 eSIR_FALSE,
10758 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053010759 if (eHAL_STATUS_SUCCESS == status)
10760 {
10761 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010762 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053010763 &pAdapter->change_country_code,
10764 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010765 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053010766 {
10767 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010768 FL("SME Timed out while setting country code %ld"),
10769 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080010770
10771 if (pHddCtx->isLogpInProgress)
10772 {
10773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10774 "%s: LOGP in Progress. Ignore!!!", __func__);
10775 return -EAGAIN;
10776 }
Kiet Lam10841362013-11-01 11:36:50 +053010777 }
10778 }
10779 else
10780 {
10781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010782 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053010783 return -EINVAL;
10784 }
10785 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053010786 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070010787 if(status != VOS_STATUS_SUCCESS)
10788 {
10789 hddLog(VOS_TRACE_LEVEL_FATAL,
10790 "%s: Error initializing the ap mode", __func__);
10791 return -EINVAL;
10792 }
10793 hdd_set_conparam(1);
10794
Nirav Shah7e3c8132015-06-22 23:51:42 +053010795 status = hdd_sta_id_hash_attach(pAdapter);
10796 if (VOS_STATUS_SUCCESS != status)
10797 {
10798 hddLog(VOS_TRACE_LEVEL_ERROR,
10799 FL("Failed to initialize hash for AP"));
10800 return -EINVAL;
10801 }
10802
Jeff Johnson295189b2012-06-20 16:38:30 -070010803 /*interface type changed update in wiphy structure*/
10804 if(wdev)
10805 {
10806 wdev->iftype = type;
10807 pHddCtx->change_iface = type;
10808 }
10809 else
10810 {
10811 hddLog(VOS_TRACE_LEVEL_ERROR,
10812 "%s: ERROR !!!! Wireless dev is NULL", __func__);
10813 return -EINVAL;
10814 }
10815 goto done;
10816 }
10817
10818 default:
10819 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10820 __func__);
10821 return -EOPNOTSUPP;
10822 }
10823 }
10824 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010825 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010826 )
10827 {
10828 switch(type)
10829 {
10830 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010831 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010832 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053010833
10834 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010835#ifdef FEATURE_WLAN_TDLS
10836
10837 /* A Mutex Lock is introduced while changing the mode to
10838 * protect the concurrent access for the Adapters by TDLS
10839 * module.
10840 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010841 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010842#endif
c_hpothu002231a2015-02-05 14:58:51 +053010843 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010844 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010845 //Check for sub-string p2p to confirm its a p2p interface
10846 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010847 {
10848 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10849 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10850 }
10851 else
10852 {
10853 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010854 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010855 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053010856
10857 /* set con_mode to STA only when no SAP concurrency mode */
10858 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
10859 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070010860 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010861 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
10862 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010863#ifdef FEATURE_WLAN_TDLS
10864 mutex_unlock(&pHddCtx->tdls_lock);
10865#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053010866 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070010867 if( VOS_STATUS_SUCCESS != status )
10868 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070010869 /* In case of JB, for P2P-GO, only change interface will be called,
10870 * This is the right place to enable back bmps_imps()
10871 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010872 if (pHddCtx->hdd_wlan_suspended)
10873 {
10874 hdd_set_pwrparams(pHddCtx);
10875 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010876 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010877 goto done;
10878 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010879 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010880 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010881 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10882 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010883 goto done;
10884 default:
10885 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10886 __func__);
10887 return -EOPNOTSUPP;
10888
10889 }
10890
10891 }
10892 else
10893 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010894 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
10895 __func__, hdd_device_modetoString(pAdapter->device_mode),
10896 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010897 return -EOPNOTSUPP;
10898 }
10899
10900
10901 if(pRoamProfile)
10902 {
10903 if ( LastBSSType != pRoamProfile->BSSType )
10904 {
10905 /*interface type changed update in wiphy structure*/
10906 wdev->iftype = type;
10907
10908 /*the BSS mode changed, We need to issue disconnect
10909 if connected or in IBSS disconnect state*/
10910 if ( hdd_connGetConnectedBssType(
10911 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
10912 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
10913 {
10914 /*need to issue a disconnect to CSR.*/
10915 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10916 if( eHAL_STATUS_SUCCESS ==
10917 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10918 pAdapter->sessionId,
10919 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10920 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010921 ret = wait_for_completion_interruptible_timeout(
10922 &pAdapter->disconnect_comp_var,
10923 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10924 if (ret <= 0)
10925 {
10926 hddLog(VOS_TRACE_LEVEL_ERROR,
10927 FL("wait on disconnect_comp_var failed %ld"), ret);
10928 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010929 }
10930 }
10931 }
10932 }
10933
10934done:
10935 /*set bitmask based on updated value*/
10936 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070010937
10938 /* Only STA mode support TM now
10939 * all other mode, TM feature should be disabled */
10940 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
10941 (~VOS_STA & pHddCtx->concurrency_mode) )
10942 {
10943 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
10944 }
10945
Jeff Johnson295189b2012-06-20 16:38:30 -070010946#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010947 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010948 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070010949 {
10950 //we are ok to do AMP
10951 pHddCtx->isAmpAllowed = VOS_TRUE;
10952 }
10953#endif //WLAN_BTAMP_FEATURE
10954 EXIT();
10955 return 0;
10956}
10957
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010958/*
10959 * FUNCTION: wlan_hdd_cfg80211_change_iface
10960 * wrapper function to protect the actual implementation from SSR.
10961 */
10962int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
10963 struct net_device *ndev,
10964 enum nl80211_iftype type,
10965 u32 *flags,
10966 struct vif_params *params
10967 )
10968{
10969 int ret;
10970
10971 vos_ssr_protect(__func__);
10972 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
10973 vos_ssr_unprotect(__func__);
10974
10975 return ret;
10976}
10977
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010978#ifdef FEATURE_WLAN_TDLS
10979static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010980 struct net_device *dev,
10981#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10982 const u8 *mac,
10983#else
10984 u8 *mac,
10985#endif
10986 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010987{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010988 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010989 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010990 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010991 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010992 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010993 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010994
10995 ENTER();
10996
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010997 if (!dev) {
10998 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
10999 return -EINVAL;
11000 }
11001
11002 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11003 if (!pAdapter) {
11004 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
11005 return -EINVAL;
11006 }
11007
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011008 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011009 {
11010 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11011 "Invalid arguments");
11012 return -EINVAL;
11013 }
Hoonki Lee27511902013-03-14 18:19:06 -070011014
11015 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
11016 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
11017 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011018 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070011019 "%s: TDLS mode is disabled OR not enabled in FW."
11020 MAC_ADDRESS_STR " Request declined.",
11021 __func__, MAC_ADDR_ARRAY(mac));
11022 return -ENOTSUPP;
11023 }
11024
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011025 if (pHddCtx->isLogpInProgress)
11026 {
11027 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11028 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053011029 wlan_hdd_tdls_set_link_status(pAdapter,
11030 mac,
11031 eTDLS_LINK_IDLE,
11032 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011033 return -EBUSY;
11034 }
11035
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011036 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053011037 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011038
11039 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011040 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011041 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
11042 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053011043 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011044 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011045 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011046
11047 /* in add station, we accept existing valid staId if there is */
11048 if ((0 == update) &&
11049 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
11050 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011051 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011053 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011054 " link_status %d. staId %d. add station ignored.",
11055 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011056 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011057 return 0;
11058 }
11059 /* in change station, we accept only when staId is valid */
11060 if ((1 == update) &&
11061 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
11062 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
11063 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011064 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011065 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011066 "%s: " MAC_ADDRESS_STR
11067 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011068 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
11069 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
11070 mutex_unlock(&pHddCtx->tdls_lock);
11071 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011072 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011073 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011074
11075 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053011076 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011077 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011078 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11079 "%s: " MAC_ADDRESS_STR
11080 " TDLS setup is ongoing. Request declined.",
11081 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070011082 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011083 }
11084
11085 /* first to check if we reached to maximum supported TDLS peer.
11086 TODO: for now, return -EPERM looks working fine,
11087 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011088 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
11089 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011090 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11092 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011093 " TDLS Max peer already connected. Request declined."
11094 " Num of peers (%d), Max allowed (%d).",
11095 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
11096 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011097 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011098 }
11099 else
11100 {
11101 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011102 mutex_lock(&pHddCtx->tdls_lock);
11103 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011104 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011105 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011106 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11108 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
11109 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011110 return -EPERM;
11111 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053011112 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011113 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011114 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053011115 wlan_hdd_tdls_set_link_status(pAdapter,
11116 mac,
11117 eTDLS_LINK_CONNECTING,
11118 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011119
Jeff Johnsond75fe012013-04-06 10:53:06 -070011120 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011121 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011122 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011123 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011124 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011125 if(StaParams->htcap_present)
11126 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011128 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011129 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011130 "ht_capa->extended_capabilities: %0x",
11131 StaParams->HTCap.extendedHtCapInfo);
11132 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011134 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011135 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011136 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070011137 if(StaParams->vhtcap_present)
11138 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070011140 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
11141 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
11142 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
11143 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011144 {
11145 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011146 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011147 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053011148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011149 "[%d]: %x ", i, StaParams->supported_rates[i]);
11150 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070011151 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053011152 else if ((1 == update) && (NULL == StaParams))
11153 {
11154 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11155 "%s : update is true, but staParams is NULL. Error!", __func__);
11156 return -EPERM;
11157 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011158
11159 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
11160
11161 if (!update)
11162 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011163 /*Before adding sta make sure that device exited from BMPS*/
11164 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
11165 {
11166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11167 "%s: Adding tdls peer sta. Disable BMPS", __func__);
11168 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
11169 if (status != VOS_STATUS_SUCCESS) {
11170 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
11171 }
11172 }
11173
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011174 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011175 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011176 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053011177 hddLog(VOS_TRACE_LEVEL_ERROR,
11178 FL("Failed to add TDLS peer STA. Enable Bmps"));
11179 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011180 return -EPERM;
11181 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011182 }
11183 else
11184 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011185 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011186 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053011187 if (ret != eHAL_STATUS_SUCCESS) {
11188 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
11189 return -EPERM;
11190 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011191 }
11192
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011193 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011194 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
11195
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011196 mutex_lock(&pHddCtx->tdls_lock);
11197 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
11198
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011199 if ((pTdlsPeer != NULL) &&
11200 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011201 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011202 hddLog(VOS_TRACE_LEVEL_ERROR,
11203 FL("peer link status %u"), pTdlsPeer->link_status);
11204 mutex_unlock(&pHddCtx->tdls_lock);
11205 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011206 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053011207 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011208
Masti, Narayanraddi07262462016-01-19 12:40:06 +053011209 if (ret <= 0)
11210 {
11211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11212 "%s: timeout waiting for tdls add station indication %ld",
11213 __func__, ret);
11214 goto error;
11215 }
11216
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011217 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
11218 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011220 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070011221 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011222 }
11223
11224 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070011225
11226error:
Atul Mittal115287b2014-07-08 13:26:33 +053011227 wlan_hdd_tdls_set_link_status(pAdapter,
11228 mac,
11229 eTDLS_LINK_IDLE,
11230 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070011231 return -EPERM;
11232
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011233}
11234#endif
11235
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011236static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011237 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011238#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11239 const u8 *mac,
11240#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011241 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011242#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011243 struct station_parameters *params)
11244{
11245 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011246 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011247 hdd_context_t *pHddCtx;
11248 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011249 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011250 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011251#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011252 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011253 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011254 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011255 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011256#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011257
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011258 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011259
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011260 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011261 if ((NULL == pAdapter))
11262 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011264 "invalid adapter ");
11265 return -EINVAL;
11266 }
11267
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011268 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11269 TRACE_CODE_HDD_CHANGE_STATION,
11270 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053011271 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011272
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011273 ret = wlan_hdd_validate_context(pHddCtx);
11274 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053011275 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011276 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011277 }
11278
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011279 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11280
11281 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011282 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11284 "invalid HDD station context");
11285 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011286 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011287 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
11288
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011289 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11290 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070011291 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011292 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070011293 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011294 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070011295 WLANTL_STA_AUTHENTICATED);
11296
Gopichand Nakkala29149562013-05-10 21:43:41 +053011297 if (status != VOS_STATUS_SUCCESS)
11298 {
11299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11300 "%s: Not able to change TL state to AUTHENTICATED", __func__);
11301 return -EINVAL;
11302 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011303 }
11304 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070011305 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
11306 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011307#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011308 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11309 StaParams.capability = params->capability;
11310 StaParams.uapsd_queues = params->uapsd_queues;
11311 StaParams.max_sp = params->max_sp;
11312
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011313 /* Convert (first channel , number of channels) tuple to
11314 * the total list of channels. This goes with the assumption
11315 * that if the first channel is < 14, then the next channels
11316 * are an incremental of 1 else an incremental of 4 till the number
11317 * of channels.
11318 */
11319 if (0 != params->supported_channels_len) {
11320 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
11321 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
11322 {
11323 int wifi_chan_index;
11324 StaParams.supported_channels[j] = params->supported_channels[i];
11325 wifi_chan_index =
11326 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
11327 no_of_channels = params->supported_channels[i+1];
11328 for(k=1; k <= no_of_channels; k++)
11329 {
11330 StaParams.supported_channels[j+1] =
11331 StaParams.supported_channels[j] + wifi_chan_index;
11332 j+=1;
11333 }
11334 }
11335 StaParams.supported_channels_len = j;
11336 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053011337 if (params->supported_oper_classes_len >
11338 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
11339 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11340 "received oper classes:%d, resetting it to max supported %d",
11341 params->supported_oper_classes_len,
11342 SIR_MAC_MAX_SUPP_OPER_CLASSES);
11343 params->supported_oper_classes_len =
11344 SIR_MAC_MAX_SUPP_OPER_CLASSES;
11345 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011346 vos_mem_copy(StaParams.supported_oper_classes,
11347 params->supported_oper_classes,
11348 params->supported_oper_classes_len);
11349 StaParams.supported_oper_classes_len =
11350 params->supported_oper_classes_len;
11351
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053011352 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
11353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11354 "received extn capabilities:%d, resetting it to max supported",
11355 params->ext_capab_len);
11356 params->ext_capab_len = sizeof(StaParams.extn_capability);
11357 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011358 if (0 != params->ext_capab_len)
11359 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053011360 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011361
11362 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011363 {
11364 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011365 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011366 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011367
11368 StaParams.supported_rates_len = params->supported_rates_len;
11369
11370 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
11371 * The supported_rates array , for all the structures propogating till Add Sta
11372 * to the firmware has to be modified , if the supplicant (ieee80211) is
11373 * modified to send more rates.
11374 */
11375
11376 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11377 */
11378 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11379 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11380
11381 if (0 != StaParams.supported_rates_len) {
11382 int i = 0;
11383 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11384 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011385 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011386 "Supported Rates with Length %d", StaParams.supported_rates_len);
11387 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011389 "[%d]: %0x", i, StaParams.supported_rates[i]);
11390 }
11391
11392 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011393 {
11394 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011395 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011396 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011397
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011398 if (0 != params->ext_capab_len ) {
11399 /*Define A Macro : TODO Sunil*/
11400 if ((1<<4) & StaParams.extn_capability[3]) {
11401 isBufSta = 1;
11402 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011403 /* TDLS Channel Switching Support */
11404 if ((1<<6) & StaParams.extn_capability[3]) {
11405 isOffChannelSupported = 1;
11406 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011407 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011408
11409 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053011410 (params->ht_capa || params->vht_capa ||
11411 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011412 /* TDLS Peer is WME/QoS capable */
11413 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011414
11415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11416 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
11417 __func__, isQosWmmSta, StaParams.htcap_present);
11418
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011419 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11420 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011421 isOffChannelSupported,
11422 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011423
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011424 if (VOS_STATUS_SUCCESS != status) {
11425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11426 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11427 return -EINVAL;
11428 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011429 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11430
11431 if (VOS_STATUS_SUCCESS != status) {
11432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11433 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11434 return -EINVAL;
11435 }
11436 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011437#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011438 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011439 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011440 return status;
11441}
11442
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011443#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11444static int wlan_hdd_change_station(struct wiphy *wiphy,
11445 struct net_device *dev,
11446 const u8 *mac,
11447 struct station_parameters *params)
11448#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011449static int wlan_hdd_change_station(struct wiphy *wiphy,
11450 struct net_device *dev,
11451 u8 *mac,
11452 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011453#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011454{
11455 int ret;
11456
11457 vos_ssr_protect(__func__);
11458 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
11459 vos_ssr_unprotect(__func__);
11460
11461 return ret;
11462}
11463
Jeff Johnson295189b2012-06-20 16:38:30 -070011464/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011465 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011466 * This function is used to initialize the key information
11467 */
11468#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011469static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011470 struct net_device *ndev,
11471 u8 key_index, bool pairwise,
11472 const u8 *mac_addr,
11473 struct key_params *params
11474 )
11475#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011476static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011477 struct net_device *ndev,
11478 u8 key_index, const u8 *mac_addr,
11479 struct key_params *params
11480 )
11481#endif
11482{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011483 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011484 tCsrRoamSetKey setKey;
11485 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011486 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011487 v_U32_t roamId= 0xFF;
11488 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011489 hdd_hostapd_state_t *pHostapdState;
11490 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011491 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011492 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011493
11494 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011495
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011496 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11497 TRACE_CODE_HDD_CFG80211_ADD_KEY,
11498 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011499 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11500 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011501 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011502 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011503 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011504 }
11505
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011506 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11507 __func__, hdd_device_modetoString(pAdapter->device_mode),
11508 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011509
11510 if (CSR_MAX_NUM_KEY <= key_index)
11511 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011512 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011513 key_index);
11514
11515 return -EINVAL;
11516 }
11517
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011518 if (CSR_MAX_KEY_LEN < params->key_len)
11519 {
11520 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
11521 params->key_len);
11522
11523 return -EINVAL;
11524 }
11525
11526 hddLog(VOS_TRACE_LEVEL_INFO,
11527 "%s: called with key index = %d & key length %d",
11528 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011529
11530 /*extract key idx, key len and key*/
11531 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11532 setKey.keyId = key_index;
11533 setKey.keyLength = params->key_len;
11534 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
11535
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011536 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011537 {
11538 case WLAN_CIPHER_SUITE_WEP40:
11539 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11540 break;
11541
11542 case WLAN_CIPHER_SUITE_WEP104:
11543 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
11544 break;
11545
11546 case WLAN_CIPHER_SUITE_TKIP:
11547 {
11548 u8 *pKey = &setKey.Key[0];
11549 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
11550
11551 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
11552
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011553 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070011554
11555 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011556 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011557 |--------------|----------|----------|
11558 <---16bytes---><--8bytes--><--8bytes-->
11559
11560 */
11561 /*Sme expects the 32 bytes key to be in the below order
11562
11563 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011564 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011565 |--------------|----------|----------|
11566 <---16bytes---><--8bytes--><--8bytes-->
11567 */
11568 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011569 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070011570
11571 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011572 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011573
11574 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011575 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011576
11577
11578 break;
11579 }
11580
11581 case WLAN_CIPHER_SUITE_CCMP:
11582 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
11583 break;
11584
11585#ifdef FEATURE_WLAN_WAPI
11586 case WLAN_CIPHER_SUITE_SMS4:
11587 {
11588 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11589 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
11590 params->key, params->key_len);
11591 return 0;
11592 }
11593#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011594
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011595#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011596 case WLAN_CIPHER_SUITE_KRK:
11597 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
11598 break;
11599#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011600
11601#ifdef WLAN_FEATURE_11W
11602 case WLAN_CIPHER_SUITE_AES_CMAC:
11603 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070011604 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070011605#endif
11606
Jeff Johnson295189b2012-06-20 16:38:30 -070011607 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011608 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011609 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011610 status = -EOPNOTSUPP;
11611 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011612 }
11613
11614 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
11615 __func__, setKey.encType);
11616
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011617 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070011618#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11619 (!pairwise)
11620#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011621 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070011622#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011623 )
11624 {
11625 /* set group key*/
11626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11627 "%s- %d: setting Broadcast key",
11628 __func__, __LINE__);
11629 setKey.keyDirection = eSIR_RX_ONLY;
11630 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11631 }
11632 else
11633 {
11634 /* set pairwise key*/
11635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11636 "%s- %d: setting pairwise key",
11637 __func__, __LINE__);
11638 setKey.keyDirection = eSIR_TX_RX;
11639 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11640 }
11641 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
11642 {
11643 setKey.keyDirection = eSIR_TX_RX;
11644 /*Set the group key*/
11645 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11646 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070011647
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011648 if ( 0 != status )
11649 {
11650 hddLog(VOS_TRACE_LEVEL_ERROR,
11651 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011652 status = -EINVAL;
11653 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011654 }
11655 /*Save the keys here and call sme_RoamSetKey for setting
11656 the PTK after peer joins the IBSS network*/
11657 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
11658 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011659 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011660 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053011661 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
11662 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
11663 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011664 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011665 if( pHostapdState->bssState == BSS_START )
11666 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011667 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11668 vos_status = wlan_hdd_check_ula_done(pAdapter);
11669
11670 if ( vos_status != VOS_STATUS_SUCCESS )
11671 {
11672 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11673 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11674 __LINE__, vos_status );
11675
11676 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11677
11678 status = -EINVAL;
11679 goto end;
11680 }
11681
Jeff Johnson295189b2012-06-20 16:38:30 -070011682 status = WLANSAP_SetKeySta( pVosContext, &setKey);
11683
11684 if ( status != eHAL_STATUS_SUCCESS )
11685 {
11686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11687 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11688 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011689 status = -EINVAL;
11690 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011691 }
11692 }
11693
11694 /* Saving WEP keys */
11695 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
11696 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
11697 {
11698 //Save the wep key in ap context. Issue setkey after the BSS is started.
11699 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11700 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
11701 }
11702 else
11703 {
11704 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011705 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011706 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
11707 }
11708 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011709 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
11710 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011711 {
11712 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11713 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11714
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011715#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11716 if (!pairwise)
11717#else
11718 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
11719#endif
11720 {
11721 /* set group key*/
11722 if (pHddStaCtx->roam_info.deferKeyComplete)
11723 {
11724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11725 "%s- %d: Perform Set key Complete",
11726 __func__, __LINE__);
11727 hdd_PerformRoamSetKeyComplete(pAdapter);
11728 }
11729 }
11730
Jeff Johnson295189b2012-06-20 16:38:30 -070011731 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
11732
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080011733 pWextState->roamProfile.Keys.defaultIndex = key_index;
11734
11735
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011736 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011737 params->key, params->key_len);
11738
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011739
Jeff Johnson295189b2012-06-20 16:38:30 -070011740 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11741
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011742 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011743 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011744 __func__, setKey.peerMac[0], setKey.peerMac[1],
11745 setKey.peerMac[2], setKey.peerMac[3],
11746 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011747 setKey.keyDirection);
11748
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011749 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053011750
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011751 if ( vos_status != VOS_STATUS_SUCCESS )
11752 {
11753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011754 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11755 __LINE__, vos_status );
11756
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011757 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011758
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011759 status = -EINVAL;
11760 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011761
11762 }
11763
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011764#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011765 /* The supplicant may attempt to set the PTK once pre-authentication
11766 is done. Save the key in the UMAC and include it in the ADD BSS
11767 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011768 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011769 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011770 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011771 hddLog(VOS_TRACE_LEVEL_INFO_MED,
11772 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011773 status = 0;
11774 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011775 }
11776 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
11777 {
11778 hddLog(VOS_TRACE_LEVEL_ERROR,
11779 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011780 status = -EINVAL;
11781 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011782 }
11783#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070011784
11785 /* issue set key request to SME*/
11786 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11787 pAdapter->sessionId, &setKey, &roamId );
11788
11789 if ( 0 != status )
11790 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011791 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011792 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
11793 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011794 status = -EINVAL;
11795 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011796 }
11797
11798
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011799 /* in case of IBSS as there was no information available about WEP keys during
11800 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070011801 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011802 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
11803 !( ( IW_AUTH_KEY_MGMT_802_1X
11804 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070011805 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
11806 )
11807 &&
11808 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
11809 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
11810 )
11811 )
11812 {
11813 setKey.keyDirection = eSIR_RX_ONLY;
11814 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11815
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011816 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011817 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011818 __func__, setKey.peerMac[0], setKey.peerMac[1],
11819 setKey.peerMac[2], setKey.peerMac[3],
11820 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011821 setKey.keyDirection);
11822
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011823 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011824 pAdapter->sessionId, &setKey, &roamId );
11825
11826 if ( 0 != status )
11827 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011828 hddLog(VOS_TRACE_LEVEL_ERROR,
11829 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011830 __func__, status);
11831 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011832 status = -EINVAL;
11833 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011834 }
11835 }
11836 }
11837
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011838end:
11839 /* Need to clear any trace of key value in the memory.
11840 * Thus zero out the memory even though it is local
11841 * variable.
11842 */
11843 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011844 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011845 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011846}
11847
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011848#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11849static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11850 struct net_device *ndev,
11851 u8 key_index, bool pairwise,
11852 const u8 *mac_addr,
11853 struct key_params *params
11854 )
11855#else
11856static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11857 struct net_device *ndev,
11858 u8 key_index, const u8 *mac_addr,
11859 struct key_params *params
11860 )
11861#endif
11862{
11863 int ret;
11864 vos_ssr_protect(__func__);
11865#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11866 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
11867 mac_addr, params);
11868#else
11869 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
11870 params);
11871#endif
11872 vos_ssr_unprotect(__func__);
11873
11874 return ret;
11875}
11876
Jeff Johnson295189b2012-06-20 16:38:30 -070011877/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011878 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011879 * This function is used to get the key information
11880 */
11881#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011882static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011883 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011884 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011885 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011886 const u8 *mac_addr, void *cookie,
11887 void (*callback)(void *cookie, struct key_params*)
11888 )
11889#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011890static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011891 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011892 struct net_device *ndev,
11893 u8 key_index, const u8 *mac_addr, void *cookie,
11894 void (*callback)(void *cookie, struct key_params*)
11895 )
11896#endif
11897{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011898 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011899 hdd_wext_state_t *pWextState = NULL;
11900 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011901 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011902 hdd_context_t *pHddCtx;
11903 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011904
11905 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011906
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011907 if (NULL == pAdapter)
11908 {
11909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11910 "%s: HDD adapter is Null", __func__);
11911 return -ENODEV;
11912 }
11913
11914 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11915 ret = wlan_hdd_validate_context(pHddCtx);
11916 if (0 != ret)
11917 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011918 return ret;
11919 }
11920
11921 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11922 pRoamProfile = &(pWextState->roamProfile);
11923
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011924 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11925 __func__, hdd_device_modetoString(pAdapter->device_mode),
11926 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011927
Jeff Johnson295189b2012-06-20 16:38:30 -070011928 memset(&params, 0, sizeof(params));
11929
11930 if (CSR_MAX_NUM_KEY <= key_index)
11931 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011932 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011933 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011934 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011935
11936 switch(pRoamProfile->EncryptionType.encryptionType[0])
11937 {
11938 case eCSR_ENCRYPT_TYPE_NONE:
11939 params.cipher = IW_AUTH_CIPHER_NONE;
11940 break;
11941
11942 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
11943 case eCSR_ENCRYPT_TYPE_WEP40:
11944 params.cipher = WLAN_CIPHER_SUITE_WEP40;
11945 break;
11946
11947 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
11948 case eCSR_ENCRYPT_TYPE_WEP104:
11949 params.cipher = WLAN_CIPHER_SUITE_WEP104;
11950 break;
11951
11952 case eCSR_ENCRYPT_TYPE_TKIP:
11953 params.cipher = WLAN_CIPHER_SUITE_TKIP;
11954 break;
11955
11956 case eCSR_ENCRYPT_TYPE_AES:
11957 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
11958 break;
11959
11960 default:
11961 params.cipher = IW_AUTH_CIPHER_NONE;
11962 break;
11963 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011964
c_hpothuaaf19692014-05-17 17:01:48 +053011965 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11966 TRACE_CODE_HDD_CFG80211_GET_KEY,
11967 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011968
Jeff Johnson295189b2012-06-20 16:38:30 -070011969 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
11970 params.seq_len = 0;
11971 params.seq = NULL;
11972 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
11973 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011974 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011975 return 0;
11976}
11977
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011978#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11979static int wlan_hdd_cfg80211_get_key(
11980 struct wiphy *wiphy,
11981 struct net_device *ndev,
11982 u8 key_index, bool pairwise,
11983 const u8 *mac_addr, void *cookie,
11984 void (*callback)(void *cookie, struct key_params*)
11985 )
11986#else
11987static int wlan_hdd_cfg80211_get_key(
11988 struct wiphy *wiphy,
11989 struct net_device *ndev,
11990 u8 key_index, const u8 *mac_addr, void *cookie,
11991 void (*callback)(void *cookie, struct key_params*)
11992 )
11993#endif
11994{
11995 int ret;
11996
11997 vos_ssr_protect(__func__);
11998#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11999 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
12000 mac_addr, cookie, callback);
12001#else
12002 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
12003 callback);
12004#endif
12005 vos_ssr_unprotect(__func__);
12006
12007 return ret;
12008}
12009
Jeff Johnson295189b2012-06-20 16:38:30 -070012010/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012011 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012012 * This function is used to delete the key information
12013 */
12014#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012015static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012016 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012017 u8 key_index,
12018 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012019 const u8 *mac_addr
12020 )
12021#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012022static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012023 struct net_device *ndev,
12024 u8 key_index,
12025 const u8 *mac_addr
12026 )
12027#endif
12028{
12029 int status = 0;
12030
12031 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012032 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070012033 //it is observed that this is invalidating peer
12034 //key index whenever re-key is done. This is affecting data link.
12035 //It should be ok to ignore del_key.
12036#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012037 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
12038 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012039 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12040 tCsrRoamSetKey setKey;
12041 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012042
Jeff Johnson295189b2012-06-20 16:38:30 -070012043 ENTER();
12044
12045 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
12046 __func__,pAdapter->device_mode);
12047
12048 if (CSR_MAX_NUM_KEY <= key_index)
12049 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012050 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012051 key_index);
12052
12053 return -EINVAL;
12054 }
12055
12056 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12057 setKey.keyId = key_index;
12058
12059 if (mac_addr)
12060 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
12061 else
12062 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
12063
12064 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
12065
12066 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012067 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012068 )
12069 {
12070
12071 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070012072 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
12073 if( pHostapdState->bssState == BSS_START)
12074 {
12075 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012076
Jeff Johnson295189b2012-06-20 16:38:30 -070012077 if ( status != eHAL_STATUS_SUCCESS )
12078 {
12079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12080 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12081 __LINE__, status );
12082 }
12083 }
12084 }
12085 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012086 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070012087 )
12088 {
12089 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12090
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012091 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12092
12093 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012094 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012095 __func__, setKey.peerMac[0], setKey.peerMac[1],
12096 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070012097 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012098 if(pAdapter->sessionCtx.station.conn_info.connState ==
12099 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070012100 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012101 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012102 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012103
Jeff Johnson295189b2012-06-20 16:38:30 -070012104 if ( 0 != status )
12105 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012106 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012107 "%s: sme_RoamSetKey failure, returned %d",
12108 __func__, status);
12109 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12110 return -EINVAL;
12111 }
12112 }
12113 }
12114#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012115 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012116 return status;
12117}
12118
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012119#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12120static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12121 struct net_device *ndev,
12122 u8 key_index,
12123 bool pairwise,
12124 const u8 *mac_addr
12125 )
12126#else
12127static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
12128 struct net_device *ndev,
12129 u8 key_index,
12130 const u8 *mac_addr
12131 )
12132#endif
12133{
12134 int ret;
12135
12136 vos_ssr_protect(__func__);
12137#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12138 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
12139 mac_addr);
12140#else
12141 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
12142#endif
12143 vos_ssr_unprotect(__func__);
12144
12145 return ret;
12146}
12147
Jeff Johnson295189b2012-06-20 16:38:30 -070012148/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012149 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012150 * This function is used to set the default tx key index
12151 */
12152#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012153static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012154 struct net_device *ndev,
12155 u8 key_index,
12156 bool unicast, bool multicast)
12157#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012158static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012159 struct net_device *ndev,
12160 u8 key_index)
12161#endif
12162{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012163 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012164 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012165 hdd_wext_state_t *pWextState;
12166 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012167 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012168
12169 ENTER();
12170
Gopichand Nakkala29149562013-05-10 21:43:41 +053012171 if ((NULL == pAdapter))
12172 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012174 "invalid adapter");
12175 return -EINVAL;
12176 }
12177
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012178 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12179 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
12180 pAdapter->sessionId, key_index));
12181
Gopichand Nakkala29149562013-05-10 21:43:41 +053012182 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12183 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12184
12185 if ((NULL == pWextState) || (NULL == pHddStaCtx))
12186 {
12187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12188 "invalid Wext state or HDD context");
12189 return -EINVAL;
12190 }
12191
Arif Hussain6d2a3322013-11-17 19:50:10 -080012192 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012193 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012194
Jeff Johnson295189b2012-06-20 16:38:30 -070012195 if (CSR_MAX_NUM_KEY <= key_index)
12196 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012197 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012198 key_index);
12199
12200 return -EINVAL;
12201 }
12202
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012203 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12204 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012205 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012206 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012207 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012208 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012209
Jeff Johnson295189b2012-06-20 16:38:30 -070012210 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012211 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012212 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012213 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012214 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080012215 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012216 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080012217 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070012218 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012219 {
12220 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070012221 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012222
Jeff Johnson295189b2012-06-20 16:38:30 -070012223 tCsrRoamSetKey setKey;
12224 v_U32_t roamId= 0xFF;
12225 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012226
12227 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012228 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012229
Jeff Johnson295189b2012-06-20 16:38:30 -070012230 Keys->defaultIndex = (u8)key_index;
12231 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12232 setKey.keyId = key_index;
12233 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012234
12235 vos_mem_copy(&setKey.Key[0],
12236 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012237 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012238
Gopichand Nakkala29149562013-05-10 21:43:41 +053012239 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012240
12241 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070012242 &pHddStaCtx->conn_info.bssId[0],
12243 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012244
Gopichand Nakkala29149562013-05-10 21:43:41 +053012245 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
12246 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
12247 eCSR_ENCRYPT_TYPE_WEP104)
12248 {
12249 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
12250 even though ap is configured for WEP-40 encryption. In this canse the key length
12251 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
12252 type(104) and switching encryption type to 40*/
12253 pWextState->roamProfile.EncryptionType.encryptionType[0] =
12254 eCSR_ENCRYPT_TYPE_WEP40;
12255 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
12256 eCSR_ENCRYPT_TYPE_WEP40;
12257 }
12258
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012259 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012260 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012261
Jeff Johnson295189b2012-06-20 16:38:30 -070012262 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012263 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012264 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012265
Jeff Johnson295189b2012-06-20 16:38:30 -070012266 if ( 0 != status )
12267 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012268 hddLog(VOS_TRACE_LEVEL_ERROR,
12269 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012270 status);
12271 return -EINVAL;
12272 }
12273 }
12274 }
12275
12276 /* In SoftAp mode setting key direction for default mode */
12277 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
12278 {
12279 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
12280 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
12281 (eCSR_ENCRYPT_TYPE_AES !=
12282 pWextState->roamProfile.EncryptionType.encryptionType[0])
12283 )
12284 {
12285 /* Saving key direction for default key index to TX default */
12286 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12287 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
12288 }
12289 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012290 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012291 return status;
12292}
12293
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012294#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12295static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12296 struct net_device *ndev,
12297 u8 key_index,
12298 bool unicast, bool multicast)
12299#else
12300static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12301 struct net_device *ndev,
12302 u8 key_index)
12303#endif
12304{
12305 int ret;
12306 vos_ssr_protect(__func__);
12307#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12308 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
12309 multicast);
12310#else
12311 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
12312#endif
12313 vos_ssr_unprotect(__func__);
12314
12315 return ret;
12316}
12317
Jeff Johnson295189b2012-06-20 16:38:30 -070012318/*
12319 * FUNCTION: wlan_hdd_cfg80211_inform_bss
12320 * This function is used to inform the BSS details to nl80211 interface.
12321 */
12322static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
12323 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
12324{
12325 struct net_device *dev = pAdapter->dev;
12326 struct wireless_dev *wdev = dev->ieee80211_ptr;
12327 struct wiphy *wiphy = wdev->wiphy;
12328 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
12329 int chan_no;
12330 int ie_length;
12331 const char *ie;
12332 unsigned int freq;
12333 struct ieee80211_channel *chan;
12334 int rssi = 0;
12335 struct cfg80211_bss *bss = NULL;
12336
Jeff Johnson295189b2012-06-20 16:38:30 -070012337 if( NULL == pBssDesc )
12338 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012339 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012340 return bss;
12341 }
12342
12343 chan_no = pBssDesc->channelId;
12344 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
12345 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
12346
12347 if( NULL == ie )
12348 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012349 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012350 return bss;
12351 }
12352
12353#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
12354 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
12355 {
12356 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12357 }
12358 else
12359 {
12360 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12361 }
12362#else
12363 freq = ieee80211_channel_to_frequency(chan_no);
12364#endif
12365
12366 chan = __ieee80211_get_channel(wiphy, freq);
12367
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053012368 if (!chan) {
12369 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
12370 return NULL;
12371 }
12372
Abhishek Singhaee43942014-06-16 18:55:47 +053012373 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070012374
Anand N Sunkad9f80b742015-07-30 20:05:51 +053012375 return cfg80211_inform_bss(wiphy, chan,
12376#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12377 CFG80211_BSS_FTYPE_UNKNOWN,
12378#endif
12379 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012380 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070012381 pBssDesc->capabilityInfo,
12382 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053012383 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070012384}
12385
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012386/*
12387 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
12388 * interface that BSS might have been lost.
12389 * @pAdapter: adaptor
12390 * @bssid: bssid which might have been lost
12391 *
12392 * Return: bss which is unlinked from kernel cache
12393 */
12394struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
12395 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
12396{
12397 struct net_device *dev = pAdapter->dev;
12398 struct wireless_dev *wdev = dev->ieee80211_ptr;
12399 struct wiphy *wiphy = wdev->wiphy;
12400 struct cfg80211_bss *bss = NULL;
12401
Abhishek Singh5a597e62016-12-05 15:16:30 +053012402 bss = hdd_get_bss_entry(wiphy,
12403 NULL, bssid,
12404 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012405 if (bss == NULL) {
12406 hddLog(LOGE, FL("BSS not present"));
12407 } else {
12408 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
12409 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
12410 cfg80211_unlink_bss(wiphy, bss);
12411 }
12412 return bss;
12413}
Jeff Johnson295189b2012-06-20 16:38:30 -070012414
12415
12416/*
12417 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
12418 * This function is used to inform the BSS details to nl80211 interface.
12419 */
12420struct cfg80211_bss*
12421wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
12422 tSirBssDescription *bss_desc
12423 )
12424{
12425 /*
12426 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
12427 already exists in bss data base of cfg80211 for that particular BSS ID.
12428 Using cfg80211_inform_bss_frame to update the bss entry instead of
12429 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
12430 now there is no possibility to get the mgmt(probe response) frame from PE,
12431 converting bss_desc to ieee80211_mgmt(probe response) and passing to
12432 cfg80211_inform_bss_frame.
12433 */
12434 struct net_device *dev = pAdapter->dev;
12435 struct wireless_dev *wdev = dev->ieee80211_ptr;
12436 struct wiphy *wiphy = wdev->wiphy;
12437 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012438#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12439 qcom_ie_age *qie_age = NULL;
12440 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
12441#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012442 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012443#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012444 const char *ie =
12445 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
12446 unsigned int freq;
12447 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012448 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012449 struct cfg80211_bss *bss_status = NULL;
12450 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
12451 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070012452 hdd_context_t *pHddCtx;
12453 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070012454#ifdef WLAN_OPEN_SOURCE
12455 struct timespec ts;
12456#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012457
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012458
Wilson Yangf80a0542013-10-07 13:02:37 -070012459 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12460 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070012461 if (0 != status)
12462 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012463 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012464 }
12465
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012466 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070012467 if (!mgmt)
12468 {
12469 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12470 "%s: memory allocation failed ", __func__);
12471 return NULL;
12472 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012473
Jeff Johnson295189b2012-06-20 16:38:30 -070012474 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012475
12476#ifdef WLAN_OPEN_SOURCE
12477 /* Android does not want the timestamp from the frame.
12478 Instead it wants a monotonic increasing value */
12479 get_monotonic_boottime(&ts);
12480 mgmt->u.probe_resp.timestamp =
12481 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
12482#else
12483 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012484 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
12485 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070012486
12487#endif
12488
Jeff Johnson295189b2012-06-20 16:38:30 -070012489 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
12490 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012491
12492#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12493 /* GPS Requirement: need age ie per entry. Using vendor specific. */
12494 /* Assuming this is the last IE, copy at the end */
12495 ie_length -=sizeof(qcom_ie_age);
12496 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
12497 qie_age->element_id = QCOM_VENDOR_IE_ID;
12498 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
12499 qie_age->oui_1 = QCOM_OUI1;
12500 qie_age->oui_2 = QCOM_OUI2;
12501 qie_age->oui_3 = QCOM_OUI3;
12502 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053012503 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
12504 * bss related timestamp is in units of ms. Due to this when scan results
12505 * are sent to lowi the scan age is high.To address this, send age in units
12506 * of 1/10 ms.
12507 */
12508 qie_age->age = (vos_timer_get_system_time() -
12509 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012510#endif
12511
Jeff Johnson295189b2012-06-20 16:38:30 -070012512 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053012513 if (bss_desc->fProbeRsp)
12514 {
12515 mgmt->frame_control |=
12516 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
12517 }
12518 else
12519 {
12520 mgmt->frame_control |=
12521 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
12522 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012523
12524#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012525 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012526 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
12527 {
12528 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12529 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012530 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012531 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
12532
12533 {
12534 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12535 }
12536 else
12537 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012538 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
12539 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070012540 kfree(mgmt);
12541 return NULL;
12542 }
12543#else
12544 freq = ieee80211_channel_to_frequency(chan_no);
12545#endif
12546 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012547 /*when the band is changed on the fly using the GUI, three things are done
12548 * 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)
12549 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
12550 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
12551 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
12552 * and discards the channels correponding to previous band and calls back with zero bss results.
12553 * 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
12554 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
12555 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
12556 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
12557 * So drop the bss and continue to next bss.
12558 */
12559 if(chan == NULL)
12560 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053012561 hddLog(VOS_TRACE_LEVEL_ERROR,
12562 FL("chan pointer is NULL, chan_no: %d freq: %d"),
12563 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070012564 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012565 return NULL;
12566 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053012567 /*To keep the rssi icon of the connected AP in the scan window
12568 *and the rssi icon of the wireless networks in sync
12569 * */
12570 if (( eConnectionState_Associated ==
12571 pAdapter->sessionCtx.station.conn_info.connState ) &&
12572 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
12573 pAdapter->sessionCtx.station.conn_info.bssId,
12574 WNI_CFG_BSSID_LEN)) &&
12575 (pHddCtx->hdd_wlan_suspended == FALSE))
12576 {
12577 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
12578 rssi = (pAdapter->rssi * 100);
12579 }
12580 else
12581 {
12582 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
12583 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012584
Nirav Shah20ac06f2013-12-12 18:14:06 +053012585 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053012586 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
12587 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053012588
Jeff Johnson295189b2012-06-20 16:38:30 -070012589 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
12590 frame_len, rssi, GFP_KERNEL);
12591 kfree(mgmt);
12592 return bss_status;
12593}
12594
12595/*
12596 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
12597 * This function is used to update the BSS data base of CFG8011
12598 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012599struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012600 tCsrRoamInfo *pRoamInfo
12601 )
12602{
12603 tCsrRoamConnectedProfile roamProfile;
12604 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12605 struct cfg80211_bss *bss = NULL;
12606
12607 ENTER();
12608
12609 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
12610 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
12611
12612 if (NULL != roamProfile.pBssDesc)
12613 {
Girish Gowlif4b68022014-08-28 23:18:57 +053012614 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12615 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070012616
12617 if (NULL == bss)
12618 {
12619 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
12620 __func__);
12621 }
12622
12623 sme_RoamFreeConnectProfile(hHal, &roamProfile);
12624 }
12625 else
12626 {
12627 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
12628 __func__);
12629 }
12630 return bss;
12631}
12632
12633/*
12634 * FUNCTION: wlan_hdd_cfg80211_update_bss
12635 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012636static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
12637 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070012638 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012639{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012640 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012641 tCsrScanResultInfo *pScanResult;
12642 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012643 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012644 tScanResultHandle pResult;
12645 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012646 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012647 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012648 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012649
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012650 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12651 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
12652 NO_SESSION, pAdapter->sessionId));
12653
Wilson Yangf80a0542013-10-07 13:02:37 -070012654 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012655 ret = wlan_hdd_validate_context(pHddCtx);
12656 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070012657 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012658 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070012659 }
12660
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012661 if (pAdapter->request != NULL)
12662 {
12663 if ((pAdapter->request->n_ssids == 1)
12664 && (pAdapter->request->ssids != NULL)
12665 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
12666 is_p2p_scan = true;
12667 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012668 /*
12669 * start getting scan results and populate cgf80211 BSS database
12670 */
12671 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
12672
12673 /* no scan results */
12674 if (NULL == pResult)
12675 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012676 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
12677 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012678 wlan_hdd_get_frame_logs(pAdapter,
12679 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070012680 return status;
12681 }
12682
12683 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
12684
12685 while (pScanResult)
12686 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012687 /*
12688 * cfg80211_inform_bss() is not updating ie field of bss entry, if
12689 * entry already exists in bss data base of cfg80211 for that
12690 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
12691 * bss entry instead of cfg80211_inform_bss, But this call expects
12692 * mgmt packet as input. As of now there is no possibility to get
12693 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070012694 * ieee80211_mgmt(probe response) and passing to c
12695 * fg80211_inform_bss_frame.
12696 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012697 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
12698 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
12699 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012700 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12701 continue; //Skip the non p2p bss entries
12702 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012703 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12704 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012705
Jeff Johnson295189b2012-06-20 16:38:30 -070012706
12707 if (NULL == bss_status)
12708 {
12709 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012710 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012711 }
12712 else
12713 {
Yue Maf49ba872013-08-19 12:04:25 -070012714 cfg80211_put_bss(
12715#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
12716 wiphy,
12717#endif
12718 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070012719 }
12720
12721 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12722 }
12723
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012724 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012725 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012726 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012727}
12728
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012729void
12730hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
12731{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012732 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080012733 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012734} /****** end hddPrintMacAddr() ******/
12735
12736void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012737hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012738{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012739 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012740 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012741 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
12742 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
12743 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012744} /****** end hddPrintPmkId() ******/
12745
12746//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
12747//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
12748
12749//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
12750//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
12751
12752#define dump_bssid(bssid) \
12753 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012754 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
12755 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012756 }
12757
12758#define dump_pmkid(pMac, pmkid) \
12759 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012760 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
12761 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012762 }
12763
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070012764#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012765/*
12766 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
12767 * This function is used to notify the supplicant of a new PMKSA candidate.
12768 */
12769int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012770 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012771 int index, bool preauth )
12772{
Jeff Johnsone7245742012-09-05 17:12:55 -070012773#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012774 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012775 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012776
12777 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070012778 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012779
12780 if( NULL == pRoamInfo )
12781 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012782 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012783 return -EINVAL;
12784 }
12785
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012786 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
12787 {
12788 dump_bssid(pRoamInfo->bssid);
12789 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012790 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012791 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012792#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012793 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012794}
12795#endif //FEATURE_WLAN_LFR
12796
Yue Maef608272013-04-08 23:09:17 -070012797#ifdef FEATURE_WLAN_LFR_METRICS
12798/*
12799 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
12800 * 802.11r/LFR metrics reporting function to report preauth initiation
12801 *
12802 */
12803#define MAX_LFR_METRICS_EVENT_LENGTH 100
12804VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
12805 tCsrRoamInfo *pRoamInfo)
12806{
12807 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12808 union iwreq_data wrqu;
12809
12810 ENTER();
12811
12812 if (NULL == pAdapter)
12813 {
12814 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12815 return VOS_STATUS_E_FAILURE;
12816 }
12817
12818 /* create the event */
12819 memset(&wrqu, 0, sizeof(wrqu));
12820 memset(metrics_notification, 0, sizeof(metrics_notification));
12821
12822 wrqu.data.pointer = metrics_notification;
12823 wrqu.data.length = scnprintf(metrics_notification,
12824 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
12825 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12826
12827 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12828
12829 EXIT();
12830
12831 return VOS_STATUS_SUCCESS;
12832}
12833
12834/*
12835 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
12836 * 802.11r/LFR metrics reporting function to report preauth completion
12837 * or failure
12838 */
12839VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
12840 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
12841{
12842 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12843 union iwreq_data wrqu;
12844
12845 ENTER();
12846
12847 if (NULL == pAdapter)
12848 {
12849 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12850 return VOS_STATUS_E_FAILURE;
12851 }
12852
12853 /* create the event */
12854 memset(&wrqu, 0, sizeof(wrqu));
12855 memset(metrics_notification, 0, sizeof(metrics_notification));
12856
12857 scnprintf(metrics_notification, sizeof(metrics_notification),
12858 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
12859 MAC_ADDR_ARRAY(pRoamInfo->bssid));
12860
12861 if (1 == preauth_status)
12862 strncat(metrics_notification, " TRUE", 5);
12863 else
12864 strncat(metrics_notification, " FALSE", 6);
12865
12866 wrqu.data.pointer = metrics_notification;
12867 wrqu.data.length = strlen(metrics_notification);
12868
12869 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12870
12871 EXIT();
12872
12873 return VOS_STATUS_SUCCESS;
12874}
12875
12876/*
12877 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
12878 * 802.11r/LFR metrics reporting function to report handover initiation
12879 *
12880 */
12881VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
12882 tCsrRoamInfo *pRoamInfo)
12883{
12884 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12885 union iwreq_data wrqu;
12886
12887 ENTER();
12888
12889 if (NULL == pAdapter)
12890 {
12891 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12892 return VOS_STATUS_E_FAILURE;
12893 }
12894
12895 /* create the event */
12896 memset(&wrqu, 0, sizeof(wrqu));
12897 memset(metrics_notification, 0, sizeof(metrics_notification));
12898
12899 wrqu.data.pointer = metrics_notification;
12900 wrqu.data.length = scnprintf(metrics_notification,
12901 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
12902 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12903
12904 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12905
12906 EXIT();
12907
12908 return VOS_STATUS_SUCCESS;
12909}
12910#endif
12911
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012912
12913/**
12914 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
12915 * @scan_req: scan request to be checked
12916 *
12917 * Return: true or false
12918 */
12919#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
12920static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
12921 cfg80211_scan_request
12922 *scan_req)
12923{
12924 if (!scan_req || !scan_req->wiphy) {
12925 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
12926 return false;
12927 }
12928 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
12929 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
12930 return false;
12931 }
12932 return true;
12933}
12934#else
12935static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
12936 cfg80211_scan_request
12937 *scan_req)
12938{
12939 if (!scan_req || !scan_req->wiphy) {
12940 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
12941 return false;
12942 }
12943 return true;
12944}
12945#endif
12946
12947
Jeff Johnson295189b2012-06-20 16:38:30 -070012948/*
12949 * FUNCTION: hdd_cfg80211_scan_done_callback
12950 * scanning callback function, called after finishing scan
12951 *
12952 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012953static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070012954 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
12955{
12956 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012957 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012958 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012959 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012960 struct cfg80211_scan_request *req = NULL;
12961 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012962 bool aborted = false;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012963#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12964 bool iface_down = false;
12965#endif
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012966 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012967 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012968 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012969
12970 ENTER();
12971
c_manjee1b4ab9a2016-10-26 11:36:55 +053012972 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
12973 !pAdapter->dev) {
12974 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
12975 return 0;
12976 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012977 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053012978 if (NULL == pHddCtx) {
12979 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012980 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012981 }
12982
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012983#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12984 if (!(pAdapter->dev->flags & IFF_UP))
12985 {
12986 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012987 iface_down = true;
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012988 }
12989#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012990 pScanInfo = &pHddCtx->scan_info;
12991
Jeff Johnson295189b2012-06-20 16:38:30 -070012992 hddLog(VOS_TRACE_LEVEL_INFO,
12993 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080012994 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012995 __func__, halHandle, pContext, (int) scanId, (int) status);
12996
Kiet Lamac06e2c2013-10-23 16:25:07 +053012997 pScanInfo->mScanPendingCounter = 0;
12998
Jeff Johnson295189b2012-06-20 16:38:30 -070012999 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013000 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070013001 &pScanInfo->scan_req_completion_event,
13002 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013003 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070013004 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013005 hddLog(VOS_TRACE_LEVEL_ERROR,
13006 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070013007 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013008 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013009 }
13010
Yue Maef608272013-04-08 23:09:17 -070013011 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070013012 {
13013 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070013014 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013015 }
13016
13017 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013018 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070013019 {
13020 hddLog(VOS_TRACE_LEVEL_INFO,
13021 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080013022 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070013023 (int) scanId);
13024 }
13025
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013026#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013027 if (!iface_down)
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013028#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013029 {
13030 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
13031 pAdapter);
13032 if (0 > ret)
13033 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053013034 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013035
Jeff Johnson295189b2012-06-20 16:38:30 -070013036 /* If any client wait scan result through WEXT
13037 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013038 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070013039 {
13040 /* The other scan request waiting for current scan finish
13041 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013042 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013043 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013044 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070013045 }
13046 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013047 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070013048 {
13049 struct net_device *dev = pAdapter->dev;
13050 union iwreq_data wrqu;
13051 int we_event;
13052 char *msg;
13053
13054 memset(&wrqu, '\0', sizeof(wrqu));
13055 we_event = SIOCGIWSCAN;
13056 msg = NULL;
13057 wireless_send_event(dev, we_event, &wrqu, msg);
13058 }
13059 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013060 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013061
13062 /* Get the Scan Req */
13063 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053013064 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013065
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013066 /* Scan is no longer pending */
13067 pScanInfo->mScanPending = VOS_FALSE;
13068
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013069 if (!wlan_hdd_cfg80211_validate_scan_req(req))
Jeff Johnson295189b2012-06-20 16:38:30 -070013070 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053013071#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13072 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
13073 iface_down ? "up" : "down");
13074#endif
13075
13076 if (pAdapter->dev) {
13077 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
13078 pAdapter->dev->name);
13079 }
mukul sharmae7041822015-12-03 15:09:21 +053013080 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070013081 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070013082 }
13083
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013084 /* last_scan_timestamp is used to decide if new scan
13085 * is needed or not on station interface. If last station
13086 * scan time and new station scan time is less then
13087 * last_scan_timestamp ; driver will return cached scan.
13088 */
13089 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
13090 {
13091 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
13092
13093 if ( req->n_channels )
13094 {
13095 for (i = 0; i < req->n_channels ; i++ )
13096 {
13097 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
13098 }
13099 /* store no of channel scanned */
13100 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
13101 }
13102
13103 }
13104
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070013105 /*
13106 * cfg80211_scan_done informing NL80211 about completion
13107 * of scanning
13108 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013109 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
13110 {
13111 aborted = true;
13112 }
mukul sharmae7041822015-12-03 15:09:21 +053013113
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013114#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13115 if (!iface_down)
13116#endif
13117 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053013118
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013119 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070013120
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013121allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013122 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
13123 ) && (pHddCtx->spoofMacAddr.isEnabled
13124 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053013125 /* Generate new random mac addr for next scan */
13126 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053013127
13128 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
13129 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053013130 }
13131
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013132 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013133 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013134
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013135 /* Acquire wakelock to handle the case where APP's tries to suspend
13136 * immediatly after the driver gets connect request(i.e after scan)
13137 * from supplicant, this result in app's is suspending and not able
13138 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013139 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070013140
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013141#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
13142 if (!iface_down)
13143#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013144#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013145 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070013146#endif
13147
Jeff Johnson295189b2012-06-20 16:38:30 -070013148 EXIT();
13149 return 0;
13150}
13151
13152/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053013153 * FUNCTION: hdd_isConnectionInProgress
13154 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013155 *
13156 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013157v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
13158 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013159{
13160 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13161 hdd_station_ctx_t *pHddStaCtx = NULL;
13162 hdd_adapter_t *pAdapter = NULL;
13163 VOS_STATUS status = 0;
13164 v_U8_t staId = 0;
13165 v_U8_t *staMac = NULL;
13166
13167 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13168
13169 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13170 {
13171 pAdapter = pAdapterNode->pAdapter;
13172
13173 if( pAdapter )
13174 {
13175 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013176 "%s: Adapter with device mode %s (%d) exists",
13177 __func__, hdd_device_modetoString(pAdapter->device_mode),
13178 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013179 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053013180 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13181 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
13182 (eConnectionState_Connecting ==
13183 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13184 {
13185 hddLog(VOS_TRACE_LEVEL_ERROR,
13186 "%s: %p(%d) Connection is in progress", __func__,
13187 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013188 if (session_id && reason)
13189 {
13190 *session_id = pAdapter->sessionId;
13191 *reason = eHDD_CONNECTION_IN_PROGRESS;
13192 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013193 return VOS_TRUE;
13194 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013195 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053013196 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013197 {
13198 hddLog(VOS_TRACE_LEVEL_ERROR,
13199 "%s: %p(%d) Reassociation is in progress", __func__,
13200 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013201 if (session_id && reason)
13202 {
13203 *session_id = pAdapter->sessionId;
13204 *reason = eHDD_REASSOC_IN_PROGRESS;
13205 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013206 return VOS_TRUE;
13207 }
13208 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013209 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13210 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013211 {
13212 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13213 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013214 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013215 {
13216 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
13217 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080013218 "%s: client " MAC_ADDRESS_STR
13219 " is in the middle of WPS/EAPOL exchange.", __func__,
13220 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013221 if (session_id && reason)
13222 {
13223 *session_id = pAdapter->sessionId;
13224 *reason = eHDD_EAPOL_IN_PROGRESS;
13225 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013226 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013227 }
13228 }
13229 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
13230 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
13231 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013232 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13233 ptSapContext pSapCtx = NULL;
13234 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13235 if(pSapCtx == NULL){
13236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13237 FL("psapCtx is NULL"));
13238 return VOS_FALSE;
13239 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013240 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
13241 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013242 if ((pSapCtx->aStaInfo[staId].isUsed) &&
13243 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013244 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013245 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013246
13247 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080013248 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
13249 "middle of WPS/EAPOL exchange.", __func__,
13250 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013251 if (session_id && reason)
13252 {
13253 *session_id = pAdapter->sessionId;
13254 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
13255 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013256 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013257 }
13258 }
13259 }
13260 }
13261 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13262 pAdapterNode = pNext;
13263 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053013264 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013265}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013266
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013267/**
13268 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
13269 * to the Scan request
13270 * @scanRequest: Pointer to the csr scan request
13271 * @request: Pointer to the scan request from supplicant
13272 *
13273 * Return: None
13274 */
13275#ifdef CFG80211_SCAN_BSSID
13276static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13277 struct cfg80211_scan_request *request)
13278{
13279 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
13280}
13281#else
13282static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
13283 struct cfg80211_scan_request *request)
13284{
13285}
13286#endif
13287
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013288/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013289 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070013290 * this scan respond to scan trigger and update cfg80211 scan database
13291 * later, scan dump command can be used to recieve scan results
13292 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013293int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013294#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13295 struct net_device *dev,
13296#endif
13297 struct cfg80211_scan_request *request)
13298{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013299 hdd_adapter_t *pAdapter = NULL;
13300 hdd_context_t *pHddCtx = NULL;
13301 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013302 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013303 tCsrScanRequest scanRequest;
13304 tANI_U8 *channelList = NULL, i;
13305 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013306 int status;
13307 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013308 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013309 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053013310 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013311 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013312 v_U8_t curr_session_id;
13313 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070013314
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013315#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
13316 struct net_device *dev = NULL;
13317 if (NULL == request)
13318 {
13319 hddLog(VOS_TRACE_LEVEL_ERROR,
13320 "%s: scan req param null", __func__);
13321 return -EINVAL;
13322 }
13323 dev = request->wdev->netdev;
13324#endif
13325
13326 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13327 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
13328 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13329
Jeff Johnson295189b2012-06-20 16:38:30 -070013330 ENTER();
13331
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013332 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13333 __func__, hdd_device_modetoString(pAdapter->device_mode),
13334 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013335
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013336 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013337 if (0 != status)
13338 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013339 return status;
13340 }
13341
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013342 if (NULL == pwextBuf)
13343 {
13344 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
13345 __func__);
13346 return -EIO;
13347 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013348 cfg_param = pHddCtx->cfg_ini;
13349 pScanInfo = &pHddCtx->scan_info;
13350
Jeff Johnson295189b2012-06-20 16:38:30 -070013351#ifdef WLAN_BTAMP_FEATURE
13352 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013353 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070013354 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013355 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013356 "%s: No scanning when AMP is on", __func__);
13357 return -EOPNOTSUPP;
13358 }
13359#endif
13360 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013361 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013362 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013363 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013364 "%s: Not scanning on device_mode = %s (%d)",
13365 __func__, hdd_device_modetoString(pAdapter->device_mode),
13366 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013367 return -EOPNOTSUPP;
13368 }
13369
13370 if (TRUE == pScanInfo->mScanPending)
13371 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013372 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
13373 {
13374 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
13375 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013376 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013377 }
13378
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053013379 // Don't allow scan if PNO scan is going on.
13380 if (pHddCtx->isPnoEnable)
13381 {
13382 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13383 FL("pno scan in progress"));
13384 return -EBUSY;
13385 }
13386
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013387 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070013388 //Channel and action frame is pending
13389 //Otherwise Cancel Remain On Channel and allow Scan
13390 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013391 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070013392 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013393 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070013394 return -EBUSY;
13395 }
13396
Jeff Johnson295189b2012-06-20 16:38:30 -070013397 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
13398 {
13399 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080013400 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013401 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013402 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013403 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
13404 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013405 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013406 "%s: MAX TM Level Scan not allowed", __func__);
13407 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013408 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013409 }
13410 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
13411
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013412 /* Check if scan is allowed at this point of time.
13413 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053013414 if (TRUE == pHddCtx->btCoexModeSet)
13415 {
13416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13417 FL("BTCoex Mode operation in progress"));
13418 return -EBUSY;
13419 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013420 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013421 {
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013422 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Scan not allowed"));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013423 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
13424 pHddCtx->last_scan_reject_reason != curr_reason ||
13425 !pHddCtx->last_scan_reject_timestamp)
13426 {
13427 pHddCtx->last_scan_reject_session_id = curr_session_id;
13428 pHddCtx->last_scan_reject_reason = curr_reason;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053013429 pHddCtx->last_scan_reject_timestamp = jiffies_to_msecs(jiffies);
Abhishek Singhe4b12562017-06-20 16:53:39 +053013430 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013431 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053013432 else
13433 {
13434 pHddCtx->scan_reject_cnt++;
13435
13436 hddLog(LOGE, FL("Reject cnt %d time delta %lu ms"), pHddCtx->scan_reject_cnt,
13437 (jiffies_to_msecs(jiffies) -
13438 pHddCtx->last_scan_reject_timestamp));
13439
13440 if ((pHddCtx->scan_reject_cnt >=
13441 SCAN_REJECT_THRESHOLD) &&
13442 (jiffies_to_msecs(jiffies) -
13443 pHddCtx->last_scan_reject_timestamp) >=
13444 SCAN_REJECT_THRESHOLD_TIME)
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013445 {
13446 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053013447 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013448 if (pHddCtx->cfg_ini->enableFatalEvent)
13449 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
13450 WLAN_LOG_INDICATOR_HOST_DRIVER,
13451 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
13452 FALSE, FALSE);
13453 else
13454 {
13455 hddLog(LOGE, FL("Triggering SSR"));
13456 vos_wlanRestart();
13457 }
13458 }
13459 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013460 return -EBUSY;
13461 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013462 pHddCtx->last_scan_reject_timestamp = 0;
13463 pHddCtx->last_scan_reject_session_id = 0xFF;
13464 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053013465 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013466
Jeff Johnson295189b2012-06-20 16:38:30 -070013467 vos_mem_zero( &scanRequest, sizeof(scanRequest));
13468
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013469 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
13470 * Becasue of this, driver is assuming that this is not wildcard scan and so
13471 * is not aging out the scan results.
13472 */
13473 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070013474 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013475 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013476 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013477
13478 if ((request->ssids) && (0 < request->n_ssids))
13479 {
13480 tCsrSSIDInfo *SsidInfo;
13481 int j;
13482 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
13483 /* Allocate num_ssid tCsrSSIDInfo structure */
13484 SsidInfo = scanRequest.SSIDs.SSIDList =
13485 ( tCsrSSIDInfo *)vos_mem_malloc(
13486 request->n_ssids*sizeof(tCsrSSIDInfo));
13487
13488 if(NULL == scanRequest.SSIDs.SSIDList)
13489 {
13490 hddLog(VOS_TRACE_LEVEL_ERROR,
13491 "%s: memory alloc failed SSIDInfo buffer", __func__);
13492 return -ENOMEM;
13493 }
13494
13495 /* copy all the ssid's and their length */
13496 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
13497 {
13498 /* get the ssid length */
13499 SsidInfo->SSID.length = request->ssids[j].ssid_len;
13500 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
13501 SsidInfo->SSID.length);
13502 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
13503 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
13504 j, SsidInfo->SSID.ssId);
13505 }
13506 /* set the scan type to active */
13507 scanRequest.scanType = eSIR_ACTIVE_SCAN;
13508 }
13509 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013510 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013511 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13512 TRACE_CODE_HDD_CFG80211_SCAN,
13513 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070013514 /* set the scan type to active */
13515 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070013516 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013517 else
13518 {
13519 /*Set the scan type to default type, in this case it is ACTIVE*/
13520 scanRequest.scanType = pScanInfo->scan_mode;
13521 }
13522 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
13523 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070013524
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013525 csr_scan_request_assign_bssid(&scanRequest, request);
13526
Jeff Johnson295189b2012-06-20 16:38:30 -070013527 /* set BSSType to default type */
13528 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
13529
13530 /*TODO: scan the requested channels only*/
13531
13532 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013533 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070013534 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013535 hddLog(VOS_TRACE_LEVEL_WARN,
13536 "No of Scan Channels exceeded limit: %d", request->n_channels);
13537 request->n_channels = MAX_CHANNEL;
13538 }
13539
13540 hddLog(VOS_TRACE_LEVEL_INFO,
13541 "No of Scan Channels: %d", request->n_channels);
13542
13543
13544 if( request->n_channels )
13545 {
13546 char chList [(request->n_channels*5)+1];
13547 int len;
13548 channelList = vos_mem_malloc( request->n_channels );
13549 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053013550 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013551 hddLog(VOS_TRACE_LEVEL_ERROR,
13552 "%s: memory alloc failed channelList", __func__);
13553 status = -ENOMEM;
13554 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053013555 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013556
13557 for( i = 0, len = 0; i < request->n_channels ; i++ )
13558 {
13559 channelList[i] = request->channels[i]->hw_value;
13560 len += snprintf(chList+len, 5, "%d ", channelList[i]);
13561 }
13562
Nirav Shah20ac06f2013-12-12 18:14:06 +053013563 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013564 "Channel-List: %s ", chList);
13565 }
c_hpothu53512302014-04-15 18:49:53 +053013566
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013567 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
13568 scanRequest.ChannelInfo.ChannelList = channelList;
13569
13570 /* set requestType to full scan */
13571 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
13572
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013573 /* if there is back to back scan happening in driver with in
13574 * nDeferScanTimeInterval interval driver should defer new scan request
13575 * and should provide last cached scan results instead of new channel list.
13576 * This rule is not applicable if scan is p2p scan.
13577 * This condition will work only in case when last request no of channels
13578 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053013579 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053013580 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013581 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013582
Sushant Kaushik86592172015-04-27 16:35:03 +053013583 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
13584 /* if wps ie is NULL , then only defer scan */
13585 if ( pWpsIe == NULL &&
13586 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053013587 {
13588 if ( pScanInfo->last_scan_timestamp !=0 &&
13589 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
13590 {
13591 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
13592 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
13593 vos_mem_compare(pScanInfo->last_scan_channelList,
13594 channelList, pScanInfo->last_scan_numChannels))
13595 {
13596 hddLog(VOS_TRACE_LEVEL_WARN,
13597 " New and old station scan time differ is less then %u",
13598 pHddCtx->cfg_ini->nDeferScanTimeInterval);
13599
13600 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013601 pAdapter);
13602
Agarwal Ashish57e84372014-12-05 18:26:53 +053013603 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013604 "Return old cached scan as all channels and no of channels are same");
13605
Agarwal Ashish57e84372014-12-05 18:26:53 +053013606 if (0 > ret)
13607 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013608
Agarwal Ashish57e84372014-12-05 18:26:53 +053013609 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013610
13611 status = eHAL_STATUS_SUCCESS;
13612 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053013613 }
13614 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013615 }
13616
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013617 /* Flush the scan results(only p2p beacons) for STA scan and P2P
13618 * search (Flush on both full scan and social scan but not on single
13619 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
13620 */
13621
13622 /* Supplicant does single channel scan after 8-way handshake
13623 * and in that case driver shoudnt flush scan results. If
13624 * driver flushes the scan results here and unfortunately if
13625 * the AP doesnt respond to our probe req then association
13626 * fails which is not desired
13627 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013628 if ((request->n_ssids == 1)
13629 && (request->ssids != NULL)
13630 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
13631 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013632
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013633 if( is_p2p_scan ||
13634 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013635 {
13636 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
13637 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
13638 pAdapter->sessionId );
13639 }
13640
13641 if( request->ie_len )
13642 {
13643 /* save this for future association (join requires this) */
13644 /*TODO: Array needs to be converted to dynamic allocation,
13645 * as multiple ie.s can be sent in cfg80211_scan_request structure
13646 * CR 597966
13647 */
13648 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
13649 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
13650 pScanInfo->scanAddIE.length = request->ie_len;
13651
13652 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13653 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13654 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013655 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013656 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070013657 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013658 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
13659 memcpy( pwextBuf->roamProfile.addIEScan,
13660 request->ie, request->ie_len);
13661 }
13662 else
13663 {
13664 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
13665 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013666 }
13667
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013668 }
13669 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
13670 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
13671
13672 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
13673 request->ie_len);
13674 if (pP2pIe != NULL)
13675 {
13676#ifdef WLAN_FEATURE_P2P_DEBUG
13677 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
13678 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
13679 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053013680 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013681 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
13682 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13683 "Go nego completed to Connection is started");
13684 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13685 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053013686 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013687 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
13688 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013689 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013690 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
13691 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13692 "Disconnected state to Connection is started");
13693 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13694 "for 4way Handshake");
13695 }
13696#endif
13697
13698 /* no_cck will be set during p2p find to disable 11b rates */
13699 if(TRUE == request->no_cck)
13700 {
13701 hddLog(VOS_TRACE_LEVEL_INFO,
13702 "%s: This is a P2P Search", __func__);
13703 scanRequest.p2pSearch = 1;
13704
13705 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053013706 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013707 /* set requestType to P2P Discovery */
13708 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
13709 }
13710
13711 /*
13712 Skip Dfs Channel in case of P2P Search
13713 if it is set in ini file
13714 */
13715 if(cfg_param->skipDfsChnlInP2pSearch)
13716 {
13717 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013718 }
13719 else
13720 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013721 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013722 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013723
Agarwal Ashish4f616132013-12-30 23:32:50 +053013724 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013725 }
13726 }
13727
13728 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
13729
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013730#ifdef FEATURE_WLAN_TDLS
13731 /* if tdls disagree scan right now, return immediately.
13732 tdls will schedule the scan when scan is allowed. (return SUCCESS)
13733 or will reject the scan if any TDLS is in progress. (return -EBUSY)
13734 */
13735 status = wlan_hdd_tdls_scan_callback (pAdapter,
13736 wiphy,
13737#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13738 dev,
13739#endif
13740 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013741 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013742 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053013743 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013744 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
13745 "scan rejected %d", __func__, status);
13746 else
13747 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
13748 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013749 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053013750 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013751 }
13752#endif
13753
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013754 /* acquire the wakelock to avoid the apps suspend during the scan. To
13755 * address the following issues.
13756 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
13757 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
13758 * for long time, this result in apps running at full power for long time.
13759 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
13760 * be stuck in full power because of resume BMPS
13761 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013762 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013763
Nirav Shah20ac06f2013-12-12 18:14:06 +053013764 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
13765 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013766 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
13767 scanRequest.requestType, scanRequest.scanType,
13768 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053013769 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
13770
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013771 if (pHddCtx->spoofMacAddr.isEnabled &&
13772 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053013773 {
13774 hddLog(VOS_TRACE_LEVEL_INFO,
13775 "%s: MAC Spoofing enabled for current scan", __func__);
13776 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
13777 * to fill TxBds for probe request during current scan
13778 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013779 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053013780 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013781
13782 if(status != VOS_STATUS_SUCCESS)
13783 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013784 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013785 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053013786#ifdef FEATURE_WLAN_TDLS
13787 wlan_hdd_tdls_scan_done_callback(pAdapter);
13788#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013789 goto free_mem;
13790 }
Siddharth Bhal76972212014-10-15 16:22:51 +053013791 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013792 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070013793 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013794 pAdapter->sessionId, &scanRequest, &scanId,
13795 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070013796
Jeff Johnson295189b2012-06-20 16:38:30 -070013797 if (eHAL_STATUS_SUCCESS != status)
13798 {
13799 hddLog(VOS_TRACE_LEVEL_ERROR,
13800 "%s: sme_ScanRequest returned error %d", __func__, status);
13801 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013802 if(eHAL_STATUS_RESOURCES == status)
13803 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013804 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
13805 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013806 status = -EBUSY;
13807 } else {
13808 status = -EIO;
13809 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013810 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013811
13812#ifdef FEATURE_WLAN_TDLS
13813 wlan_hdd_tdls_scan_done_callback(pAdapter);
13814#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013815 goto free_mem;
13816 }
13817
13818 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013819 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013820 pAdapter->request = request;
13821 pScanInfo->scanId = scanId;
13822
13823 complete(&pScanInfo->scan_req_completion_event);
13824
13825free_mem:
13826 if( scanRequest.SSIDs.SSIDList )
13827 {
13828 vos_mem_free(scanRequest.SSIDs.SSIDList);
13829 }
13830
13831 if( channelList )
13832 vos_mem_free( channelList );
13833
13834 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013835 return status;
13836}
13837
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013838int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13839#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13840 struct net_device *dev,
13841#endif
13842 struct cfg80211_scan_request *request)
13843{
13844 int ret;
13845
13846 vos_ssr_protect(__func__);
13847 ret = __wlan_hdd_cfg80211_scan(wiphy,
13848#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13849 dev,
13850#endif
13851 request);
13852 vos_ssr_unprotect(__func__);
13853
13854 return ret;
13855}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013856
13857void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13858{
13859 v_U8_t iniDot11Mode =
13860 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13861 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13862
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013863 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13864 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013865 switch ( iniDot11Mode )
13866 {
13867 case eHDD_DOT11_MODE_AUTO:
13868 case eHDD_DOT11_MODE_11ac:
13869 case eHDD_DOT11_MODE_11ac_ONLY:
13870#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013871 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13872 sme_IsFeatureSupportedByFW(DOT11AC) )
13873 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13874 else
13875 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013876#else
13877 hddDot11Mode = eHDD_DOT11_MODE_11n;
13878#endif
13879 break;
13880 case eHDD_DOT11_MODE_11n:
13881 case eHDD_DOT11_MODE_11n_ONLY:
13882 hddDot11Mode = eHDD_DOT11_MODE_11n;
13883 break;
13884 default:
13885 hddDot11Mode = iniDot11Mode;
13886 break;
13887 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013888#ifdef WLAN_FEATURE_AP_HT40_24G
13889 if (operationChannel > SIR_11B_CHANNEL_END)
13890#endif
13891 {
13892 /* This call decides required channel bonding mode */
13893 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013894 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13895 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013896 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013897}
13898
Jeff Johnson295189b2012-06-20 16:38:30 -070013899/*
13900 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013901 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013902 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013903int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013904 const u8 *ssid, size_t ssid_len, const u8 *bssid,
13905 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070013906{
13907 int status = 0;
13908 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080013909 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013910 v_U32_t roamId;
13911 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070013912 eCsrAuthType RSNAuthType;
13913
13914 ENTER();
13915
13916 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080013917 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13918
13919 status = wlan_hdd_validate_context(pHddCtx);
13920 if (status)
13921 {
Yue Mae36e3552014-03-05 17:06:20 -080013922 return status;
13923 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013924
Jeff Johnson295189b2012-06-20 16:38:30 -070013925 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
13926 {
13927 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
13928 return -EINVAL;
13929 }
13930
Nitesh Shah9b066282017-06-06 18:05:52 +053013931 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
13932
Jeff Johnson295189b2012-06-20 16:38:30 -070013933 pRoamProfile = &pWextState->roamProfile;
13934
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013935 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070013936 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013937 hdd_station_ctx_t *pHddStaCtx;
13938 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053013939 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013940
Siddharth Bhalda0d1622015-04-24 15:47:49 +053013941 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
13942
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013943 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070013944 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
13945 {
13946 /*QoS not enabled in cfg file*/
13947 pRoamProfile->uapsd_mask = 0;
13948 }
13949 else
13950 {
13951 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013952 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070013953 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
13954 }
13955
13956 pRoamProfile->SSIDs.numOfSSIDs = 1;
13957 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
13958 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013959 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070013960 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
13961 ssid, ssid_len);
13962
Abhishek Singhb3e376c2017-01-04 15:27:13 +053013963 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
13964 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
13965
Jeff Johnson295189b2012-06-20 16:38:30 -070013966 if (bssid)
13967 {
13968 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053013969 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013970 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013971 /* Save BSSID in seperate variable as well, as RoamProfile
13972 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070013973 case of join failure we should send valid BSSID to supplicant
13974 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053013975 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013976 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053013977
Jeff Johnson295189b2012-06-20 16:38:30 -070013978 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053013979 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070013980 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053013981 /* Store bssid_hint to use in the scan filter. */
13982 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
13983 WNI_CFG_BSSID_LEN);
13984 /*
13985 * Save BSSID in seperate variable as well, as RoamProfile
13986 * BSSID is getting zeroed out in the association process. And in
13987 * case of join failure we should send valid BSSID to supplicant
13988 */
13989 vos_mem_copy(pWextState->req_bssId, bssid_hint,
13990 WNI_CFG_BSSID_LEN);
13991 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
13992 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070013993 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013994
Abhishek Singhb3e376c2017-01-04 15:27:13 +053013995
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013996 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
13997 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013998 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
13999 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014000 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014001 /*set gen ie*/
14002 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
14003 /*set auth*/
14004 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
14005 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014006#ifdef FEATURE_WLAN_WAPI
14007 if (pAdapter->wapi_info.nWapiMode)
14008 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014009 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014010 switch (pAdapter->wapi_info.wapiAuthMode)
14011 {
14012 case WAPI_AUTH_MODE_PSK:
14013 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014014 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014015 pAdapter->wapi_info.wapiAuthMode);
14016 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
14017 break;
14018 }
14019 case WAPI_AUTH_MODE_CERT:
14020 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014021 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014022 pAdapter->wapi_info.wapiAuthMode);
14023 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
14024 break;
14025 }
14026 } // End of switch
14027 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
14028 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
14029 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014030 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014031 pRoamProfile->AuthType.numEntries = 1;
14032 pRoamProfile->EncryptionType.numEntries = 1;
14033 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14034 pRoamProfile->mcEncryptionType.numEntries = 1;
14035 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
14036 }
14037 }
14038#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014039#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014040 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014041 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14042 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
14043 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014044 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
14045 sizeof (tSirGtkOffloadParams));
14046 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014047 }
14048#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014049 pRoamProfile->csrPersona = pAdapter->device_mode;
14050
Jeff Johnson32d95a32012-09-10 13:15:23 -070014051 if( operatingChannel )
14052 {
14053 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
14054 pRoamProfile->ChannelInfo.numOfChannels = 1;
14055 }
Chet Lanctot186b5732013-03-18 10:26:30 -070014056 else
14057 {
14058 pRoamProfile->ChannelInfo.ChannelList = NULL;
14059 pRoamProfile->ChannelInfo.numOfChannels = 0;
14060 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014061 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
14062 {
14063 hdd_select_cbmode(pAdapter,operatingChannel);
14064 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014065
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014066 /*
14067 * Change conn_state to connecting before sme_RoamConnect(),
14068 * because sme_RoamConnect() has a direct path to call
14069 * hdd_smeRoamCallback(), which will change the conn_state
14070 * If direct path, conn_state will be accordingly changed
14071 * to NotConnected or Associated by either
14072 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
14073 * in sme_RoamCallback()
14074 * if sme_RomConnect is to be queued,
14075 * Connecting state will remain until it is completed.
14076 * If connection state is not changed,
14077 * connection state will remain in eConnectionState_NotConnected state.
14078 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
14079 * if conn state is eConnectionState_NotConnected.
14080 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
14081 * informed of connect result indication which is an issue.
14082 */
14083
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014084 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14085 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053014086 {
14087 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014088 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014089 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
14090 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053014091 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014092 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014093 pAdapter->sessionId, pRoamProfile, &roamId);
14094
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053014095 if ((eHAL_STATUS_SUCCESS != status) &&
14096 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
14097 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014098
14099 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053014100 hddLog(VOS_TRACE_LEVEL_ERROR,
14101 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
14102 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014103 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014104 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080014105 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053014106 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080014107
14108 pRoamProfile->ChannelInfo.ChannelList = NULL;
14109 pRoamProfile->ChannelInfo.numOfChannels = 0;
14110
Jeff Johnson295189b2012-06-20 16:38:30 -070014111 }
14112 else
14113 {
14114 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
14115 return -EINVAL;
14116 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080014117 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014118 return status;
14119}
14120
14121/*
14122 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
14123 * This function is used to set the authentication type (OPEN/SHARED).
14124 *
14125 */
14126static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
14127 enum nl80211_auth_type auth_type)
14128{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014129 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014130 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14131
14132 ENTER();
14133
14134 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014135 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070014136 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014137 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014138 hddLog(VOS_TRACE_LEVEL_INFO,
14139 "%s: set authentication type to AUTOSWITCH", __func__);
14140 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
14141 break;
14142
14143 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014144#ifdef WLAN_FEATURE_VOWIFI_11R
14145 case NL80211_AUTHTYPE_FT:
14146#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014147 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014148 "%s: set authentication type to OPEN", __func__);
14149 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
14150 break;
14151
14152 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014153 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014154 "%s: set authentication type to SHARED", __func__);
14155 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
14156 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014157#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014158 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014159 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070014160 "%s: set authentication type to CCKM WPA", __func__);
14161 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
14162 break;
14163#endif
14164
14165
14166 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014167 hddLog(VOS_TRACE_LEVEL_ERROR,
14168 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014169 auth_type);
14170 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
14171 return -EINVAL;
14172 }
14173
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014174 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014175 pHddStaCtx->conn_info.authType;
14176 return 0;
14177}
14178
14179/*
14180 * FUNCTION: wlan_hdd_set_akm_suite
14181 * This function is used to set the key mgmt type(PSK/8021x).
14182 *
14183 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014184static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014185 u32 key_mgmt
14186 )
14187{
14188 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14189 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053014190 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014191#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053014192#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014193#endif
14194#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053014195#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053014196#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014197 /*set key mgmt type*/
14198 switch(key_mgmt)
14199 {
14200 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053014201 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014202#ifdef WLAN_FEATURE_VOWIFI_11R
14203 case WLAN_AKM_SUITE_FT_PSK:
14204#endif
14205 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070014206 __func__);
14207 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
14208 break;
14209
14210 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053014211 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014212#ifdef WLAN_FEATURE_VOWIFI_11R
14213 case WLAN_AKM_SUITE_FT_8021X:
14214#endif
14215 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070014216 __func__);
14217 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14218 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014219#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014220#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
14221#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
14222 case WLAN_AKM_SUITE_CCKM:
14223 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
14224 __func__);
14225 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
14226 break;
14227#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070014228#ifndef WLAN_AKM_SUITE_OSEN
14229#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
14230 case WLAN_AKM_SUITE_OSEN:
14231 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
14232 __func__);
14233 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
14234 break;
14235#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014236
14237 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014238 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014239 __func__, key_mgmt);
14240 return -EINVAL;
14241
14242 }
14243 return 0;
14244}
14245
14246/*
14247 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014248 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070014249 * (NONE/WEP40/WEP104/TKIP/CCMP).
14250 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014251static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
14252 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070014253 bool ucast
14254 )
14255{
14256 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014257 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014258 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14259
14260 ENTER();
14261
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014262 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014263 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014264 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070014265 __func__, cipher);
14266 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14267 }
14268 else
14269 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014270
Jeff Johnson295189b2012-06-20 16:38:30 -070014271 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014272 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070014273 {
14274 case IW_AUTH_CIPHER_NONE:
14275 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14276 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014277
Jeff Johnson295189b2012-06-20 16:38:30 -070014278 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014279 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070014280 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014281
Jeff Johnson295189b2012-06-20 16:38:30 -070014282 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053014283 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070014284 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014285
Jeff Johnson295189b2012-06-20 16:38:30 -070014286 case WLAN_CIPHER_SUITE_TKIP:
14287 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
14288 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014289
Jeff Johnson295189b2012-06-20 16:38:30 -070014290 case WLAN_CIPHER_SUITE_CCMP:
14291 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14292 break;
14293#ifdef FEATURE_WLAN_WAPI
14294 case WLAN_CIPHER_SUITE_SMS4:
14295 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
14296 break;
14297#endif
14298
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080014299#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070014300 case WLAN_CIPHER_SUITE_KRK:
14301 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
14302 break;
14303#endif
14304 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014305 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014306 __func__, cipher);
14307 return -EOPNOTSUPP;
14308 }
14309 }
14310
14311 if (ucast)
14312 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014313 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014314 __func__, encryptionType);
14315 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14316 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014317 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014318 encryptionType;
14319 }
14320 else
14321 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014322 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014323 __func__, encryptionType);
14324 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
14325 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
14326 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
14327 }
14328
14329 return 0;
14330}
14331
14332
14333/*
14334 * FUNCTION: wlan_hdd_cfg80211_set_ie
14335 * This function is used to parse WPA/RSN IE's.
14336 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014337int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014338#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14339 const u8 *ie,
14340#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014341 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014342#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014343 size_t ie_len
14344 )
14345{
14346 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014347#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14348 const u8 *genie = ie;
14349#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014350 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014351#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014352 v_U16_t remLen = ie_len;
14353#ifdef FEATURE_WLAN_WAPI
14354 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
14355 u16 *tmp;
14356 v_U16_t akmsuiteCount;
14357 int *akmlist;
14358#endif
14359 ENTER();
14360
14361 /* clear previous assocAddIE */
14362 pWextState->assocAddIE.length = 0;
14363 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014364 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014365
14366 while (remLen >= 2)
14367 {
14368 v_U16_t eLen = 0;
14369 v_U8_t elementId;
14370 elementId = *genie++;
14371 eLen = *genie++;
14372 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014373
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053014374 /* Sanity check on eLen */
14375 if (eLen > remLen) {
14376 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
14377 __func__, eLen, elementId);
14378 VOS_ASSERT(0);
14379 return -EINVAL;
14380 }
14381
Arif Hussain6d2a3322013-11-17 19:50:10 -080014382 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070014383 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014384
14385 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070014386 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014387 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014388 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 -070014389 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014390 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014391 "%s: Invalid WPA IE", __func__);
14392 return -EINVAL;
14393 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014394 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070014395 {
14396 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014397 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014398 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014399
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014400 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014401 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014402 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
14403 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014404 VOS_ASSERT(0);
14405 return -ENOMEM;
14406 }
14407 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14408 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14409 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014410
Jeff Johnson295189b2012-06-20 16:38:30 -070014411 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
14412 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14413 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14414 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014415 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
14416 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053014417 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
14418 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
14419 __func__, eLen);
14420 VOS_ASSERT(0);
14421 return -EINVAL;
14422 }
14423
Jeff Johnson295189b2012-06-20 16:38:30 -070014424 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
14425 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14426 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
14427 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
14428 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
14429 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014430 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053014431 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070014432 {
14433 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014434 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014435 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014436
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014437 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014438 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014439 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14440 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014441 VOS_ASSERT(0);
14442 return -ENOMEM;
14443 }
14444 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14445 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14446 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014447
Jeff Johnson295189b2012-06-20 16:38:30 -070014448 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14449 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14450 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014451#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014452 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
14453 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014454 /*Consider WFD IE, only for P2P Client */
14455 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
14456 {
14457 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014458 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014459 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014460
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014461 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014462 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014463 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14464 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014465 VOS_ASSERT(0);
14466 return -ENOMEM;
14467 }
14468 // WFD IE is saved to Additional IE ; it should be accumulated to handle
14469 // WPS IE + P2P IE + WFD IE
14470 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14471 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014472
Jeff Johnson295189b2012-06-20 16:38:30 -070014473 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14474 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14475 }
14476#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014477 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014478 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014479 HS20_OUI_TYPE_SIZE)) )
14480 {
14481 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014482 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014483 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014484
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014485 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014486 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014487 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14488 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014489 VOS_ASSERT(0);
14490 return -ENOMEM;
14491 }
14492 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14493 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014494
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014495 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14496 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14497 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014498 /* Appending OSEN Information Element in Assiciation Request */
14499 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
14500 OSEN_OUI_TYPE_SIZE)) )
14501 {
14502 v_U16_t curAddIELen = pWextState->assocAddIE.length;
14503 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
14504 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014505
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014506 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014507 {
14508 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14509 "Need bigger buffer space");
14510 VOS_ASSERT(0);
14511 return -ENOMEM;
14512 }
14513 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14514 pWextState->assocAddIE.length += eLen + 2;
14515
14516 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
14517 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14518 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14519 }
14520
Abhishek Singh4322e622015-06-10 15:42:54 +053014521 /* Update only for WPA IE */
14522 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
14523 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014524
14525 /* populating as ADDIE in beacon frames */
14526 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014527 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014528 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
14529 {
14530 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14531 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
14532 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14533 {
14534 hddLog(LOGE,
14535 "Coldn't pass "
14536 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
14537 }
14538 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
14539 else
14540 hddLog(LOGE,
14541 "Could not pass on "
14542 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
14543
14544 /* IBSS mode doesn't contain params->proberesp_ies still
14545 beaconIE's need to be populated in probe response frames */
14546 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
14547 {
14548 u16 rem_probe_resp_ie_len = eLen + 2;
14549 u8 probe_rsp_ie_len[3] = {0};
14550 u8 counter = 0;
14551
14552 /* Check Probe Resp Length if it is greater then 255 then
14553 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
14554 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
14555 not able Store More then 255 bytes into One Variable */
14556
14557 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
14558 {
14559 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
14560 {
14561 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
14562 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
14563 }
14564 else
14565 {
14566 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
14567 rem_probe_resp_ie_len = 0;
14568 }
14569 }
14570
14571 rem_probe_resp_ie_len = 0;
14572
14573 if (probe_rsp_ie_len[0] > 0)
14574 {
14575 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14576 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
14577 (tANI_U8*)(genie - 2),
14578 probe_rsp_ie_len[0], NULL,
14579 eANI_BOOLEAN_FALSE)
14580 == eHAL_STATUS_FAILURE)
14581 {
14582 hddLog(LOGE,
14583 "Could not pass"
14584 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
14585 }
14586 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
14587 }
14588
14589 if (probe_rsp_ie_len[1] > 0)
14590 {
14591 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14592 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
14593 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14594 probe_rsp_ie_len[1], NULL,
14595 eANI_BOOLEAN_FALSE)
14596 == eHAL_STATUS_FAILURE)
14597 {
14598 hddLog(LOGE,
14599 "Could not pass"
14600 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
14601 }
14602 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
14603 }
14604
14605 if (probe_rsp_ie_len[2] > 0)
14606 {
14607 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14608 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
14609 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14610 probe_rsp_ie_len[2], NULL,
14611 eANI_BOOLEAN_FALSE)
14612 == eHAL_STATUS_FAILURE)
14613 {
14614 hddLog(LOGE,
14615 "Could not pass"
14616 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
14617 }
14618 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
14619 }
14620
14621 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14622 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
14623 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14624 {
14625 hddLog(LOGE,
14626 "Could not pass"
14627 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
14628 }
14629 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014630 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014631 break;
14632 case DOT11F_EID_RSN:
14633 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
14634 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14635 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
14636 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
14637 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
14638 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053014639
Abhishek Singhb16f3562016-01-20 11:08:32 +053014640 /* Appending extended capabilities with Interworking or
14641 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053014642 *
14643 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053014644 * interworkingService or bsstransition bit is set to 1.
14645 * Driver is only interested in interworkingService and
14646 * bsstransition capability from supplicant.
14647 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053014648 * required from supplicat, it needs to be handled while
14649 * sending Assoc Req in LIM.
14650 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014651 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014652 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014653 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014654 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014655 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014656
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014657 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014658 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014659 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14660 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014661 VOS_ASSERT(0);
14662 return -ENOMEM;
14663 }
14664 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14665 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014666
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014667 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14668 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14669 break;
14670 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014671#ifdef FEATURE_WLAN_WAPI
14672 case WLAN_EID_WAPI:
14673 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014674 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070014675 pAdapter->wapi_info.nWapiMode);
14676 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014677 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070014678 akmsuiteCount = WPA_GET_LE16(tmp);
14679 tmp = tmp + 1;
14680 akmlist = (int *)(tmp);
14681 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
14682 {
14683 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
14684 }
14685 else
14686 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014687 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070014688 VOS_ASSERT(0);
14689 return -EINVAL;
14690 }
14691
14692 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
14693 {
14694 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014695 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014696 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014697 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014698 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014699 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014700 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014701 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014702 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
14703 }
14704 break;
14705#endif
14706 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014707 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014708 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014709 /* when Unknown IE is received we should break and continue
14710 * to the next IE in the buffer instead we were returning
14711 * so changing this to break */
14712 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014713 }
14714 genie += eLen;
14715 remLen -= eLen;
14716 }
14717 EXIT();
14718 return 0;
14719}
14720
14721/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014722 * FUNCTION: hdd_isWPAIEPresent
14723 * Parse the received IE to find the WPA IE
14724 *
14725 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014726static bool hdd_isWPAIEPresent(
14727#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
14728 const u8 *ie,
14729#else
14730 u8 *ie,
14731#endif
14732 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014733{
14734 v_U8_t eLen = 0;
14735 v_U16_t remLen = ie_len;
14736 v_U8_t elementId = 0;
14737
14738 while (remLen >= 2)
14739 {
14740 elementId = *ie++;
14741 eLen = *ie++;
14742 remLen -= 2;
14743 if (eLen > remLen)
14744 {
14745 hddLog(VOS_TRACE_LEVEL_ERROR,
14746 "%s: IE length is wrong %d", __func__, eLen);
14747 return FALSE;
14748 }
14749 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
14750 {
14751 /* OUI - 0x00 0X50 0XF2
14752 WPA Information Element - 0x01
14753 WPA version - 0x01*/
14754 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
14755 return TRUE;
14756 }
14757 ie += eLen;
14758 remLen -= eLen;
14759 }
14760 return FALSE;
14761}
14762
14763/*
Jeff Johnson295189b2012-06-20 16:38:30 -070014764 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014765 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014766 * parameters during connect operation.
14767 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014768int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014769 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014770 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014771{
14772 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014773 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014774 ENTER();
14775
14776 /*set wpa version*/
14777 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
14778
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014779 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014780 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053014781 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014782 {
14783 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14784 }
14785 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
14786 {
14787 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14788 }
14789 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014790
14791 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014792 pWextState->wpaVersion);
14793
14794 /*set authentication type*/
14795 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
14796
14797 if (0 > status)
14798 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014799 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014800 "%s: failed to set authentication type ", __func__);
14801 return status;
14802 }
14803
14804 /*set key mgmt type*/
14805 if (req->crypto.n_akm_suites)
14806 {
14807 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
14808 if (0 > status)
14809 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014810 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070014811 __func__);
14812 return status;
14813 }
14814 }
14815
14816 /*set pairwise cipher type*/
14817 if (req->crypto.n_ciphers_pairwise)
14818 {
14819 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
14820 req->crypto.ciphers_pairwise[0], true);
14821 if (0 > status)
14822 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014823 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014824 "%s: failed to set unicast cipher type", __func__);
14825 return status;
14826 }
14827 }
14828 else
14829 {
14830 /*Reset previous cipher suite to none*/
14831 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
14832 if (0 > status)
14833 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014834 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014835 "%s: failed to set unicast cipher type", __func__);
14836 return status;
14837 }
14838 }
14839
14840 /*set group cipher type*/
14841 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14842 false);
14843
14844 if (0 > status)
14845 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014846 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014847 __func__);
14848 return status;
14849 }
14850
Chet Lanctot186b5732013-03-18 10:26:30 -070014851#ifdef WLAN_FEATURE_11W
14852 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14853#endif
14854
Jeff Johnson295189b2012-06-20 16:38:30 -070014855 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14856 if (req->ie_len)
14857 {
14858 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14859 if ( 0 > status)
14860 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014861 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014862 __func__);
14863 return status;
14864 }
14865 }
14866
14867 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014868 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014869 {
14870 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14871 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14872 )
14873 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014874 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014875 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14876 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014877 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014878 __func__);
14879 return -EOPNOTSUPP;
14880 }
14881 else
14882 {
14883 u8 key_len = req->key_len;
14884 u8 key_idx = req->key_idx;
14885
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014886 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014887 && (CSR_MAX_NUM_KEY > key_idx)
14888 )
14889 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014890 hddLog(VOS_TRACE_LEVEL_INFO,
14891 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014892 __func__, key_idx, key_len);
14893 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014894 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014895 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014896 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014897 (u8)key_len;
14898 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14899 }
14900 }
14901 }
14902 }
14903
14904 return status;
14905}
14906
14907/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014908 * FUNCTION: wlan_hdd_try_disconnect
14909 * This function is used to disconnect from previous
14910 * connection
14911 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053014912int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014913{
14914 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014915 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014916 hdd_station_ctx_t *pHddStaCtx;
14917 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014918 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014919
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014920 ret = wlan_hdd_validate_context(pHddCtx);
14921 if (0 != ret)
14922 {
14923 return ret;
14924 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014925 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14926
14927 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14928
14929 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14930 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053014931 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014932 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14933 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053014934 /* Indicate disconnect to SME so that in-progress connection or preauth
14935 * can be aborted
14936 */
14937 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
14938 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014939 spin_lock_bh(&pAdapter->lock_for_active_session);
14940 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14941 {
14942 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14943 }
14944 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053014945 hdd_connSetConnectionState(pHddStaCtx,
14946 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014947 /* Issue disconnect to CSR */
14948 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014949 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014950 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014951 eCSR_DISCONNECT_REASON_UNSPECIFIED);
14952 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
14953 hddLog(LOG1,
14954 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
14955 } else if ( 0 != status ) {
14956 hddLog(LOGE,
14957 FL("csrRoamDisconnect failure, returned %d"),
14958 (int)status );
14959 result = -EINVAL;
14960 goto disconnected;
14961 }
14962 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014963 &pAdapter->disconnect_comp_var,
14964 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014965 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
14966 hddLog(LOGE,
14967 "%s: Failed to disconnect, timed out", __func__);
14968 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014969 }
14970 }
14971 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
14972 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014973 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014974 &pAdapter->disconnect_comp_var,
14975 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014976 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014977 {
14978 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014979 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014980 }
14981 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014982disconnected:
14983 hddLog(LOG1,
14984 FL("Set HDD connState to eConnectionState_NotConnected"));
14985 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14986 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014987}
14988
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014989/**
14990 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
14991 * @adapter: Pointer to the HDD adapter
14992 * @req: Pointer to the structure cfg_connect_params receieved from user space
14993 *
14994 * This function will start reassociation if bssid hint, channel hint and
14995 * previous bssid parameters are present in the connect request
14996 *
14997 * Return: success if reassociation is happening
14998 * Error code if reassociation is not permitted or not happening
14999 */
15000#ifdef CFG80211_CONNECT_PREV_BSSID
15001static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15002 struct cfg80211_connect_params *req)
15003{
15004 int status = -EPERM;
15005 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
15006 hddLog(VOS_TRACE_LEVEL_INFO,
15007 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
15008 req->channel_hint->hw_value,
15009 MAC_ADDR_ARRAY(req->bssid_hint));
15010 status = hdd_reassoc(adapter, req->bssid_hint,
15011 req->channel_hint->hw_value,
15012 CONNECT_CMD_USERSPACE);
15013 }
15014 return status;
15015}
15016#else
15017static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
15018 struct cfg80211_connect_params *req)
15019{
15020 return -EPERM;
15021}
15022#endif
15023
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015024/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053015025 * FUNCTION: __wlan_hdd_cfg80211_connect
15026 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015027 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015028static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015029 struct net_device *ndev,
15030 struct cfg80211_connect_params *req
15031 )
15032{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015033 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015034 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053015035#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
15036 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015037 const u8 *bssid_hint = req->bssid_hint;
15038#else
15039 const u8 *bssid_hint = NULL;
15040#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015041 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015042 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053015043 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015044
15045 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015046
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015047 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15048 TRACE_CODE_HDD_CFG80211_CONNECT,
15049 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015050 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015051 "%s: device_mode = %s (%d)", __func__,
15052 hdd_device_modetoString(pAdapter->device_mode),
15053 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015054
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015055 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015056 if (!pHddCtx)
15057 {
15058 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15059 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053015060 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080015061 }
15062
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015063 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015064 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015065 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015066 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015067 }
15068
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053015069 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
15070 if (0 == status)
15071 return status;
15072
Agarwal Ashish51325b52014-06-16 16:50:49 +053015073
Jeff Johnson295189b2012-06-20 16:38:30 -070015074#ifdef WLAN_BTAMP_FEATURE
15075 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015076 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070015077 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015078 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015079 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080015080 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070015081 }
15082#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015083
15084 //If Device Mode is Station Concurrent Sessions Exit BMps
15085 //P2P Mode will be taken care in Open/close adapter
15086 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053015087 (vos_concurrent_open_sessions_running())) {
15088 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
15089 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015090 }
15091
15092 /*Try disconnecting if already in connected state*/
15093 status = wlan_hdd_try_disconnect(pAdapter);
15094 if ( 0 > status)
15095 {
15096 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15097 " connection"));
15098 return -EALREADY;
15099 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053015100 /* Check for max concurrent connections after doing disconnect if any*/
15101 if (vos_max_concurrent_connections_reached()) {
15102 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15103 return -ECONNREFUSED;
15104 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015105
Jeff Johnson295189b2012-06-20 16:38:30 -070015106 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015107 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070015108
15109 if ( 0 > status)
15110 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015111 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070015112 __func__);
15113 return status;
15114 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053015115
15116 if (pHddCtx->spoofMacAddr.isEnabled)
15117 {
15118 hddLog(VOS_TRACE_LEVEL_INFO,
15119 "%s: MAC Spoofing enabled ", __func__);
15120 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15121 * to fill TxBds for probe request during SSID scan which may happen
15122 * as part of connect command
15123 */
15124 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
15125 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
15126 if (status != VOS_STATUS_SUCCESS)
15127 return -ECONNREFUSED;
15128 }
15129
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015130 if (req->channel)
15131 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070015132 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015133 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053015134
15135 /* Abort if any scan is going on */
15136 status = wlan_hdd_scan_abort(pAdapter);
15137 if (0 != status)
15138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
15139
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053015140 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
15141 req->ssid_len, req->bssid,
15142 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015143
Sushant Kaushikd7083982015-03-18 14:33:24 +053015144 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015145 {
15146 //ReEnable BMPS if disabled
15147 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
15148 (NULL != pHddCtx))
15149 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053015150 if (pHddCtx->hdd_wlan_suspended)
15151 {
15152 hdd_set_pwrparams(pHddCtx);
15153 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015154 //ReEnable Bmps and Imps back
15155 hdd_enable_bmps_imps(pHddCtx);
15156 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015157 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070015158 return status;
15159 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015160 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015161 EXIT();
15162 return status;
15163}
15164
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015165static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
15166 struct net_device *ndev,
15167 struct cfg80211_connect_params *req)
15168{
15169 int ret;
15170 vos_ssr_protect(__func__);
15171 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
15172 vos_ssr_unprotect(__func__);
15173
15174 return ret;
15175}
Jeff Johnson295189b2012-06-20 16:38:30 -070015176
15177/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015178 * FUNCTION: wlan_hdd_disconnect
15179 * This function is used to issue a disconnect request to SME
15180 */
15181int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
15182{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015183 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015184 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015185 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015186 long ret;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015187 eConnectionState prev_conn_state;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015188
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015189 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015190
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015191 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015192 if (0 != status)
15193 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015194 return status;
15195 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053015196 /* Indicate sme of disconnect so that in progress connection or preauth
15197 * can be aborted
15198 */
15199 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053015200 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015201 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015202
Agarwal Ashish47d18112014-08-04 19:55:07 +053015203 /* Need to apply spin lock before decreasing active sessions
15204 * as there can be chance for double decrement if context switch
15205 * Calls hdd_DisConnectHandler.
15206 */
15207
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015208 prev_conn_state = pHddStaCtx->conn_info.connState;
15209
Agarwal Ashish47d18112014-08-04 19:55:07 +053015210 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015211 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15212 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015213 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
15214 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053015215 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
15216 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053015217
Abhishek Singhf4669da2014-05-26 15:07:49 +053015218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053015219 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
15220
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015221 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015222
Mihir Shete182a0b22014-08-18 16:08:48 +053015223 /*
15224 * stop tx queues before deleting STA/BSS context from the firmware.
15225 * tx has to be disabled because the firmware can get busy dropping
15226 * the tx frames after BSS/STA has been deleted and will not send
15227 * back a response resulting in WDI timeout
15228 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053015229 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053015230 netif_tx_disable(pAdapter->dev);
15231 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015232
Mihir Shete182a0b22014-08-18 16:08:48 +053015233 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015234 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
15235 pAdapter->sessionId, reason);
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015236 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
15237 prev_conn_state != eConnectionState_Connecting)
15238 {
15239 hddLog(LOG1,
15240 FL("status = %d, already disconnected"), status);
15241 result = 0;
15242 goto disconnected;
15243 }
15244 /*
15245 * Wait here instead of returning directly, this will block the next
15246 * connect command and allow processing of the scan for ssid and
15247 * the previous connect command in CSR. Else we might hit some
15248 * race conditions leading to SME and HDD out of sync.
15249 */
15250 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015251 {
15252 hddLog(LOG1,
15253 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015254 }
15255 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015256 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015257 hddLog(LOGE,
15258 FL("csrRoamDisconnect failure, returned %d"),
15259 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015260 result = -EINVAL;
15261 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015262 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015263 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015264 &pAdapter->disconnect_comp_var,
15265 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015266 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015267 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015268 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015269 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015270 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015271 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015272disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053015273 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015274 FL("Set HDD connState to eConnectionState_NotConnected"));
15275 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015276#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
15277 /* Sending disconnect event to userspace for kernel version < 3.11
15278 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
15279 */
15280 hddLog(LOG1, FL("Send disconnected event to userspace"));
15281
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053015282 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053015283 WLAN_REASON_UNSPECIFIED);
15284#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053015285
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015286 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053015287 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015288}
15289
15290
15291/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015292 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070015293 * This function is used to issue a disconnect request to SME
15294 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015295static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015296 struct net_device *dev,
15297 u16 reason
15298 )
15299{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015300 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015301 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015302 tCsrRoamProfile *pRoamProfile;
15303 hdd_station_ctx_t *pHddStaCtx;
15304 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015305#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015306 tANI_U8 staIdx;
15307#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015308
Jeff Johnson295189b2012-06-20 16:38:30 -070015309 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015310
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015311 if (!pAdapter) {
15312 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15313 return -EINVAL;
15314 }
15315
15316 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15317 if (!pHddStaCtx) {
15318 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
15319 return -EINVAL;
15320 }
15321
15322 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15323 status = wlan_hdd_validate_context(pHddCtx);
15324 if (0 != status)
15325 {
15326 return status;
15327 }
15328
15329 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
15330
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015331 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15332 TRACE_CODE_HDD_CFG80211_DISCONNECT,
15333 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015334 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
15335 __func__, hdd_device_modetoString(pAdapter->device_mode),
15336 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015337
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015338 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
15339 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070015340
Jeff Johnson295189b2012-06-20 16:38:30 -070015341 if (NULL != pRoamProfile)
15342 {
15343 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015344 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
15345 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070015346 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015347 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070015348 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015349 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070015350 switch(reason)
15351 {
15352 case WLAN_REASON_MIC_FAILURE:
15353 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
15354 break;
15355
15356 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
15357 case WLAN_REASON_DISASSOC_AP_BUSY:
15358 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
15359 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
15360 break;
15361
15362 case WLAN_REASON_PREV_AUTH_NOT_VALID:
15363 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053015364 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070015365 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
15366 break;
15367
Jeff Johnson295189b2012-06-20 16:38:30 -070015368 default:
15369 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
15370 break;
15371 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015372 pScanInfo = &pHddCtx->scan_info;
15373 if (pScanInfo->mScanPending)
15374 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053015375 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015376 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015377 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053015378 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053015379 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053015380 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015381#ifdef FEATURE_WLAN_TDLS
15382 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015383 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015384 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015385 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
15386 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015387 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015388 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015389 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015391 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080015392 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015393 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015394 status = sme_DeleteTdlsPeerSta(
15395 WLAN_HDD_GET_HAL_CTX(pAdapter),
15396 pAdapter->sessionId,
15397 mac);
15398 if (status != eHAL_STATUS_SUCCESS) {
15399 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15400 return -EPERM;
15401 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015402 }
15403 }
15404#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053015405
15406 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
15407 reasonCode,
15408 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015409 status = wlan_hdd_disconnect(pAdapter, reasonCode);
15410 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070015411 {
15412 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015413 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015414 __func__, (int)status );
15415 return -EINVAL;
15416 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015417 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015418 else
15419 {
15420 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
15421 "called while in %d state", __func__,
15422 pHddStaCtx->conn_info.connState);
15423 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015424 }
15425 else
15426 {
15427 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
15428 }
15429
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015430 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015431 return status;
15432}
15433
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015434static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
15435 struct net_device *dev,
15436 u16 reason
15437 )
15438{
15439 int ret;
15440 vos_ssr_protect(__func__);
15441 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
15442 vos_ssr_unprotect(__func__);
15443
15444 return ret;
15445}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015446
Jeff Johnson295189b2012-06-20 16:38:30 -070015447/*
15448 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015449 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015450 * settings in IBSS mode.
15451 */
15452static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015453 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015454 struct cfg80211_ibss_params *params
15455 )
15456{
15457 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015458 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015459 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15460 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015461
Jeff Johnson295189b2012-06-20 16:38:30 -070015462 ENTER();
15463
15464 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070015465 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070015466
15467 if (params->ie_len && ( NULL != params->ie) )
15468 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015469 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15470 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015471 {
15472 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15473 encryptionType = eCSR_ENCRYPT_TYPE_AES;
15474 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015475 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015476 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015477 tDot11fIEWPA dot11WPAIE;
15478 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015479 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015480
Wilson Yang00256342013-10-10 23:13:38 -070015481 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015482 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15483 params->ie_len, DOT11F_EID_WPA);
15484 if ( NULL != ie )
15485 {
15486 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15487 // Unpack the WPA IE
15488 //Skip past the EID byte and length byte - and four byte WiFi OUI
15489 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
15490 &ie[2+4],
15491 ie[1] - 4,
15492 &dot11WPAIE);
15493 /*Extract the multicast cipher, the encType for unicast
15494 cipher for wpa-none is none*/
15495 encryptionType =
15496 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
15497 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015498 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015499
Jeff Johnson295189b2012-06-20 16:38:30 -070015500 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
15501
15502 if (0 > status)
15503 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015504 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015505 __func__);
15506 return status;
15507 }
15508 }
15509
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015510 pWextState->roamProfile.AuthType.authType[0] =
15511 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070015512 eCSR_AUTH_TYPE_OPEN_SYSTEM;
15513
15514 if (params->privacy)
15515 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015516 /* Security enabled IBSS, At this time there is no information available
15517 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070015518 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015519 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070015520 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015521 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070015522 *enable privacy bit in beacons */
15523
15524 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
15525 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015526 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
15527 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070015528 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15529 pWextState->roamProfile.EncryptionType.numEntries = 1;
15530 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070015531 return status;
15532}
15533
15534/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015535 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015536 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015537 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015538static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015539 struct net_device *dev,
15540 struct cfg80211_ibss_params *params
15541 )
15542{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015543 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015544 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15545 tCsrRoamProfile *pRoamProfile;
15546 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015547 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15548 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015549 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070015550
15551 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015552
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015553 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15554 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
15555 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015556 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015557 "%s: device_mode = %s (%d)", __func__,
15558 hdd_device_modetoString(pAdapter->device_mode),
15559 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015560
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015561 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015562 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015563 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015564 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015565 }
15566
15567 if (NULL == pWextState)
15568 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015569 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015570 __func__);
15571 return -EIO;
15572 }
15573
Agarwal Ashish51325b52014-06-16 16:50:49 +053015574 if (vos_max_concurrent_connections_reached()) {
15575 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15576 return -ECONNREFUSED;
15577 }
15578
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015579 /*Try disconnecting if already in connected state*/
15580 status = wlan_hdd_try_disconnect(pAdapter);
15581 if ( 0 > status)
15582 {
15583 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15584 " IBSS connection"));
15585 return -EALREADY;
15586 }
15587
Jeff Johnson295189b2012-06-20 16:38:30 -070015588 pRoamProfile = &pWextState->roamProfile;
15589
15590 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
15591 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015592 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015593 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015594 return -EINVAL;
15595 }
15596
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015597 /* BSSID is provided by upper layers hence no need to AUTO generate */
15598 if (NULL != params->bssid) {
15599 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15600 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
15601 hddLog (VOS_TRACE_LEVEL_ERROR,
15602 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15603 return -EIO;
15604 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015605 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015606 }
krunal sonie9002db2013-11-25 14:24:17 -080015607 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
15608 {
15609 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15610 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
15611 {
15612 hddLog (VOS_TRACE_LEVEL_ERROR,
15613 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15614 return -EIO;
15615 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015616
15617 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080015618 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015619 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080015620 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015621
Jeff Johnson295189b2012-06-20 16:38:30 -070015622 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070015623 if (NULL !=
15624#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15625 params->chandef.chan)
15626#else
15627 params->channel)
15628#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015629 {
15630 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015631 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15632 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
15633 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15634 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015635
15636 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015637 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070015638 ieee80211_frequency_to_channel(
15639#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15640 params->chandef.chan->center_freq);
15641#else
15642 params->channel->center_freq);
15643#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015644
15645 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15646 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070015647 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015648 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
15649 __func__);
15650 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070015651 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015652
15653 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015654 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015655 if (channelNum == validChan[indx])
15656 {
15657 break;
15658 }
15659 }
15660 if (indx >= numChans)
15661 {
15662 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015663 __func__, channelNum);
15664 return -EINVAL;
15665 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015666 /* Set the Operational Channel */
15667 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
15668 channelNum);
15669 pRoamProfile->ChannelInfo.numOfChannels = 1;
15670 pHddStaCtx->conn_info.operationChannel = channelNum;
15671 pRoamProfile->ChannelInfo.ChannelList =
15672 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070015673 }
15674
15675 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015676 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070015677 if (status < 0)
15678 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015679 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070015680 __func__);
15681 return status;
15682 }
15683
15684 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015685 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053015686 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015687 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015688
15689 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015690 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015691
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015692 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015693 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015694}
15695
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015696static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
15697 struct net_device *dev,
15698 struct cfg80211_ibss_params *params
15699 )
15700{
15701 int ret = 0;
15702
15703 vos_ssr_protect(__func__);
15704 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
15705 vos_ssr_unprotect(__func__);
15706
15707 return ret;
15708}
15709
Jeff Johnson295189b2012-06-20 16:38:30 -070015710/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015711 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015712 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015713 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015714static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015715 struct net_device *dev
15716 )
15717{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015718 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015719 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15720 tCsrRoamProfile *pRoamProfile;
15721 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015722 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053015723 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015724#ifdef WLAN_FEATURE_RMC
15725 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
15726#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015727
15728 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015729
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015730 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15731 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
15732 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015733 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015734 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015735 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015736 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015737 }
15738
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015739 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
15740 hdd_device_modetoString(pAdapter->device_mode),
15741 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015742 if (NULL == pWextState)
15743 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015744 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015745 __func__);
15746 return -EIO;
15747 }
15748
15749 pRoamProfile = &pWextState->roamProfile;
15750
15751 /* Issue disconnect only if interface type is set to IBSS */
15752 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
15753 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015754 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070015755 __func__);
15756 return -EINVAL;
15757 }
15758
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015759#ifdef WLAN_FEATURE_RMC
15760 /* Clearing add IE of beacon */
15761 if (ccmCfgSetStr(pHddCtx->hHal,
15762 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
15763 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
15764 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15765 {
15766 hddLog (VOS_TRACE_LEVEL_ERROR,
15767 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
15768 return -EINVAL;
15769 }
15770 if (ccmCfgSetInt(pHddCtx->hHal,
15771 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
15772 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15773 {
15774 hddLog (VOS_TRACE_LEVEL_ERROR,
15775 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
15776 __func__);
15777 return -EINVAL;
15778 }
15779
15780 // Reset WNI_CFG_PROBE_RSP Flags
15781 wlan_hdd_reset_prob_rspies(pAdapter);
15782
15783 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15784 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
15785 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15786 {
15787 hddLog (VOS_TRACE_LEVEL_ERROR,
15788 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
15789 __func__);
15790 return -EINVAL;
15791 }
15792#endif
15793
Jeff Johnson295189b2012-06-20 16:38:30 -070015794 /* Issue Disconnect request */
15795 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053015796 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
15797 pAdapter->sessionId,
15798 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
15799 if (!HAL_STATUS_SUCCESS(hal_status)) {
15800 hddLog(LOGE,
15801 FL("sme_RoamDisconnect failed hal_status(%d)"),
15802 hal_status);
15803 return -EAGAIN;
15804 }
15805 status = wait_for_completion_timeout(
15806 &pAdapter->disconnect_comp_var,
15807 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
15808 if (!status) {
15809 hddLog(LOGE,
15810 FL("wait on disconnect_comp_var failed"));
15811 return -ETIMEDOUT;
15812 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015813
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015814 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015815 return 0;
15816}
15817
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015818static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
15819 struct net_device *dev
15820 )
15821{
15822 int ret = 0;
15823
15824 vos_ssr_protect(__func__);
15825 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
15826 vos_ssr_unprotect(__func__);
15827
15828 return ret;
15829}
15830
Jeff Johnson295189b2012-06-20 16:38:30 -070015831/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015832 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070015833 * This function is used to set the phy parameters
15834 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
15835 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015836static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015837 u32 changed)
15838{
15839 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15840 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015841 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015842
15843 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015844
15845 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015846 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
15847 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015848
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015849 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015850 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015851 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015852 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015853 }
15854
Jeff Johnson295189b2012-06-20 16:38:30 -070015855 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
15856 {
15857 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
15858 WNI_CFG_RTS_THRESHOLD_STAMAX :
15859 wiphy->rts_threshold;
15860
15861 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015862 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070015863 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015864 hddLog(VOS_TRACE_LEVEL_ERROR,
15865 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015866 __func__, rts_threshold);
15867 return -EINVAL;
15868 }
15869
15870 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
15871 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015872 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015873 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015874 hddLog(VOS_TRACE_LEVEL_ERROR,
15875 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015876 __func__, rts_threshold);
15877 return -EIO;
15878 }
15879
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015880 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015881 rts_threshold);
15882 }
15883
15884 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
15885 {
15886 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
15887 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
15888 wiphy->frag_threshold;
15889
15890 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015891 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015892 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015893 hddLog(VOS_TRACE_LEVEL_ERROR,
15894 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015895 frag_threshold);
15896 return -EINVAL;
15897 }
15898
15899 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
15900 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015901 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015902 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015903 hddLog(VOS_TRACE_LEVEL_ERROR,
15904 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015905 __func__, frag_threshold);
15906 return -EIO;
15907 }
15908
15909 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
15910 frag_threshold);
15911 }
15912
15913 if ((changed & WIPHY_PARAM_RETRY_SHORT)
15914 || (changed & WIPHY_PARAM_RETRY_LONG))
15915 {
15916 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
15917 wiphy->retry_short :
15918 wiphy->retry_long;
15919
15920 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
15921 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
15922 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015923 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015924 __func__, retry_value);
15925 return -EINVAL;
15926 }
15927
15928 if (changed & WIPHY_PARAM_RETRY_SHORT)
15929 {
15930 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
15931 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015932 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015933 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015934 hddLog(VOS_TRACE_LEVEL_ERROR,
15935 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015936 __func__, retry_value);
15937 return -EIO;
15938 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015939 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015940 __func__, retry_value);
15941 }
15942 else if (changed & WIPHY_PARAM_RETRY_SHORT)
15943 {
15944 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
15945 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015946 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015947 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015948 hddLog(VOS_TRACE_LEVEL_ERROR,
15949 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015950 __func__, retry_value);
15951 return -EIO;
15952 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015953 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015954 __func__, retry_value);
15955 }
15956 }
15957
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015958 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015959 return 0;
15960}
15961
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015962static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
15963 u32 changed)
15964{
15965 int ret;
15966
15967 vos_ssr_protect(__func__);
15968 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
15969 vos_ssr_unprotect(__func__);
15970
15971 return ret;
15972}
15973
Jeff Johnson295189b2012-06-20 16:38:30 -070015974/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015975 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015976 * This function is used to set the txpower
15977 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015978static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015979#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15980 struct wireless_dev *wdev,
15981#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015982#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015983 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015984#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015985 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015986#endif
15987 int dbm)
15988{
15989 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015990 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015991 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
15992 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015993 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015994
15995 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015996
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015997 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15998 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
15999 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016000 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016001 if (0 != status)
16002 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016003 return status;
16004 }
16005
16006 hHal = pHddCtx->hHal;
16007
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016008 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
16009 dbm, ccmCfgSetCallback,
16010 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016011 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016012 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016013 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
16014 return -EIO;
16015 }
16016
16017 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
16018 dbm);
16019
16020 switch(type)
16021 {
16022 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
16023 /* Fall through */
16024 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
16025 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
16026 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016027 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
16028 __func__);
16029 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070016030 }
16031 break;
16032 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016033 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016034 __func__);
16035 return -EOPNOTSUPP;
16036 break;
16037 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016038 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
16039 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070016040 return -EIO;
16041 }
16042
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016043 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016044 return 0;
16045}
16046
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053016047static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
16048#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16049 struct wireless_dev *wdev,
16050#endif
16051#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16052 enum tx_power_setting type,
16053#else
16054 enum nl80211_tx_power_setting type,
16055#endif
16056 int dbm)
16057{
16058 int ret;
16059 vos_ssr_protect(__func__);
16060 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
16061#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16062 wdev,
16063#endif
16064#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
16065 type,
16066#else
16067 type,
16068#endif
16069 dbm);
16070 vos_ssr_unprotect(__func__);
16071
16072 return ret;
16073}
16074
Jeff Johnson295189b2012-06-20 16:38:30 -070016075/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016076 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070016077 * This function is used to read the txpower
16078 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016079static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070016080#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16081 struct wireless_dev *wdev,
16082#endif
16083 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070016084{
16085
16086 hdd_adapter_t *pAdapter;
16087 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016088 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016089
Jeff Johnsone7245742012-09-05 17:12:55 -070016090 ENTER();
16091
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016092 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016093 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016094 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016095 *dbm = 0;
16096 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016097 }
16098
Jeff Johnson295189b2012-06-20 16:38:30 -070016099 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
16100 if (NULL == pAdapter)
16101 {
16102 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
16103 return -ENOENT;
16104 }
16105
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016106 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16107 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
16108 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070016109 wlan_hdd_get_classAstats(pAdapter);
16110 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
16111
Jeff Johnsone7245742012-09-05 17:12:55 -070016112 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016113 return 0;
16114}
16115
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016116static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
16117#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16118 struct wireless_dev *wdev,
16119#endif
16120 int *dbm)
16121{
16122 int ret;
16123
16124 vos_ssr_protect(__func__);
16125 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
16126#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
16127 wdev,
16128#endif
16129 dbm);
16130 vos_ssr_unprotect(__func__);
16131
16132 return ret;
16133}
16134
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016135static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016136#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16137 const u8* mac,
16138#else
16139 u8* mac,
16140#endif
16141 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070016142{
16143 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
16144 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16145 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053016146 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016147
16148 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
16149 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070016150
16151 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
16152 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
16153 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
16154 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
16155 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
16156 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
16157 tANI_U16 maxRate = 0;
16158 tANI_U16 myRate;
16159 tANI_U16 currentRate = 0;
16160 tANI_U8 maxSpeedMCS = 0;
16161 tANI_U8 maxMCSIdx = 0;
16162 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053016163 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070016164 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016165 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016166
Leo Chang6f8870f2013-03-26 18:11:36 -070016167#ifdef WLAN_FEATURE_11AC
16168 tANI_U32 vht_mcs_map;
16169 eDataRate11ACMaxMcs vhtMaxMcs;
16170#endif /* WLAN_FEATURE_11AC */
16171
Jeff Johnsone7245742012-09-05 17:12:55 -070016172 ENTER();
16173
Jeff Johnson295189b2012-06-20 16:38:30 -070016174 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
16175 (0 == ssidlen))
16176 {
16177 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
16178 " Invalid ssidlen, %d", __func__, ssidlen);
16179 /*To keep GUI happy*/
16180 return 0;
16181 }
16182
Mukul Sharma811205f2014-07-09 21:07:30 +053016183 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16184 {
16185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16186 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053016187 /* return a cached value */
16188 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053016189 return 0;
16190 }
16191
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016192 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016193 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016194 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016195 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016196 }
16197
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053016198 wlan_hdd_get_station_stats(pAdapter);
16199 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070016200
Kiet Lam3b17fc82013-09-27 05:24:08 +053016201 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
16202 sinfo->filled |= STATION_INFO_SIGNAL;
16203
c_hpothu09f19542014-05-30 21:53:31 +053016204 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053016205 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
16206 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053016207 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053016208 {
16209 rate_flags = pAdapter->maxRateFlags;
16210 }
c_hpothu44ff4e02014-05-08 00:13:57 +053016211
Jeff Johnson295189b2012-06-20 16:38:30 -070016212 //convert to the UI units of 100kbps
16213 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
16214
16215#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070016216 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 -070016217 sinfo->signal,
16218 pCfg->reportMaxLinkSpeed,
16219 myRate,
16220 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016221 (int) pCfg->linkSpeedRssiMid,
16222 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070016223 (int) rate_flags,
16224 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070016225#endif //LINKSPEED_DEBUG_ENABLED
16226
16227 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
16228 {
16229 // we do not want to necessarily report the current speed
16230 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
16231 {
16232 // report the max possible speed
16233 rssidx = 0;
16234 }
16235 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
16236 {
16237 // report the max possible speed with RSSI scaling
16238 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
16239 {
16240 // report the max possible speed
16241 rssidx = 0;
16242 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016243 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070016244 {
16245 // report middle speed
16246 rssidx = 1;
16247 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016248 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
16249 {
16250 // report middle speed
16251 rssidx = 2;
16252 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016253 else
16254 {
16255 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070016256 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070016257 }
16258 }
16259 else
16260 {
16261 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
16262 hddLog(VOS_TRACE_LEVEL_ERROR,
16263 "%s: Invalid value for reportMaxLinkSpeed: %u",
16264 __func__, pCfg->reportMaxLinkSpeed);
16265 rssidx = 0;
16266 }
16267
16268 maxRate = 0;
16269
16270 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016271 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
16272 OperationalRates, &ORLeng))
16273 {
16274 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16275 /*To keep GUI happy*/
16276 return 0;
16277 }
16278
Jeff Johnson295189b2012-06-20 16:38:30 -070016279 for (i = 0; i < ORLeng; i++)
16280 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016281 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016282 {
16283 /* Validate Rate Set */
16284 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
16285 {
16286 currentRate = supported_data_rate[j].supported_rate[rssidx];
16287 break;
16288 }
16289 }
16290 /* Update MAX rate */
16291 maxRate = (currentRate > maxRate)?currentRate:maxRate;
16292 }
16293
16294 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016295 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
16296 ExtendedRates, &ERLeng))
16297 {
16298 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16299 /*To keep GUI happy*/
16300 return 0;
16301 }
16302
Jeff Johnson295189b2012-06-20 16:38:30 -070016303 for (i = 0; i < ERLeng; i++)
16304 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016305 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016306 {
16307 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
16308 {
16309 currentRate = supported_data_rate[j].supported_rate[rssidx];
16310 break;
16311 }
16312 }
16313 /* Update MAX rate */
16314 maxRate = (currentRate > maxRate)?currentRate:maxRate;
16315 }
c_hpothu79aab322014-07-14 21:11:01 +053016316
Kiet Lamb69f8dc2013-11-15 15:34:27 +053016317 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053016318 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053016319 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053016320 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070016321 {
c_hpothu79aab322014-07-14 21:11:01 +053016322 if (rate_flags & eHAL_TX_RATE_VHT80)
16323 mode = 2;
16324 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
16325 mode = 1;
16326 else
16327 mode = 0;
16328
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053016329 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
16330 MCSRates, &MCSLeng))
16331 {
16332 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
16333 /*To keep GUI happy*/
16334 return 0;
16335 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016336 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070016337#ifdef WLAN_FEATURE_11AC
16338 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016339 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070016340 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016341 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016342 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070016343 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070016344 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016345 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016346 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016347 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070016348 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016349 maxMCSIdx = 7;
16350 }
16351 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
16352 {
16353 maxMCSIdx = 8;
16354 }
16355 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
16356 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016357 //VHT20 is supporting 0~8
16358 if (rate_flags & eHAL_TX_RATE_VHT20)
16359 maxMCSIdx = 8;
16360 else
16361 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070016362 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016363
c_hpothu79aab322014-07-14 21:11:01 +053016364 if (0 != rssidx)/*check for scaled */
16365 {
16366 //get middle rate MCS index if rssi=1/2
16367 for (i=0; i <= maxMCSIdx; i++)
16368 {
16369 if (sinfo->signal <= rssiMcsTbl[mode][i])
16370 {
16371 maxMCSIdx = i;
16372 break;
16373 }
16374 }
16375 }
16376
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016377 if (rate_flags & eHAL_TX_RATE_VHT80)
16378 {
16379 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
16380 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
16381 }
16382 else if (rate_flags & eHAL_TX_RATE_VHT40)
16383 {
16384 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
16385 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
16386 }
16387 else if (rate_flags & eHAL_TX_RATE_VHT20)
16388 {
16389 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
16390 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
16391 }
16392
Leo Chang6f8870f2013-03-26 18:11:36 -070016393 maxSpeedMCS = 1;
16394 if (currentRate > maxRate)
16395 {
16396 maxRate = currentRate;
16397 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016398
Leo Chang6f8870f2013-03-26 18:11:36 -070016399 }
16400 else
16401#endif /* WLAN_FEATURE_11AC */
16402 {
16403 if (rate_flags & eHAL_TX_RATE_HT40)
16404 {
16405 rateFlag |= 1;
16406 }
16407 if (rate_flags & eHAL_TX_RATE_SGI)
16408 {
16409 rateFlag |= 2;
16410 }
16411
Girish Gowli01abcee2014-07-31 20:18:55 +053016412 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053016413 if (rssidx == 1 || rssidx == 2)
16414 {
16415 //get middle rate MCS index if rssi=1/2
16416 for (i=0; i <= 7; i++)
16417 {
16418 if (sinfo->signal <= rssiMcsTbl[mode][i])
16419 {
16420 temp = i+1;
16421 break;
16422 }
16423 }
16424 }
c_hpothu79aab322014-07-14 21:11:01 +053016425
16426 for (i = 0; i < MCSLeng; i++)
16427 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016428 for (j = 0; j < temp; j++)
16429 {
16430 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
16431 {
16432 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016433 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016434 break;
16435 }
16436 }
16437 if ((j < temp) && (currentRate > maxRate))
16438 {
16439 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070016440 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016441 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016442 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016443 }
16444 }
16445
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016446 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
16447 {
16448 maxRate = myRate;
16449 maxSpeedMCS = 1;
16450 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16451 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016452 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053016453 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070016454 {
16455 maxRate = myRate;
16456 if (rate_flags & eHAL_TX_RATE_LEGACY)
16457 {
16458 maxSpeedMCS = 0;
16459 }
16460 else
16461 {
16462 maxSpeedMCS = 1;
16463 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16464 }
16465 }
16466
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016467 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070016468 {
16469 sinfo->txrate.legacy = maxRate;
16470#ifdef LINKSPEED_DEBUG_ENABLED
16471 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
16472#endif //LINKSPEED_DEBUG_ENABLED
16473 }
16474 else
16475 {
16476 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070016477#ifdef WLAN_FEATURE_11AC
16478 sinfo->txrate.nss = 1;
16479 if (rate_flags & eHAL_TX_RATE_VHT80)
16480 {
16481 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016482 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070016483 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016484 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070016485 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016486 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16487 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16488 }
16489 else if (rate_flags & eHAL_TX_RATE_VHT20)
16490 {
16491 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16492 }
16493#endif /* WLAN_FEATURE_11AC */
16494 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
16495 {
16496 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16497 if (rate_flags & eHAL_TX_RATE_HT40)
16498 {
16499 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16500 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016501 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016502 if (rate_flags & eHAL_TX_RATE_SGI)
16503 {
16504 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16505 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016506
Jeff Johnson295189b2012-06-20 16:38:30 -070016507#ifdef LINKSPEED_DEBUG_ENABLED
16508 pr_info("Reporting MCS rate %d flags %x\n",
16509 sinfo->txrate.mcs,
16510 sinfo->txrate.flags );
16511#endif //LINKSPEED_DEBUG_ENABLED
16512 }
16513 }
16514 else
16515 {
16516 // report current rate instead of max rate
16517
16518 if (rate_flags & eHAL_TX_RATE_LEGACY)
16519 {
16520 //provide to the UI in units of 100kbps
16521 sinfo->txrate.legacy = myRate;
16522#ifdef LINKSPEED_DEBUG_ENABLED
16523 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
16524#endif //LINKSPEED_DEBUG_ENABLED
16525 }
16526 else
16527 {
16528 //must be MCS
16529 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016530#ifdef WLAN_FEATURE_11AC
16531 sinfo->txrate.nss = 1;
16532 if (rate_flags & eHAL_TX_RATE_VHT80)
16533 {
16534 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16535 }
16536 else
16537#endif /* WLAN_FEATURE_11AC */
16538 {
16539 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16540 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016541 if (rate_flags & eHAL_TX_RATE_SGI)
16542 {
16543 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16544 }
16545 if (rate_flags & eHAL_TX_RATE_HT40)
16546 {
16547 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16548 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016549#ifdef WLAN_FEATURE_11AC
16550 else if (rate_flags & eHAL_TX_RATE_VHT80)
16551 {
16552 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
16553 }
16554#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070016555#ifdef LINKSPEED_DEBUG_ENABLED
16556 pr_info("Reporting actual MCS rate %d flags %x\n",
16557 sinfo->txrate.mcs,
16558 sinfo->txrate.flags );
16559#endif //LINKSPEED_DEBUG_ENABLED
16560 }
16561 }
16562 sinfo->filled |= STATION_INFO_TX_BITRATE;
16563
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016564 sinfo->tx_packets =
16565 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
16566 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
16567 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
16568 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
16569
16570 sinfo->tx_retries =
16571 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
16572 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
16573 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
16574 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
16575
16576 sinfo->tx_failed =
16577 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
16578 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
16579 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
16580 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
16581
16582 sinfo->filled |=
16583 STATION_INFO_TX_PACKETS |
16584 STATION_INFO_TX_RETRIES |
16585 STATION_INFO_TX_FAILED;
16586
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053016587 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
16588 sinfo->filled |= STATION_INFO_RX_PACKETS;
16589
16590 if (rate_flags & eHAL_TX_RATE_LEGACY)
16591 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
16592 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
16593 sinfo->rx_packets);
16594 else
16595 hddLog(LOG1,
16596 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
16597 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
16598 sinfo->tx_packets, sinfo->rx_packets);
16599
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016600 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16601 TRACE_CODE_HDD_CFG80211_GET_STA,
16602 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016603 EXIT();
16604 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070016605}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016606#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16607static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16608 const u8* mac, struct station_info *sinfo)
16609#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016610static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16611 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016612#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016613{
16614 int ret;
16615
16616 vos_ssr_protect(__func__);
16617 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
16618 vos_ssr_unprotect(__func__);
16619
16620 return ret;
16621}
16622
16623static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070016624 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070016625{
16626 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016627 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016628 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016629 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016630
Jeff Johnsone7245742012-09-05 17:12:55 -070016631 ENTER();
16632
Jeff Johnson295189b2012-06-20 16:38:30 -070016633 if (NULL == pAdapter)
16634 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016635 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016636 return -ENODEV;
16637 }
16638
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016639 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16640 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
16641 pAdapter->sessionId, timeout));
16642
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016643 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016644 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016645 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016646 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016647 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016648 }
16649
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016650 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
16651 (TRUE == pHddCtx->hdd_wlan_suspended) &&
16652 (pHddCtx->cfg_ini->fhostArpOffload) &&
16653 (eConnectionState_Associated ==
16654 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
16655 {
Amar Singhald53568e2013-09-26 11:03:45 -070016656
16657 hddLog(VOS_TRACE_LEVEL_INFO,
16658 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053016659 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016660 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16661 {
16662 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016663 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016664 __func__, vos_status);
16665 }
16666 }
16667
Jeff Johnson295189b2012-06-20 16:38:30 -070016668 /**The get power cmd from the supplicant gets updated by the nl only
16669 *on successful execution of the function call
16670 *we are oppositely mapped w.r.t mode in the driver
16671 **/
16672 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
16673
16674 if (VOS_STATUS_E_FAILURE == vos_status)
16675 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16677 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016678 return -EINVAL;
16679 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016680 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016681 return 0;
16682}
16683
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016684static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
16685 struct net_device *dev, bool mode, int timeout)
16686{
16687 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016688
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016689 vos_ssr_protect(__func__);
16690 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
16691 vos_ssr_unprotect(__func__);
16692
16693 return ret;
16694}
Sushant Kaushik084f6592015-09-10 13:11:56 +053016695
Jeff Johnson295189b2012-06-20 16:38:30 -070016696#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016697static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
16698 struct net_device *netdev,
16699 u8 key_index)
16700{
16701 ENTER();
16702 return 0;
16703}
16704
Jeff Johnson295189b2012-06-20 16:38:30 -070016705static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016706 struct net_device *netdev,
16707 u8 key_index)
16708{
16709 int ret;
16710 vos_ssr_protect(__func__);
16711 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
16712 vos_ssr_unprotect(__func__);
16713 return ret;
16714}
16715#endif //LINUX_VERSION_CODE
16716
16717#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16718static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16719 struct net_device *dev,
16720 struct ieee80211_txq_params *params)
16721{
16722 ENTER();
16723 return 0;
16724}
16725#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16726static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16727 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016728{
Jeff Johnsone7245742012-09-05 17:12:55 -070016729 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070016730 return 0;
16731}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016732#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070016733
16734#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16735static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016736 struct net_device *dev,
16737 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016738{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016739 int ret;
16740
16741 vos_ssr_protect(__func__);
16742 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
16743 vos_ssr_unprotect(__func__);
16744 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016745}
16746#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16747static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
16748 struct ieee80211_txq_params *params)
16749{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016750 int ret;
16751
16752 vos_ssr_protect(__func__);
16753 ret = __wlan_hdd_set_txq_params(wiphy, params);
16754 vos_ssr_unprotect(__func__);
16755 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016756}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016757#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016758
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016759static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016760 struct net_device *dev,
16761 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070016762{
16763 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016764 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016765 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016766 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016767 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016768 v_CONTEXT_t pVosContext = NULL;
16769 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016770
Jeff Johnsone7245742012-09-05 17:12:55 -070016771 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016772
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016773 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070016774 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016775 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016776 return -EINVAL;
16777 }
16778
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016779 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16780 TRACE_CODE_HDD_CFG80211_DEL_STA,
16781 pAdapter->sessionId, pAdapter->device_mode));
16782
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016783 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16784 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016785 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016786 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016787 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016788 }
16789
Jeff Johnson295189b2012-06-20 16:38:30 -070016790 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016791 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016792 )
16793 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016794 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
16795 pSapCtx = VOS_GET_SAP_CB(pVosContext);
16796 if(pSapCtx == NULL){
16797 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16798 FL("psapCtx is NULL"));
16799 return -ENOENT;
16800 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053016801 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
16802 {
16803 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
16804 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
16805 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
16806 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016807 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070016808 {
16809 v_U16_t i;
16810 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
16811 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016812 if ((pSapCtx->aStaInfo[i].isUsed) &&
16813 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070016814 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016815 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016816 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016817 ETHER_ADDR_LEN);
16818
Jeff Johnson295189b2012-06-20 16:38:30 -070016819 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016820 "%s: Delete STA with MAC::"
16821 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016822 __func__,
16823 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
16824 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070016825 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016826 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016827 }
16828 }
16829 }
16830 else
16831 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016832
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016833 vos_status = hdd_softap_GetStaId(pAdapter,
16834 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016835 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16836 {
16837 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016838 "%s: Skip this DEL STA as this is not used::"
16839 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016840 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016841 return -ENOENT;
16842 }
16843
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016844 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016845 {
16846 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016847 "%s: Skip this DEL STA as deauth is in progress::"
16848 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016849 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016850 return -ENOENT;
16851 }
16852
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016853 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016854
Jeff Johnson295189b2012-06-20 16:38:30 -070016855 hddLog(VOS_TRACE_LEVEL_INFO,
16856 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016857 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016858 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016859 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016860
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016861 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016862 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16863 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016864 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016865 hddLog(VOS_TRACE_LEVEL_INFO,
16866 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016867 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016868 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016869 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016870 return -ENOENT;
16871 }
16872
Jeff Johnson295189b2012-06-20 16:38:30 -070016873 }
16874 }
16875
16876 EXIT();
16877
16878 return 0;
16879}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016880
16881#ifdef CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053016882int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016883 struct net_device *dev,
16884 struct station_del_parameters *param)
16885#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016886#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053016887int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016888 struct net_device *dev, const u8 *mac)
16889#else
Kapil Gupta137ef892016-12-13 19:38:00 +053016890int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016891 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016892#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016893#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016894{
16895 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016896 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070016897
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016898 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016899
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016900#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016901 if (NULL == param) {
16902 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016903 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016904 return -EINVAL;
16905 }
16906
16907 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
16908 param->subtype, &delStaParams);
16909
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016910#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053016911 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016912 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016913#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016914 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
16915
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016916 vos_ssr_unprotect(__func__);
16917
16918 return ret;
16919}
16920
16921static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016922 struct net_device *dev,
16923#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16924 const u8 *mac,
16925#else
16926 u8 *mac,
16927#endif
16928 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016929{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016930 hdd_adapter_t *pAdapter;
16931 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016932 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016933#ifdef FEATURE_WLAN_TDLS
16934 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016935
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016936 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016937
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016938 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16939 if (NULL == pAdapter)
16940 {
16941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16942 "%s: Adapter is NULL",__func__);
16943 return -EINVAL;
16944 }
16945 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16946 status = wlan_hdd_validate_context(pHddCtx);
16947 if (0 != status)
16948 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016949 return status;
16950 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016951
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016952 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16953 TRACE_CODE_HDD_CFG80211_ADD_STA,
16954 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016955 mask = params->sta_flags_mask;
16956
16957 set = params->sta_flags_set;
16958
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016959 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016960 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
16961 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016962
16963 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
16964 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080016965 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016966 }
16967 }
16968#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016969 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016970 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016971}
16972
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016973#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16974static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16975 struct net_device *dev, const u8 *mac,
16976 struct station_parameters *params)
16977#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016978static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16979 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016980#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016981{
16982 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016983
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016984 vos_ssr_protect(__func__);
16985 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
16986 vos_ssr_unprotect(__func__);
16987
16988 return ret;
16989}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016990#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070016991
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016992static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070016993 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016994{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016995 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16996 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016997 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016998 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016999 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017000 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070017001
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017002 ENTER();
17003
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017004 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017005 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017006 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017007 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017008 return -EINVAL;
17009 }
17010
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017011 if (!pmksa) {
17012 hddLog(LOGE, FL("pmksa is NULL"));
17013 return -EINVAL;
17014 }
17015
17016 if (!pmksa->bssid || !pmksa->pmkid) {
17017 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
17018 pmksa->bssid, pmksa->pmkid);
17019 return -EINVAL;
17020 }
17021
17022 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
17023 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17024
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017025 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17026 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017027 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017028 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017029 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017030 }
17031
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017032 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017033 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17034
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017035 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
17036 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017037
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017038 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017039 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017040 &pmk_id, 1, FALSE);
17041
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017042 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17043 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
17044 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017045
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017046 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017047 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017048}
17049
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017050static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
17051 struct cfg80211_pmksa *pmksa)
17052{
17053 int ret;
17054
17055 vos_ssr_protect(__func__);
17056 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
17057 vos_ssr_unprotect(__func__);
17058
17059 return ret;
17060}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017061
Wilson Yang6507c4e2013-10-01 20:11:19 -070017062
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017063static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070017064 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017065{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017066 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17067 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017068 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017069 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017070
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017071 ENTER();
17072
Wilson Yang6507c4e2013-10-01 20:11:19 -070017073 /* Validate pAdapter */
17074 if (NULL == pAdapter)
17075 {
17076 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
17077 return -EINVAL;
17078 }
17079
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017080 if (!pmksa) {
17081 hddLog(LOGE, FL("pmksa is NULL"));
17082 return -EINVAL;
17083 }
17084
17085 if (!pmksa->bssid) {
17086 hddLog(LOGE, FL("pmksa->bssid is NULL"));
17087 return -EINVAL;
17088 }
17089
Kiet Lam98c46a12014-10-31 15:34:57 -070017090 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
17091 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
17092
Wilson Yang6507c4e2013-10-01 20:11:19 -070017093 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17094 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017095 if (0 != status)
17096 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017097 return status;
17098 }
17099
17100 /*Retrieve halHandle*/
17101 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17102
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017103 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17104 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
17105 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017106 /* Delete the PMKID CSR cache */
17107 if (eHAL_STATUS_SUCCESS !=
17108 sme_RoamDelPMKIDfromCache(halHandle,
17109 pAdapter->sessionId, pmksa->bssid, FALSE)) {
17110 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
17111 MAC_ADDR_ARRAY(pmksa->bssid));
17112 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017113 }
17114
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017115 EXIT();
17116 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017117}
17118
Wilson Yang6507c4e2013-10-01 20:11:19 -070017119
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017120static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
17121 struct cfg80211_pmksa *pmksa)
17122{
17123 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017124
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017125 vos_ssr_protect(__func__);
17126 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
17127 vos_ssr_unprotect(__func__);
17128
17129 return ret;
17130
17131}
17132
17133static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017134{
Wilson Yang6507c4e2013-10-01 20:11:19 -070017135 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17136 tHalHandle halHandle;
17137 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080017138 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017139
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017140 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070017141
17142 /* Validate pAdapter */
17143 if (NULL == pAdapter)
17144 {
17145 hddLog(VOS_TRACE_LEVEL_ERROR,
17146 "%s: Invalid Adapter" ,__func__);
17147 return -EINVAL;
17148 }
17149
17150 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17151 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070017152 if (0 != status)
17153 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070017154 return status;
17155 }
17156
17157 /*Retrieve halHandle*/
17158 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17159
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053017160 /* Flush the PMKID cache in CSR */
17161 if (eHAL_STATUS_SUCCESS !=
17162 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
17163 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
17164 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070017165 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017166 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080017167 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017168}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053017169
17170static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
17171{
17172 int ret;
17173
17174 vos_ssr_protect(__func__);
17175 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
17176 vos_ssr_unprotect(__func__);
17177
17178 return ret;
17179}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017180#endif
17181
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017182#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017183static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17184 struct net_device *dev,
17185 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017186{
17187 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17188 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017189 hdd_context_t *pHddCtx;
17190 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017191
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017192 ENTER();
17193
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017194 if (NULL == pAdapter)
17195 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017196 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017197 return -ENODEV;
17198 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017199 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17200 ret = wlan_hdd_validate_context(pHddCtx);
17201 if (0 != ret)
17202 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017203 return ret;
17204 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017205 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017206 if (NULL == pHddStaCtx)
17207 {
17208 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
17209 return -EINVAL;
17210 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017211
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017212 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17213 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
17214 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017215 // Added for debug on reception of Re-assoc Req.
17216 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
17217 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017218 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017219 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080017220 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017221 }
17222
17223#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080017224 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017225 ftie->ie_len);
17226#endif
17227
17228 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053017229 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
17230 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017231 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017232
17233 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017234 return 0;
17235}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017236
17237static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
17238 struct net_device *dev,
17239 struct cfg80211_update_ft_ies_params *ftie)
17240{
17241 int ret;
17242
17243 vos_ssr_protect(__func__);
17244 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
17245 vos_ssr_unprotect(__func__);
17246
17247 return ret;
17248}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017249#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017250
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017251#ifdef FEATURE_WLAN_SCAN_PNO
17252
17253void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
17254 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
17255{
17256 int ret;
17257 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
17258 hdd_context_t *pHddCtx;
17259
Nirav Shah80830bf2013-12-31 16:35:12 +053017260 ENTER();
17261
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017262 if (NULL == pAdapter)
17263 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053017264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017265 "%s: HDD adapter is Null", __func__);
17266 return ;
17267 }
17268
17269 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17270 if (NULL == pHddCtx)
17271 {
17272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17273 "%s: HDD context is Null!!!", __func__);
17274 return ;
17275 }
17276
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017277 spin_lock(&pHddCtx->schedScan_lock);
17278 if (TRUE == pHddCtx->isWiphySuspended)
17279 {
17280 pHddCtx->isSchedScanUpdatePending = TRUE;
17281 spin_unlock(&pHddCtx->schedScan_lock);
17282 hddLog(VOS_TRACE_LEVEL_INFO,
17283 "%s: Update cfg80211 scan database after it resume", __func__);
17284 return ;
17285 }
17286 spin_unlock(&pHddCtx->schedScan_lock);
17287
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017288 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
17289
17290 if (0 > ret)
17291 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053017292 else
17293 {
17294 /* Acquire wakelock to handle the case where APP's tries to suspend
17295 * immediatly after the driver gets connect request(i.e after pno)
17296 * from supplicant, this result in app's is suspending and not able
17297 * to process the connect request to AP */
17298 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
17299 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017300 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17302 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017303}
17304
17305/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017306 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017307 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017308 */
17309static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
17310{
17311 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
17312 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017313 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017314 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17315 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053017316
17317 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
17318 {
17319 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17320 "%s: PNO is allowed only in STA interface", __func__);
17321 return eHAL_STATUS_FAILURE;
17322 }
17323
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017324 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
17325
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017326 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053017327 * active sessions. PNO is allowed only in case when sap session
17328 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017329 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017330 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
17331 {
17332 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017333 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017334
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017335 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
17336 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
17337 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
17338 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053017339 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
17340 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053017341 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017342 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017343 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017344 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017345 }
17346 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
17347 pAdapterNode = pNext;
17348 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017349 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017350}
17351
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017352void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
17353{
17354 hdd_adapter_t *pAdapter = callbackContext;
17355 hdd_context_t *pHddCtx;
17356
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017357 ENTER();
17358
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017359 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
17360 {
17361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17362 FL("Invalid adapter or adapter has invalid magic"));
17363 return;
17364 }
17365
17366 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17367 if (0 != wlan_hdd_validate_context(pHddCtx))
17368 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017369 return;
17370 }
17371
c_hpothub53c45d2014-08-18 16:53:14 +053017372 if (VOS_STATUS_SUCCESS != status)
17373 {
17374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017375 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053017376 pHddCtx->isPnoEnable = FALSE;
17377 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017378
17379 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
17380 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017381 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017382}
17383
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017384#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
17385 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
17386/**
17387 * hdd_config_sched_scan_plan() - configures the sched scan plans
17388 * from the framework.
17389 * @pno_req: pointer to PNO scan request
17390 * @request: pointer to scan request from framework
17391 *
17392 * Return: None
17393 */
17394static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
17395 struct cfg80211_sched_scan_request *request,
17396 hdd_context_t *hdd_ctx)
17397{
17398 v_U32_t i = 0;
17399
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017400 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017401 for (i = 0; i < request->n_scan_plans; i++)
17402 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017403 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
17404 request->scan_plans[i].iterations;
17405 pno_req->scanTimers.aTimerValues[i].uTimerValue =
17406 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017407 }
17408}
17409#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017410static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017411 struct cfg80211_sched_scan_request *request,
17412 hdd_context_t *hdd_ctx)
17413{
17414 v_U32_t i, temp_int;
17415 /* Driver gets only one time interval which is hardcoded in
17416 * supplicant for 10000ms. Taking power consumption into account 6
17417 * timers will be used, Timervalue is increased exponentially
17418 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
17419 * timer is configurable through INI param gPNOScanTimerRepeatValue.
17420 * If it is set to 0 only one timer will be used and PNO scan cycle
17421 * will be repeated after each interval specified by supplicant
17422 * till PNO is disabled.
17423 */
17424 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017425 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017426 HDD_PNO_SCAN_TIMERS_SET_ONE;
17427 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017428 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017429 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
17430
17431 temp_int = (request->interval)/1000;
17432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17433 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
17434 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017435 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017436 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017437 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017438 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017439 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017440 temp_int *= 2;
17441 }
17442 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017443 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017444}
17445#endif
17446
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017447/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017448 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
17449 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017450 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017451static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017452 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17453{
17454 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017455 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017456 hdd_context_t *pHddCtx;
17457 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053017458 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053017459 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
17460 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017461 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17462 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017463 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017464 hdd_config_t *pConfig = NULL;
17465 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017466
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017467 ENTER();
17468
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017469 if (NULL == pAdapter)
17470 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017472 "%s: HDD adapter is Null", __func__);
17473 return -ENODEV;
17474 }
17475
17476 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017477 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017478
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017479 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017480 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017481 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017482 }
17483
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017484 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017485 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17486 if (NULL == hHal)
17487 {
17488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17489 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017490 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017491 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017492 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17493 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
17494 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053017495 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053017496 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053017497 {
17498 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17499 "%s: aborting the existing scan is unsuccessfull", __func__);
17500 return -EBUSY;
17501 }
17502
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017503 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017504 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017505 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017506 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017507 return -EBUSY;
17508 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017509
c_hpothu37f21312014-04-09 21:49:54 +053017510 if (TRUE == pHddCtx->isPnoEnable)
17511 {
17512 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
17513 FL("already PNO is enabled"));
17514 return -EBUSY;
17515 }
c_hpothu225aa7c2014-10-22 17:45:13 +053017516
17517 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
17518 {
17519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17520 "%s: abort ROC failed ", __func__);
17521 return -EBUSY;
17522 }
17523
c_hpothu37f21312014-04-09 21:49:54 +053017524 pHddCtx->isPnoEnable = TRUE;
17525
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017526 pnoRequest.enable = 1; /*Enable PNO */
17527 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017528
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017529 if (( !pnoRequest.ucNetworksCount ) ||
17530 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017531 {
17532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017533 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017534 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017535 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017536 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017537 goto error;
17538 }
17539
17540 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
17541 {
17542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017543 "%s: Incorrect number of channels %d",
17544 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017545 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017546 goto error;
17547 }
17548
17549 /* Framework provides one set of channels(all)
17550 * common for all saved profile */
17551 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17552 channels_allowed, &num_channels_allowed))
17553 {
17554 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17555 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017556 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017557 goto error;
17558 }
17559 /* Checking each channel against allowed channel list */
17560 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053017561 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017562 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017563 char chList [(request->n_channels*5)+1];
17564 int len;
17565 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017566 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017567 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017568 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017569 if (request->channels[i]->hw_value == channels_allowed[indx])
17570 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017571 if ((!pConfig->enableDFSPnoChnlScan) &&
17572 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
17573 {
17574 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17575 "%s : Dropping DFS channel : %d",
17576 __func__,channels_allowed[indx]);
17577 num_ignore_dfs_ch++;
17578 break;
17579 }
17580
Nirav Shah80830bf2013-12-31 16:35:12 +053017581 valid_ch[num_ch++] = request->channels[i]->hw_value;
17582 len += snprintf(chList+len, 5, "%d ",
17583 request->channels[i]->hw_value);
17584 break ;
17585 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017586 }
17587 }
Nirav Shah80830bf2013-12-31 16:35:12 +053017588 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017589
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017590 /*If all channels are DFS and dropped, then ignore the PNO request*/
17591 if (num_ignore_dfs_ch == request->n_channels)
17592 {
17593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17594 "%s : All requested channels are DFS channels", __func__);
17595 ret = -EINVAL;
17596 goto error;
17597 }
17598 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017599
17600 pnoRequest.aNetworks =
17601 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17602 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017603 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017604 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17605 FL("failed to allocate memory aNetworks %u"),
17606 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17607 goto error;
17608 }
17609 vos_mem_zero(pnoRequest.aNetworks,
17610 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17611
17612 /* Filling per profile params */
17613 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
17614 {
17615 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017616 request->match_sets[i].ssid.ssid_len;
17617
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017618 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
17619 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017620 {
17621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017622 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017623 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017624 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017625 goto error;
17626 }
17627
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017628 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017629 request->match_sets[i].ssid.ssid,
17630 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17632 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017633 i, pnoRequest.aNetworks[i].ssId.ssId);
17634 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
17635 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
17636 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017637
17638 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017639 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
17640 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017641
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017642 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017643 }
17644
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017645 for (i = 0; i < request->n_ssids; i++)
17646 {
17647 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017648 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017649 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017650 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017651 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017652 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017653 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017654 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017655 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017656 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017657 break;
17658 }
17659 j++;
17660 }
17661 }
17662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17663 "Number of hidden networks being Configured = %d",
17664 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080017666 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017667
17668 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17669 if (pnoRequest.p24GProbeTemplate == NULL)
17670 {
17671 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17672 FL("failed to allocate memory p24GProbeTemplate %u"),
17673 SIR_PNO_MAX_PB_REQ_SIZE);
17674 goto error;
17675 }
17676
17677 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17678 if (pnoRequest.p5GProbeTemplate == NULL)
17679 {
17680 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17681 FL("failed to allocate memory p5GProbeTemplate %u"),
17682 SIR_PNO_MAX_PB_REQ_SIZE);
17683 goto error;
17684 }
17685
17686 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17687 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17688
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053017689 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
17690 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017691 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017692 pnoRequest.us24GProbeTemplateLen = request->ie_len;
17693 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
17694 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017695
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017696 pnoRequest.us5GProbeTemplateLen = request->ie_len;
17697 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
17698 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017699 }
17700
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053017701 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017702
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017703 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017704
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017705 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017706 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17707 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017708 pAdapter->pno_req_status = 0;
17709
Nirav Shah80830bf2013-12-31 16:35:12 +053017710 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17711 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017712 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
17713 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053017714
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017715 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017716 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017717 hdd_cfg80211_sched_scan_done_callback, pAdapter);
17718 if (eHAL_STATUS_SUCCESS != status)
17719 {
17720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017721 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017722 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017723 goto error;
17724 }
17725
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017726 ret = wait_for_completion_timeout(
17727 &pAdapter->pno_comp_var,
17728 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17729 if (0 >= ret)
17730 {
17731 // Did not receive the response for PNO enable in time.
17732 // Assuming the PNO enable was success.
17733 // Returning error from here, because we timeout, results
17734 // in side effect of Wifi (Wifi Setting) not to work.
17735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17736 FL("Timed out waiting for PNO to be Enabled"));
17737 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017738 }
17739
17740 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053017741 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017742
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017743error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17745 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053017746 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017747 if (pnoRequest.aNetworks)
17748 vos_mem_free(pnoRequest.aNetworks);
17749 if (pnoRequest.p24GProbeTemplate)
17750 vos_mem_free(pnoRequest.p24GProbeTemplate);
17751 if (pnoRequest.p5GProbeTemplate)
17752 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017753
17754 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017755 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017756}
17757
17758/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017759 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
17760 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017761 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017762static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
17763 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17764{
17765 int ret;
17766
17767 vos_ssr_protect(__func__);
17768 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
17769 vos_ssr_unprotect(__func__);
17770
17771 return ret;
17772}
17773
17774/*
17775 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
17776 * Function to disable PNO
17777 */
17778static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017779 struct net_device *dev)
17780{
17781 eHalStatus status = eHAL_STATUS_FAILURE;
17782 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17783 hdd_context_t *pHddCtx;
17784 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017785 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017786 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017787
17788 ENTER();
17789
17790 if (NULL == pAdapter)
17791 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017792 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017793 "%s: HDD adapter is Null", __func__);
17794 return -ENODEV;
17795 }
17796
17797 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017798
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017799 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017800 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017801 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017802 "%s: HDD context is Null", __func__);
17803 return -ENODEV;
17804 }
17805
17806 /* The return 0 is intentional when isLogpInProgress and
17807 * isLoadUnloadInProgress. We did observe a crash due to a return of
17808 * failure in sched_scan_stop , especially for a case where the unload
17809 * of the happens at the same time. The function __cfg80211_stop_sched_scan
17810 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
17811 * success. If it returns a failure , then its next invocation due to the
17812 * clean up of the second interface will have the dev pointer corresponding
17813 * to the first one leading to a crash.
17814 */
17815 if (pHddCtx->isLogpInProgress)
17816 {
17817 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17818 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053017819 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017820 return ret;
17821 }
17822
Mihir Shete18156292014-03-11 15:38:30 +053017823 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017824 {
17825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17826 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17827 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017828 }
17829
17830 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17831 if (NULL == hHal)
17832 {
17833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17834 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017835 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017836 }
17837
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017838 pnoRequest.enable = 0; /* Disable PNO */
17839 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017840
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017841 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17842 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
17843 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017844
17845 INIT_COMPLETION(pAdapter->pno_comp_var);
17846 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17847 pnoRequest.callbackContext = pAdapter;
17848 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017849 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017850 pAdapter->sessionId,
17851 NULL, pAdapter);
17852 if (eHAL_STATUS_SUCCESS != status)
17853 {
17854 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17855 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017856 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017857 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017858 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017859 ret = wait_for_completion_timeout(
17860 &pAdapter->pno_comp_var,
17861 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17862 if (0 >= ret)
17863 {
17864 // Did not receive the response for PNO disable in time.
17865 // Assuming the PNO disable was success.
17866 // Returning error from here, because we timeout, results
17867 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053017868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017869 FL("Timed out waiting for PNO to be disabled"));
17870 ret = 0;
17871 }
17872
17873 ret = pAdapter->pno_req_status;
17874 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017875
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017876error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017878 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017879
17880 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017881 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017882}
17883
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017884/*
17885 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
17886 * NL interface to disable PNO
17887 */
17888static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
17889 struct net_device *dev)
17890{
17891 int ret;
17892
17893 vos_ssr_protect(__func__);
17894 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
17895 vos_ssr_unprotect(__func__);
17896
17897 return ret;
17898}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017899#endif /*FEATURE_WLAN_SCAN_PNO*/
17900
17901
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017902#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017903#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017904static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17905 struct net_device *dev,
17906 u8 *peer, u8 action_code,
17907 u8 dialog_token,
17908 u16 status_code, u32 peer_capability,
17909 const u8 *buf, size_t len)
17910#else /* TDLS_MGMT_VERSION2 */
17911#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17912static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17913 struct net_device *dev,
17914 const u8 *peer, u8 action_code,
17915 u8 dialog_token, u16 status_code,
17916 u32 peer_capability, bool initiator,
17917 const u8 *buf, size_t len)
17918#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17919static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17920 struct net_device *dev,
17921 const u8 *peer, u8 action_code,
17922 u8 dialog_token, u16 status_code,
17923 u32 peer_capability, const u8 *buf,
17924 size_t len)
17925#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17926static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17927 struct net_device *dev,
17928 u8 *peer, u8 action_code,
17929 u8 dialog_token,
17930 u16 status_code, u32 peer_capability,
17931 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017932#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017933static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17934 struct net_device *dev,
17935 u8 *peer, u8 action_code,
17936 u8 dialog_token,
17937 u16 status_code, const u8 *buf,
17938 size_t len)
17939#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017940#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017941{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017942 hdd_adapter_t *pAdapter;
17943 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017944 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070017945 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080017946 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070017947 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017948 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017949 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017950#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017951 u32 peer_capability = 0;
17952#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017953 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017954 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053017955 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017956
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017957 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17958 if (NULL == pAdapter)
17959 {
17960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17961 "%s: Adapter is NULL",__func__);
17962 return -EINVAL;
17963 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017964 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17965 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
17966 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017967
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017968 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017969 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017970 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017971 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017972 "Invalid arguments");
17973 return -EINVAL;
17974 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017975
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017976 if (pHddCtx->isLogpInProgress)
17977 {
17978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17979 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053017980 wlan_hdd_tdls_set_link_status(pAdapter,
17981 peer,
17982 eTDLS_LINK_IDLE,
17983 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017984 return -EBUSY;
17985 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017986
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017987 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
17988 {
17989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17990 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17991 return -EAGAIN;
17992 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017993
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053017994 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
17995 if (!pHddTdlsCtx) {
17996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17997 "%s: pHddTdlsCtx not valid.", __func__);
17998 }
17999
Hoonki Lee27511902013-03-14 18:19:06 -070018000 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018001 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018002 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070018003 "%s: TDLS mode is disabled OR not enabled in FW."
18004 MAC_ADDRESS_STR " action %d declined.",
18005 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018006 return -ENOTSUPP;
18007 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018008
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018009 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18010
18011 if( NULL == pHddStaCtx )
18012 {
18013 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18014 "%s: HDD station context NULL ",__func__);
18015 return -EINVAL;
18016 }
18017
18018 /* STA should be connected and authenticated
18019 * before sending any TDLS frames
18020 */
18021 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
18022 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
18023 {
18024 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18025 "STA is not connected or unauthenticated. "
18026 "connState %u, uIsAuthenticated %u",
18027 pHddStaCtx->conn_info.connState,
18028 pHddStaCtx->conn_info.uIsAuthenticated);
18029 return -EAGAIN;
18030 }
18031
Hoonki Lee27511902013-03-14 18:19:06 -070018032 /* other than teardown frame, other mgmt frames are not sent if disabled */
18033 if (SIR_MAC_TDLS_TEARDOWN != action_code)
18034 {
18035 /* if tdls_mode is disabled to respond to peer's request */
18036 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
18037 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018038 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070018039 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018040 " TDLS mode is disabled. action %d declined.",
18041 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070018042
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018043 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070018044 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053018045
18046 if (vos_max_concurrent_connections_reached())
18047 {
18048 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
18049 return -EINVAL;
18050 }
Hoonki Lee27511902013-03-14 18:19:06 -070018051 }
18052
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018053 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
18054 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053018055 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018056 {
18057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018058 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018059 " TDLS setup is ongoing. action %d declined.",
18060 __func__, MAC_ADDR_ARRAY(peer), action_code);
18061 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018062 }
18063 }
18064
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018065 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
18066 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080018067 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018068 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18069 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080018070 {
18071 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
18072 we return error code at 'add_station()'. Hence we have this
18073 check again in addtion to add_station().
18074 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018075 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080018076 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018077 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18078 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018079 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
18080 __func__, MAC_ADDR_ARRAY(peer), action_code,
18081 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053018082 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080018083 }
18084 else
18085 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018086 /* maximum reached. tweak to send error code to peer and return
18087 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018088 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018089 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18090 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053018091 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
18092 __func__, MAC_ADDR_ARRAY(peer), status_code,
18093 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070018094 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018095 /* fall through to send setup resp with failure status
18096 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080018097 }
18098 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018099 else
18100 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018101 mutex_lock(&pHddCtx->tdls_lock);
18102 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018103 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018104 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018105 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018106 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070018107 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
18108 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018109 return -EPERM;
18110 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018111 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018112 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018113 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018114
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018116 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018117 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
18118 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018119
Hoonki Leea34dd892013-02-05 22:56:02 -080018120 /*Except teardown responder will not be used so just make 0*/
18121 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018122 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080018123 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018124
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018125 mutex_lock(&pHddCtx->tdls_lock);
18126 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018127
18128 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
18129 responder = pTdlsPeer->is_responder;
18130 else
Hoonki Leea34dd892013-02-05 22:56:02 -080018131 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053018133 "%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 -070018134 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
18135 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018136 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070018137 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080018138 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018139 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018140 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018141
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053018142 /* Discard TDLS setup if peer is removed by user app */
18143 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
18144 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18145 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
18146 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
18147
18148 mutex_lock(&pHddCtx->tdls_lock);
18149 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18150 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
18151 mutex_unlock(&pHddCtx->tdls_lock);
18152 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
18153 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
18154 MAC_ADDR_ARRAY(peer), action_code);
18155 return -EINVAL;
18156 }
18157 mutex_unlock(&pHddCtx->tdls_lock);
18158 }
18159
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018160 /* For explicit trigger of DIS_REQ come out of BMPS for
18161 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070018162 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053018163 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053018164 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
18165 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070018166 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018167 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018169 "%s: Sending frame action_code %u.Disable BMPS", __func__,
18170 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018171 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
18172 if (status != VOS_STATUS_SUCCESS) {
18173 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053018174 } else {
18175 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018176 }
Hoonki Lee14621352013-04-16 17:51:19 -070018177 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018178 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018179 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018180 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
18181 }
18182 }
Hoonki Lee14621352013-04-16 17:51:19 -070018183 }
18184
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018185 /* make sure doesn't call send_mgmt() while it is pending */
18186 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
18187 {
18188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018189 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018190 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018191 ret = -EBUSY;
18192 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018193 }
18194
18195 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018196 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
18197
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018198 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
18199 pAdapter->sessionId, peer, action_code, dialog_token,
18200 status_code, peer_capability, (tANI_U8 *)buf, len,
18201 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018202
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018203 if (VOS_STATUS_SUCCESS != status)
18204 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18206 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018207 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018208 ret = -EINVAL;
18209 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018210 }
18211
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18213 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
18214 WAIT_TIME_TDLS_MGMT);
18215
Hoonki Leed37cbb32013-04-20 00:31:14 -070018216 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
18217 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
18218
18219 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018220 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070018221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070018222 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070018223 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018224 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080018225
18226 if (pHddCtx->isLogpInProgress)
18227 {
18228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18229 "%s: LOGP in Progress. Ignore!!!", __func__);
18230 return -EAGAIN;
18231 }
Abhishek Singh837adf22015-10-01 17:37:37 +053018232 if (rc <= 0)
18233 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
18234 WLAN_LOG_INDICATOR_HOST_DRIVER,
18235 WLAN_LOG_REASON_HDD_TIME_OUT,
18236 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080018237
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018238 ret = -EINVAL;
18239 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018240 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053018241 else
18242 {
18243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18244 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
18245 __func__, rc, pAdapter->mgmtTxCompletionStatus);
18246 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018247
Gopichand Nakkala05922802013-03-14 12:23:19 -070018248 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070018249 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018250 ret = max_sta_failed;
18251 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070018252 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018253
Hoonki Leea34dd892013-02-05 22:56:02 -080018254 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
18255 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018256 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018257 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18258 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018259 }
18260 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
18261 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018262 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018263 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
18264 }
Hoonki Leea34dd892013-02-05 22:56:02 -080018265 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018266
18267 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053018268
18269tx_failed:
18270 /* add_station will be called before sending TDLS_SETUP_REQ and
18271 * TDLS_SETUP_RSP and as part of add_station driver will enable
18272 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
18273 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
18274 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
18275 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
18276 */
18277
18278 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
18279 (SIR_MAC_TDLS_SETUP_RSP == action_code))
18280 wlan_hdd_tdls_check_bmps(pAdapter);
18281 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018282}
18283
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018284#if TDLS_MGMT_VERSION2
18285static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
18286 u8 *peer, u8 action_code, u8 dialog_token,
18287 u16 status_code, u32 peer_capability,
18288 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018289#else /* TDLS_MGMT_VERSION2 */
18290#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18291static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18292 struct net_device *dev,
18293 const u8 *peer, u8 action_code,
18294 u8 dialog_token, u16 status_code,
18295 u32 peer_capability, bool initiator,
18296 const u8 *buf, size_t len)
18297#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18298static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18299 struct net_device *dev,
18300 const u8 *peer, u8 action_code,
18301 u8 dialog_token, u16 status_code,
18302 u32 peer_capability, const u8 *buf,
18303 size_t len)
18304#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18305static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
18306 struct net_device *dev,
18307 u8 *peer, u8 action_code,
18308 u8 dialog_token,
18309 u16 status_code, u32 peer_capability,
18310 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018311#else
18312static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
18313 u8 *peer, u8 action_code, u8 dialog_token,
18314 u16 status_code, const u8 *buf, size_t len)
18315#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018316#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018317{
18318 int ret;
18319
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018320 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018321#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018322 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18323 dialog_token, status_code,
18324 peer_capability, buf, len);
18325#else /* TDLS_MGMT_VERSION2 */
18326#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
18327 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18328 dialog_token, status_code,
18329 peer_capability, initiator,
18330 buf, len);
18331#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
18332 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18333 dialog_token, status_code,
18334 peer_capability, buf, len);
18335#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
18336 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18337 dialog_token, status_code,
18338 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018339#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018340 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
18341 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018342#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018343#endif
18344 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018345
Anand N Sunkad9f80b742015-07-30 20:05:51 +053018346 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018347}
Atul Mittal115287b2014-07-08 13:26:33 +053018348
18349int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018350#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18351 const u8 *peer,
18352#else
Atul Mittal115287b2014-07-08 13:26:33 +053018353 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018354#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018355 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053018356 cfg80211_exttdls_callback callback)
18357{
18358
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018359 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053018360 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018361 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053018362 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18363 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
18364 __func__, MAC_ADDR_ARRAY(peer));
18365
18366 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
18367 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
18368
18369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018370 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
18371 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
18372 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053018373 return -ENOTSUPP;
18374 }
18375
18376 /* To cater the requirement of establishing the TDLS link
18377 * irrespective of the data traffic , get an entry of TDLS peer.
18378 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053018379 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018380 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
18381 if (pTdlsPeer == NULL) {
18382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18383 "%s: peer " MAC_ADDRESS_STR " not existing",
18384 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053018385 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018386 return -EINVAL;
18387 }
18388
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053018389 /* check FW TDLS Off Channel capability */
18390 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053018391 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053018392 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018393 {
18394 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
18395 pTdlsPeer->peerParams.global_operating_class =
18396 tdls_peer_params->global_operating_class;
18397 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
18398 pTdlsPeer->peerParams.min_bandwidth_kbps =
18399 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018400 /* check configured channel is valid, non dfs and
18401 * not current operating channel */
18402 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
18403 tdls_peer_params->channel)) &&
18404 (pHddStaCtx) &&
18405 (tdls_peer_params->channel !=
18406 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018407 {
18408 pTdlsPeer->isOffChannelConfigured = TRUE;
18409 }
18410 else
18411 {
18412 pTdlsPeer->isOffChannelConfigured = FALSE;
18413 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18414 "%s: Configured Tdls Off Channel is not valid", __func__);
18415
18416 }
18417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018418 "%s: tdls_off_channel %d isOffChannelConfigured %d "
18419 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018420 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053018421 pTdlsPeer->isOffChannelConfigured,
18422 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018423 }
18424 else
18425 {
18426 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053018427 "%s: TDLS off channel FW capability %d, "
18428 "host capab %d or Invalid TDLS Peer Params", __func__,
18429 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
18430 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018431 }
18432
Atul Mittal115287b2014-07-08 13:26:33 +053018433 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
18434
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018435 mutex_unlock(&pHddCtx->tdls_lock);
18436
Atul Mittal115287b2014-07-08 13:26:33 +053018437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18438 " %s TDLS Add Force Peer Failed",
18439 __func__);
18440 return -EINVAL;
18441 }
18442 /*EXT TDLS*/
18443
18444 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018445 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18447 " %s TDLS set callback Failed",
18448 __func__);
18449 return -EINVAL;
18450 }
18451
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018452 mutex_unlock(&pHddCtx->tdls_lock);
18453
Atul Mittal115287b2014-07-08 13:26:33 +053018454 return(0);
18455
18456}
18457
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018458int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
18459#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18460 const u8 *peer
18461#else
18462 u8 *peer
18463#endif
18464)
Atul Mittal115287b2014-07-08 13:26:33 +053018465{
18466
18467 hddTdlsPeer_t *pTdlsPeer;
18468 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053018469
Atul Mittal115287b2014-07-08 13:26:33 +053018470 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18471 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
18472 __func__, MAC_ADDR_ARRAY(peer));
18473
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053018474 if (0 != wlan_hdd_validate_context(pHddCtx)) {
18475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
18476 return -EINVAL;
18477 }
18478
Atul Mittal115287b2014-07-08 13:26:33 +053018479 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
18480 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
18481
18482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018483 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
18484 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
18485 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053018486 return -ENOTSUPP;
18487 }
18488
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018489 mutex_lock(&pHddCtx->tdls_lock);
18490 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053018491
18492 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018493 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018494 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018495 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053018496 __func__, MAC_ADDR_ARRAY(peer));
18497 return -EINVAL;
18498 }
18499 else {
18500 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
18501 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053018502 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
18503 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018504 /* if channel switch is configured, reset
18505 the channel for this peer */
18506 if (TRUE == pTdlsPeer->isOffChannelConfigured)
18507 {
18508 pTdlsPeer->peerParams.channel = 0;
18509 pTdlsPeer->isOffChannelConfigured = FALSE;
18510 }
Atul Mittal115287b2014-07-08 13:26:33 +053018511 }
18512
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018513 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018514 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018515 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053018516 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018517 }
Atul Mittal115287b2014-07-08 13:26:33 +053018518
18519 /*EXT TDLS*/
18520
18521 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018522 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18524 " %s TDLS set callback Failed",
18525 __func__);
18526 return -EINVAL;
18527 }
Atul Mittal115287b2014-07-08 13:26:33 +053018528
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018529 mutex_unlock(&pHddCtx->tdls_lock);
18530
18531 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053018532}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018533static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018534#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18535 const u8 *peer,
18536#else
18537 u8 *peer,
18538#endif
18539 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018540{
18541 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18542 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018543 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018544 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018545
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018546 ENTER();
18547
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053018548 if (!pAdapter) {
18549 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
18550 return -EINVAL;
18551 }
18552
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018553 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18554 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
18555 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018556 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018557 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070018559 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018560 return -EINVAL;
18561 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018562
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018563 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018564 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018565 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018566 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018567 }
18568
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018569
18570 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018571 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018572 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018573 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018574 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
18575 "Cannot process TDLS commands",
18576 pHddCtx->cfg_ini->fEnableTDLSSupport,
18577 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018578 return -ENOTSUPP;
18579 }
18580
18581 switch (oper) {
18582 case NL80211_TDLS_ENABLE_LINK:
18583 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018584 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018585 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053018586 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
18587 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053018588 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018589 tANI_U16 numCurrTdlsPeers = 0;
18590 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018591 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018592 tSirMacAddr peerMac;
18593 int channel;
18594 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018595
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18597 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
18598 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018599
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018600 mutex_lock(&pHddCtx->tdls_lock);
18601 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018602 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053018603 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018604 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018605 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18606 " (oper %d) not exsting. ignored",
18607 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18608 return -EINVAL;
18609 }
18610
18611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18612 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18613 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18614 "NL80211_TDLS_ENABLE_LINK");
18615
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018616 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
18617 {
18618 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
18619 MAC_ADDRESS_STR " failed",
18620 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018621 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018622 return -EINVAL;
18623 }
18624
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018625 /* before starting tdls connection, set tdls
18626 * off channel established status to default value */
18627 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018628
18629 mutex_unlock(&pHddCtx->tdls_lock);
18630
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053018631 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018632 /* TDLS Off Channel, Disable tdls channel switch,
18633 when there are more than one tdls link */
18634 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053018635 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018636 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018637 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018638 /* get connected peer and send disable tdls off chan */
18639 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018640 if ((connPeer) &&
18641 (connPeer->isOffChannelSupported == TRUE) &&
18642 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018643 {
18644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18645 "%s: More then one peer connected, Disable "
18646 "TDLS channel switch", __func__);
18647
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018648 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018649 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
18650 channel = connPeer->peerParams.channel;
18651
18652 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018653
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018654 ret = sme_SendTdlsChanSwitchReq(
18655 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018656 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018657 peerMac,
18658 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018659 TDLS_OFF_CHANNEL_BW_OFFSET,
18660 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018661 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018662 hddLog(VOS_TRACE_LEVEL_ERROR,
18663 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018664 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018665 }
18666 else
18667 {
18668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18669 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018670 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018671 "isOffChannelConfigured %d",
18672 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018673 (connPeer ? (connPeer->isOffChannelSupported)
18674 : -1),
18675 (connPeer ? (connPeer->isOffChannelConfigured)
18676 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018677 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018678 }
18679 }
18680
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018681 mutex_lock(&pHddCtx->tdls_lock);
18682 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18683 if ( NULL == pTdlsPeer ) {
18684 mutex_unlock(&pHddCtx->tdls_lock);
18685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18686 "%s: " MAC_ADDRESS_STR
18687 " (oper %d) peer got freed in other context. ignored",
18688 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18689 return -EINVAL;
18690 }
18691 peer_status = pTdlsPeer->link_status;
18692 mutex_unlock(&pHddCtx->tdls_lock);
18693
18694 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018695 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018696 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053018697
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018698 if (0 != wlan_hdd_tdls_get_link_establish_params(
18699 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018700 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018701 return -EINVAL;
18702 }
18703 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018704
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018705 ret = sme_SendTdlsLinkEstablishParams(
18706 WLAN_HDD_GET_HAL_CTX(pAdapter),
18707 pAdapter->sessionId, peer,
18708 &tdlsLinkEstablishParams);
18709 if (ret != VOS_STATUS_SUCCESS) {
18710 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
18711 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018712 /* Send TDLS peer UAPSD capabilities to the firmware and
18713 * register with the TL on after the response for this operation
18714 * is received .
18715 */
18716 ret = wait_for_completion_interruptible_timeout(
18717 &pAdapter->tdls_link_establish_req_comp,
18718 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053018719
18720 mutex_lock(&pHddCtx->tdls_lock);
18721 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18722 if ( NULL == pTdlsPeer ) {
18723 mutex_unlock(&pHddCtx->tdls_lock);
18724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18725 "%s %d: " MAC_ADDRESS_STR
18726 " (oper %d) peer got freed in other context. ignored",
18727 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
18728 (int)oper);
18729 return -EINVAL;
18730 }
18731 peer_status = pTdlsPeer->link_status;
18732 mutex_unlock(&pHddCtx->tdls_lock);
18733
18734 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018735 {
18736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018737 FL("Link Establish Request Failed Status %ld"),
18738 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018739 return -EINVAL;
18740 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018741 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018742
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018743 mutex_lock(&pHddCtx->tdls_lock);
18744 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18745 if ( NULL == pTdlsPeer ) {
18746 mutex_unlock(&pHddCtx->tdls_lock);
18747 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18748 "%s: " MAC_ADDRESS_STR
18749 " (oper %d) peer got freed in other context. ignored",
18750 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18751 return -EINVAL;
18752 }
18753
Atul Mittal115287b2014-07-08 13:26:33 +053018754 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18755 eTDLS_LINK_CONNECTED,
18756 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018757 staDesc.ucSTAId = pTdlsPeer->staId;
18758 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053018759
18760 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18761 "%s: tdlsLinkEstablishParams of peer "
18762 MAC_ADDRESS_STR "uapsdQueues: %d"
18763 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
18764 "isResponder: %d peerstaId: %d",
18765 __func__,
18766 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
18767 tdlsLinkEstablishParams.uapsdQueues,
18768 tdlsLinkEstablishParams.qos,
18769 tdlsLinkEstablishParams.maxSp,
18770 tdlsLinkEstablishParams.isBufSta,
18771 tdlsLinkEstablishParams.isOffChannelSupported,
18772 tdlsLinkEstablishParams.isResponder,
18773 pTdlsPeer->staId);
18774
18775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18776 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
18777 __func__,
18778 staDesc.ucSTAId,
18779 staDesc.ucQosEnabled);
18780
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018781 ret = WLANTL_UpdateTdlsSTAClient(
18782 pHddCtx->pvosContext,
18783 &staDesc);
18784 if (ret != VOS_STATUS_SUCCESS) {
18785 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
18786 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053018787
Gopichand Nakkala471708b2013-06-04 20:03:01 +053018788 /* Mark TDLS client Authenticated .*/
18789 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
18790 pTdlsPeer->staId,
18791 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018792 if (VOS_STATUS_SUCCESS == status)
18793 {
Hoonki Lee14621352013-04-16 17:51:19 -070018794 if (pTdlsPeer->is_responder == 0)
18795 {
18796 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018797 tdlsConnInfo_t *tdlsInfo;
18798
18799 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
18800
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018801 if (!vos_timer_is_initialized(
18802 &pTdlsPeer->initiatorWaitTimeoutTimer))
18803 {
18804 /* Initialize initiator wait callback */
18805 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018806 &pTdlsPeer->initiatorWaitTimeoutTimer,
18807 VOS_TIMER_TYPE_SW,
18808 wlan_hdd_tdls_initiator_wait_cb,
18809 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018810 }
Hoonki Lee14621352013-04-16 17:51:19 -070018811 wlan_hdd_tdls_timer_restart(pAdapter,
18812 &pTdlsPeer->initiatorWaitTimeoutTimer,
18813 WAIT_TIME_TDLS_INITIATOR);
18814 /* suspend initiator TX until it receives direct packet from the
18815 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018816 ret = WLANTL_SuspendDataTx(
18817 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18818 &staId, NULL);
18819 if (ret != VOS_STATUS_SUCCESS) {
18820 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
18821 }
Hoonki Lee14621352013-04-16 17:51:19 -070018822 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018823
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018824 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018825 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018826 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018827 suppChannelLen =
18828 tdlsLinkEstablishParams.supportedChannelsLen;
18829
18830 if ((suppChannelLen > 0) &&
18831 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
18832 {
18833 tANI_U8 suppPeerChannel = 0;
18834 int i = 0;
18835 for (i = 0U; i < suppChannelLen; i++)
18836 {
18837 suppPeerChannel =
18838 tdlsLinkEstablishParams.supportedChannels[i];
18839
18840 pTdlsPeer->isOffChannelSupported = FALSE;
18841 if (suppPeerChannel ==
18842 pTdlsPeer->peerParams.channel)
18843 {
18844 pTdlsPeer->isOffChannelSupported = TRUE;
18845 break;
18846 }
18847 }
18848 }
18849 else
18850 {
18851 pTdlsPeer->isOffChannelSupported = FALSE;
18852 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018853 }
18854 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18855 "%s: TDLS channel switch request for channel "
18856 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018857 "%d isOffChannelSupported %d", __func__,
18858 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018859 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018860 suppChannelLen,
18861 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018862
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018863 /* TDLS Off Channel, Enable tdls channel switch,
18864 when their is only one tdls link and it supports */
18865 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18866 if ((numCurrTdlsPeers == 1) &&
18867 (TRUE == pTdlsPeer->isOffChannelSupported) &&
18868 (TRUE == pTdlsPeer->isOffChannelConfigured))
18869 {
18870 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18871 "%s: Send TDLS channel switch request for channel %d",
18872 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018873
18874 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018875 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
18876 channel = pTdlsPeer->peerParams.channel;
18877
18878 mutex_unlock(&pHddCtx->tdls_lock);
18879
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018880 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
18881 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018882 peerMac,
18883 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018884 TDLS_OFF_CHANNEL_BW_OFFSET,
18885 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018886 if (ret != VOS_STATUS_SUCCESS) {
18887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
18888 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018889 }
18890 else
18891 {
18892 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18893 "%s: TDLS channel switch request not sent"
18894 " numCurrTdlsPeers %d "
18895 "isOffChannelSupported %d "
18896 "isOffChannelConfigured %d",
18897 __func__, numCurrTdlsPeers,
18898 pTdlsPeer->isOffChannelSupported,
18899 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018900 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018901 }
18902
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018903 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018904 else
18905 mutex_unlock(&pHddCtx->tdls_lock);
18906
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018907 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018908
18909 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018910 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
18911 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018912 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018913 int ac;
18914 uint8 ucAc[4] = { WLANTL_AC_VO,
18915 WLANTL_AC_VI,
18916 WLANTL_AC_BK,
18917 WLANTL_AC_BE };
18918 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
18919 for(ac=0; ac < 4; ac++)
18920 {
18921 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18922 pTdlsPeer->staId, ucAc[ac],
18923 tlTid[ac], tlTid[ac], 0, 0,
18924 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018925 if (status != VOS_STATUS_SUCCESS) {
18926 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
18927 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018928 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018929 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018930 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018931
Bhargav Shah66896792015-10-01 18:17:37 +053018932 /* stop TCP delack timer if TDLS is enable */
18933 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18934 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053018935 hdd_wlan_tdls_enable_link_event(peer,
18936 pTdlsPeer->isOffChannelSupported,
18937 pTdlsPeer->isOffChannelConfigured,
18938 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018939 }
18940 break;
18941 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080018942 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018943 tANI_U16 numCurrTdlsPeers = 0;
18944 hddTdlsPeer_t *connPeer = NULL;
18945
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018946 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18947 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
18948 __func__, MAC_ADDR_ARRAY(peer));
18949
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018950 mutex_lock(&pHddCtx->tdls_lock);
18951 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018952
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018953
Sunil Dutt41de4e22013-11-14 18:09:02 +053018954 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018955 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018956 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18957 " (oper %d) not exsting. ignored",
18958 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18959 return -EINVAL;
18960 }
18961
18962 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18963 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18964 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18965 "NL80211_TDLS_DISABLE_LINK");
18966
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018967 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080018968 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018969 long status;
18970
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018971 /* set tdls off channel status to false for this peer */
18972 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053018973 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18974 eTDLS_LINK_TEARING,
18975 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
18976 eTDLS_LINK_UNSPECIFIED:
18977 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018978 mutex_unlock(&pHddCtx->tdls_lock);
18979
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018980 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
18981
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018982 status = sme_DeleteTdlsPeerSta(
18983 WLAN_HDD_GET_HAL_CTX(pAdapter),
18984 pAdapter->sessionId, peer );
18985 if (status != VOS_STATUS_SUCCESS) {
18986 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
18987 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018988
18989 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
18990 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018991
18992 mutex_lock(&pHddCtx->tdls_lock);
18993 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18994 if ( NULL == pTdlsPeer ) {
18995 mutex_unlock(&pHddCtx->tdls_lock);
18996 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18997 " peer was freed in other context",
18998 __func__, MAC_ADDR_ARRAY(peer));
18999 return -EINVAL;
19000 }
19001
Atul Mittal271a7652014-09-12 13:18:22 +053019002 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053019003 eTDLS_LINK_IDLE,
19004 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019005 mutex_unlock(&pHddCtx->tdls_lock);
19006
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019007 if (status <= 0)
19008 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19010 "%s: Del station failed status %ld",
19011 __func__, status);
19012 return -EPERM;
19013 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019014
19015 /* TDLS Off Channel, Enable tdls channel switch,
19016 when their is only one tdls link and it supports */
19017 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19018 if (numCurrTdlsPeers == 1)
19019 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019020 tSirMacAddr peerMac;
19021 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053019022
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019023 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019024 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053019025
19026 if (connPeer == NULL) {
19027 mutex_unlock(&pHddCtx->tdls_lock);
19028 hddLog(VOS_TRACE_LEVEL_ERROR,
19029 "%s connPeer is NULL", __func__);
19030 return -EINVAL;
19031 }
19032
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019033 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
19034 channel = connPeer->peerParams.channel;
19035
19036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19037 "%s: TDLS channel switch "
19038 "isOffChannelSupported %d "
19039 "isOffChannelConfigured %d "
19040 "isOffChannelEstablished %d",
19041 __func__,
19042 (connPeer ? connPeer->isOffChannelSupported : -1),
19043 (connPeer ? connPeer->isOffChannelConfigured : -1),
19044 (connPeer ? connPeer->isOffChannelEstablished : -1));
19045
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019046 if ((connPeer) &&
19047 (connPeer->isOffChannelSupported == TRUE) &&
19048 (connPeer->isOffChannelConfigured == TRUE))
19049 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019050 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019051 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019052 status = sme_SendTdlsChanSwitchReq(
19053 WLAN_HDD_GET_HAL_CTX(pAdapter),
19054 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019055 peerMac,
19056 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019057 TDLS_OFF_CHANNEL_BW_OFFSET,
19058 TDLS_CHANNEL_SWITCH_ENABLE);
19059 if (status != VOS_STATUS_SUCCESS) {
19060 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
19061 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019062 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019063 else
19064 mutex_unlock(&pHddCtx->tdls_lock);
19065 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019066 else
19067 {
19068 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19069 "%s: TDLS channel switch request not sent "
19070 "numCurrTdlsPeers %d ",
19071 __func__, numCurrTdlsPeers);
19072 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019073 }
19074 else
19075 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053019076 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19078 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080019079 }
Bhargav Shah66896792015-10-01 18:17:37 +053019080 if (numCurrTdlsPeers == 0) {
19081 /* start TCP delack timer if TDLS is disable */
19082 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
19083 hdd_manage_delack_timer(pHddCtx);
19084 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019085 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019086 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019087 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019088 {
Atul Mittal115287b2014-07-08 13:26:33 +053019089 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019090
Atul Mittal115287b2014-07-08 13:26:33 +053019091 if (0 != status)
19092 {
19093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019094 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053019095 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019096 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053019097 break;
19098 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019099 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053019100 {
Atul Mittal115287b2014-07-08 13:26:33 +053019101 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
19102 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019103 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053019104 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019105
Atul Mittal115287b2014-07-08 13:26:33 +053019106 if (0 != status)
19107 {
19108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019109 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053019110 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053019111 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053019112 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053019113 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019114 case NL80211_TDLS_DISCOVERY_REQ:
19115 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019116 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019117 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019118 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019119 return -ENOTSUPP;
19120 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019121 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19122 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019123 return -ENOTSUPP;
19124 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019125
19126 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019127 return 0;
19128}
Chilam NG571c65a2013-01-19 12:27:36 +053019129
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019130static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019131#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19132 const u8 *peer,
19133#else
19134 u8 *peer,
19135#endif
19136 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019137{
19138 int ret;
19139
19140 vos_ssr_protect(__func__);
19141 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
19142 vos_ssr_unprotect(__func__);
19143
19144 return ret;
19145}
19146
Chilam NG571c65a2013-01-19 12:27:36 +053019147int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
19148 struct net_device *dev, u8 *peer)
19149{
Arif Hussaina7c8e412013-11-20 11:06:42 -080019150 hddLog(VOS_TRACE_LEVEL_INFO,
19151 "tdls send discover req: "MAC_ADDRESS_STR,
19152 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019153#if TDLS_MGMT_VERSION2
19154 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19155 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19156#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019157#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19158 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19159 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
19160#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19161 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19162 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19163#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19164 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19165 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
19166#else
Chilam NG571c65a2013-01-19 12:27:36 +053019167 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
19168 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019169#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019170#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053019171}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019172#endif
19173
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019174#ifdef WLAN_FEATURE_GTK_OFFLOAD
19175/*
19176 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
19177 * Callback rountine called upon receiving response for
19178 * get offload info
19179 */
19180void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
19181 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
19182{
19183
19184 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019185 tANI_U8 tempReplayCounter[8];
19186 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019187
19188 ENTER();
19189
19190 if (NULL == pAdapter)
19191 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019193 "%s: HDD adapter is Null", __func__);
19194 return ;
19195 }
19196
19197 if (NULL == pGtkOffloadGetInfoRsp)
19198 {
19199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19200 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
19201 return ;
19202 }
19203
19204 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
19205 {
19206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19207 "%s: wlan Failed to get replay counter value",
19208 __func__);
19209 return ;
19210 }
19211
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019212 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19213 /* Update replay counter */
19214 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
19215 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19216
19217 {
19218 /* changing from little to big endian since supplicant
19219 * works on big endian format
19220 */
19221 int i;
19222 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
19223
19224 for (i = 0; i < 8; i++)
19225 {
19226 tempReplayCounter[7-i] = (tANI_U8)p[i];
19227 }
19228 }
19229
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019230 /* Update replay counter to NL */
19231 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019232 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019233}
19234
19235/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019236 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019237 * This function is used to offload GTK rekeying job to the firmware.
19238 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019239int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019240 struct cfg80211_gtk_rekey_data *data)
19241{
19242 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19243 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19244 hdd_station_ctx_t *pHddStaCtx;
19245 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019246 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019247 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019248 eHalStatus status = eHAL_STATUS_FAILURE;
19249
19250 ENTER();
19251
19252 if (NULL == pAdapter)
19253 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019254 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019255 "%s: HDD adapter is Null", __func__);
19256 return -ENODEV;
19257 }
19258
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019259 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19260 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
19261 pAdapter->sessionId, pAdapter->device_mode));
19262
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019263 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019264 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019265 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019266 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019267 }
19268
19269 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19270 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19271 if (NULL == hHal)
19272 {
19273 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19274 "%s: HAL context is Null!!!", __func__);
19275 return -EAGAIN;
19276 }
19277
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019278 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
19279 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
19280 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
19281 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019282 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019283 {
19284 /* changing from big to little endian since driver
19285 * works on little endian format
19286 */
19287 tANI_U8 *p =
19288 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
19289 int i;
19290
19291 for (i = 0; i < 8; i++)
19292 {
19293 p[7-i] = data->replay_ctr[i];
19294 }
19295 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019296
19297 if (TRUE == pHddCtx->hdd_wlan_suspended)
19298 {
19299 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019300 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
19301 sizeof (tSirGtkOffloadParams));
19302 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019303 pAdapter->sessionId);
19304
19305 if (eHAL_STATUS_SUCCESS != status)
19306 {
19307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19308 "%s: sme_SetGTKOffload failed, returned %d",
19309 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053019310
19311 /* Need to clear any trace of key value in the memory.
19312 * Thus zero out the memory even though it is local
19313 * variable.
19314 */
19315 vos_mem_zero(&hddGtkOffloadReqParams,
19316 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019317 return status;
19318 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019319 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19320 "%s: sme_SetGTKOffload successfull", __func__);
19321 }
19322 else
19323 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19325 "%s: wlan not suspended GTKOffload request is stored",
19326 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019327 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019328
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053019329 /* Need to clear any trace of key value in the memory.
19330 * Thus zero out the memory even though it is local
19331 * variable.
19332 */
19333 vos_mem_zero(&hddGtkOffloadReqParams,
19334 sizeof(hddGtkOffloadReqParams));
19335
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019336 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053019337 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019338}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019339
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019340int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
19341 struct cfg80211_gtk_rekey_data *data)
19342{
19343 int ret;
19344
19345 vos_ssr_protect(__func__);
19346 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
19347 vos_ssr_unprotect(__func__);
19348
19349 return ret;
19350}
19351#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019352/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019353 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019354 * This function is used to set access control policy
19355 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019356static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
19357 struct net_device *dev,
19358 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019359{
19360 int i;
19361 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19362 hdd_hostapd_state_t *pHostapdState;
19363 tsap_Config_t *pConfig;
19364 v_CONTEXT_t pVosContext = NULL;
19365 hdd_context_t *pHddCtx;
19366 int status;
19367
19368 ENTER();
19369
19370 if (NULL == pAdapter)
19371 {
19372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19373 "%s: HDD adapter is Null", __func__);
19374 return -ENODEV;
19375 }
19376
19377 if (NULL == params)
19378 {
19379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19380 "%s: params is Null", __func__);
19381 return -EINVAL;
19382 }
19383
19384 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19385 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019386 if (0 != status)
19387 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019388 return status;
19389 }
19390
19391 pVosContext = pHddCtx->pvosContext;
19392 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
19393
19394 if (NULL == pHostapdState)
19395 {
19396 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19397 "%s: pHostapdState is Null", __func__);
19398 return -EINVAL;
19399 }
19400
19401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
19402 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019403 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19404 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
19405 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019406
19407 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
19408 {
19409 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
19410
19411 /* default value */
19412 pConfig->num_accept_mac = 0;
19413 pConfig->num_deny_mac = 0;
19414
19415 /**
19416 * access control policy
19417 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
19418 * listed in hostapd.deny file.
19419 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
19420 * listed in hostapd.accept file.
19421 */
19422 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
19423 {
19424 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
19425 }
19426 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
19427 {
19428 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
19429 }
19430 else
19431 {
19432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19433 "%s:Acl Policy : %d is not supported",
19434 __func__, params->acl_policy);
19435 return -ENOTSUPP;
19436 }
19437
19438 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
19439 {
19440 pConfig->num_accept_mac = params->n_acl_entries;
19441 for (i = 0; i < params->n_acl_entries; i++)
19442 {
19443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19444 "** Add ACL MAC entry %i in WhiletList :"
19445 MAC_ADDRESS_STR, i,
19446 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
19447
19448 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
19449 sizeof(qcmacaddr));
19450 }
19451 }
19452 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
19453 {
19454 pConfig->num_deny_mac = params->n_acl_entries;
19455 for (i = 0; i < params->n_acl_entries; i++)
19456 {
19457 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19458 "** Add ACL MAC entry %i in BlackList :"
19459 MAC_ADDRESS_STR, i,
19460 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
19461
19462 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
19463 sizeof(qcmacaddr));
19464 }
19465 }
19466
19467 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
19468 {
19469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19470 "%s: SAP Set Mac Acl fail", __func__);
19471 return -EINVAL;
19472 }
19473 }
19474 else
19475 {
19476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053019477 "%s: Invalid device_mode = %s (%d)",
19478 __func__, hdd_device_modetoString(pAdapter->device_mode),
19479 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019480 return -EINVAL;
19481 }
19482
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019483 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019484 return 0;
19485}
19486
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019487static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
19488 struct net_device *dev,
19489 const struct cfg80211_acl_data *params)
19490{
19491 int ret;
19492 vos_ssr_protect(__func__);
19493 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
19494 vos_ssr_unprotect(__func__);
19495
19496 return ret;
19497}
19498
Leo Chang9056f462013-08-01 19:21:11 -070019499#ifdef WLAN_NL80211_TESTMODE
19500#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070019501void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070019502(
19503 void *pAdapter,
19504 void *indCont
19505)
19506{
Leo Changd9df8aa2013-09-26 13:32:26 -070019507 tSirLPHBInd *lphbInd;
19508 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053019509 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070019510
19511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019512 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070019513
c_hpothu73f35e62014-04-18 13:40:08 +053019514 if (pAdapter == NULL)
19515 {
19516 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19517 "%s: pAdapter is NULL\n",__func__);
19518 return;
19519 }
19520
Leo Chang9056f462013-08-01 19:21:11 -070019521 if (NULL == indCont)
19522 {
19523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019524 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070019525 return;
19526 }
19527
c_hpothu73f35e62014-04-18 13:40:08 +053019528 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070019529 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070019530 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053019531 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070019532 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070019533 GFP_ATOMIC);
19534 if (!skb)
19535 {
19536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19537 "LPHB timeout, NL buffer alloc fail");
19538 return;
19539 }
19540
Leo Changac3ba772013-10-07 09:47:04 -070019541 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070019542 {
19543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19544 "WLAN_HDD_TM_ATTR_CMD put fail");
19545 goto nla_put_failure;
19546 }
Leo Changac3ba772013-10-07 09:47:04 -070019547 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070019548 {
19549 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19550 "WLAN_HDD_TM_ATTR_TYPE put fail");
19551 goto nla_put_failure;
19552 }
Leo Changac3ba772013-10-07 09:47:04 -070019553 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070019554 sizeof(tSirLPHBInd), lphbInd))
19555 {
19556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19557 "WLAN_HDD_TM_ATTR_DATA put fail");
19558 goto nla_put_failure;
19559 }
Leo Chang9056f462013-08-01 19:21:11 -070019560 cfg80211_testmode_event(skb, GFP_ATOMIC);
19561 return;
19562
19563nla_put_failure:
19564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19565 "NLA Put fail");
19566 kfree_skb(skb);
19567
19568 return;
19569}
19570#endif /* FEATURE_WLAN_LPHB */
19571
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019572static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070019573{
19574 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
19575 int err = 0;
19576#ifdef FEATURE_WLAN_LPHB
19577 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070019578 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019579
19580 ENTER();
19581
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019582 err = wlan_hdd_validate_context(pHddCtx);
19583 if (0 != err)
19584 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019585 return err;
19586 }
Leo Chang9056f462013-08-01 19:21:11 -070019587#endif /* FEATURE_WLAN_LPHB */
19588
19589 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
19590 if (err)
19591 {
19592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19593 "%s Testmode INV ATTR", __func__);
19594 return err;
19595 }
19596
19597 if (!tb[WLAN_HDD_TM_ATTR_CMD])
19598 {
19599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19600 "%s Testmode INV CMD", __func__);
19601 return -EINVAL;
19602 }
19603
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019604 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19605 TRACE_CODE_HDD_CFG80211_TESTMODE,
19606 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070019607 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
19608 {
19609#ifdef FEATURE_WLAN_LPHB
19610 /* Low Power Heartbeat configuration request */
19611 case WLAN_HDD_TM_CMD_WLAN_HB:
19612 {
19613 int buf_len;
19614 void *buf;
19615 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080019616 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070019617
19618 if (!tb[WLAN_HDD_TM_ATTR_DATA])
19619 {
19620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19621 "%s Testmode INV DATA", __func__);
19622 return -EINVAL;
19623 }
19624
19625 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
19626 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080019627
Manjeet Singh3c577442017-02-10 19:03:38 +053019628 if (buf_len > sizeof(*hb_params)) {
19629 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
19630 buf_len);
19631 return -ERANGE;
19632 }
19633
Amar Singhal05852702014-02-04 14:40:00 -080019634 hb_params_temp =(tSirLPHBReq *)buf;
19635 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
19636 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
19637 return -EINVAL;
19638
Leo Chang9056f462013-08-01 19:21:11 -070019639 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
19640 if (NULL == hb_params)
19641 {
19642 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19643 "%s Request Buffer Alloc Fail", __func__);
19644 return -EINVAL;
19645 }
19646
19647 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070019648 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
19649 hb_params,
19650 wlan_hdd_cfg80211_lphb_ind_handler);
19651 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070019652 {
Leo Changd9df8aa2013-09-26 13:32:26 -070019653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19654 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070019655 vos_mem_free(hb_params);
19656 }
Leo Chang9056f462013-08-01 19:21:11 -070019657 return 0;
19658 }
19659#endif /* FEATURE_WLAN_LPHB */
19660 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19662 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070019663 return -EOPNOTSUPP;
19664 }
19665
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019666 EXIT();
19667 return err;
Leo Chang9056f462013-08-01 19:21:11 -070019668}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019669
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053019670static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
19671#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
19672 struct wireless_dev *wdev,
19673#endif
19674 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019675{
19676 int ret;
19677
19678 vos_ssr_protect(__func__);
19679 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
19680 vos_ssr_unprotect(__func__);
19681
19682 return ret;
19683}
Leo Chang9056f462013-08-01 19:21:11 -070019684#endif /* CONFIG_NL80211_TESTMODE */
19685
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053019686extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019687static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019688 struct net_device *dev,
19689 int idx, struct survey_info *survey)
19690{
19691 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19692 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053019693 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019694 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053019695 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019696 v_S7_t snr,rssi;
19697 int status, i, j, filled = 0;
19698
19699 ENTER();
19700
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019701 if (NULL == pAdapter)
19702 {
19703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19704 "%s: HDD adapter is Null", __func__);
19705 return -ENODEV;
19706 }
19707
19708 if (NULL == wiphy)
19709 {
19710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19711 "%s: wiphy is Null", __func__);
19712 return -ENODEV;
19713 }
19714
19715 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19716 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019717 if (0 != status)
19718 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019719 return status;
19720 }
19721
Mihir Sheted9072e02013-08-21 17:02:29 +053019722 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19723
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019724 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053019725 0 != pAdapter->survey_idx ||
19726 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019727 {
19728 /* The survey dump ops when implemented completely is expected to
19729 * return a survey of all channels and the ops is called by the
19730 * kernel with incremental values of the argument 'idx' till it
19731 * returns -ENONET. But we can only support the survey for the
19732 * operating channel for now. survey_idx is used to track
19733 * that the ops is called only once and then return -ENONET for
19734 * the next iteration
19735 */
19736 pAdapter->survey_idx = 0;
19737 return -ENONET;
19738 }
19739
Mukul Sharma9d5233b2015-06-11 20:28:20 +053019740 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
19741 {
19742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19743 "%s: Roaming in progress, hence return ", __func__);
19744 return -ENONET;
19745 }
19746
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019747 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19748
19749 wlan_hdd_get_snr(pAdapter, &snr);
19750 wlan_hdd_get_rssi(pAdapter, &rssi);
19751
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019752 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19753 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
19754 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019755 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
19756 hdd_wlan_get_freq(channel, &freq);
19757
19758
19759 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
19760 {
19761 if (NULL == wiphy->bands[i])
19762 {
19763 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
19764 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
19765 continue;
19766 }
19767
19768 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
19769 {
19770 struct ieee80211_supported_band *band = wiphy->bands[i];
19771
19772 if (band->channels[j].center_freq == (v_U16_t)freq)
19773 {
19774 survey->channel = &band->channels[j];
19775 /* The Rx BDs contain SNR values in dB for the received frames
19776 * while the supplicant expects noise. So we calculate and
19777 * return the value of noise (dBm)
19778 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
19779 */
19780 survey->noise = rssi - snr;
19781 survey->filled = SURVEY_INFO_NOISE_DBM;
19782 filled = 1;
19783 }
19784 }
19785 }
19786
19787 if (filled)
19788 pAdapter->survey_idx = 1;
19789 else
19790 {
19791 pAdapter->survey_idx = 0;
19792 return -ENONET;
19793 }
19794
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019795 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019796 return 0;
19797}
19798
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019799static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
19800 struct net_device *dev,
19801 int idx, struct survey_info *survey)
19802{
19803 int ret;
19804
19805 vos_ssr_protect(__func__);
19806 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
19807 vos_ssr_unprotect(__func__);
19808
19809 return ret;
19810}
19811
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019812/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019813 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019814 * this is called when cfg80211 driver resume
19815 * driver updates latest sched_scan scan result(if any) to cfg80211 database
19816 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019817int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019818{
19819 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19820 hdd_adapter_t *pAdapter;
19821 hdd_adapter_list_node_t *pAdapterNode, *pNext;
19822 VOS_STATUS status = VOS_STATUS_SUCCESS;
19823
19824 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019825
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019826 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019827 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019828 return 0;
19829 }
19830
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019831 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
19832 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053019833
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053019834 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053019835 {
19836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19837 "%s: Resume SoftAP", __func__);
19838 hdd_set_wlan_suspend_mode(false);
19839 }
19840
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019841 spin_lock(&pHddCtx->schedScan_lock);
19842 pHddCtx->isWiphySuspended = FALSE;
19843 if (TRUE != pHddCtx->isSchedScanUpdatePending)
19844 {
19845 spin_unlock(&pHddCtx->schedScan_lock);
19846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19847 "%s: Return resume is not due to PNO indication", __func__);
19848 return 0;
19849 }
19850 // Reset flag to avoid updatating cfg80211 data old results again
19851 pHddCtx->isSchedScanUpdatePending = FALSE;
19852 spin_unlock(&pHddCtx->schedScan_lock);
19853
19854 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
19855
19856 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
19857 {
19858 pAdapter = pAdapterNode->pAdapter;
19859 if ( (NULL != pAdapter) &&
19860 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
19861 {
19862 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019863 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19865 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019866 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019867 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019868 {
19869 /* Acquire wakelock to handle the case where APP's tries to
19870 * suspend immediately after updating the scan results. Whis
19871 * results in app's is in suspended state and not able to
19872 * process the connect request to AP
19873 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053019874 hdd_prevent_suspend_timeout(2000,
19875 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019876 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019877 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019878
19879 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19880 "%s : cfg80211 scan result database updated", __func__);
19881
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019882 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019883 return 0;
19884
19885 }
19886 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19887 pAdapterNode = pNext;
19888 }
19889
19890 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19891 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019892 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019893 return 0;
19894}
19895
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019896int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
19897{
19898 int ret;
19899
19900 vos_ssr_protect(__func__);
19901 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
19902 vos_ssr_unprotect(__func__);
19903
19904 return ret;
19905}
19906
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019907/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019908 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019909 * this is called when cfg80211 driver suspends
19910 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019911int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019912 struct cfg80211_wowlan *wow)
19913{
19914 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019915 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019916
19917 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019918
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019919 ret = wlan_hdd_validate_context(pHddCtx);
19920 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019921 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019922 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019923 }
19924
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053019925 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053019926 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19927 "%s: Suspend SoftAP", __func__);
19928 hdd_set_wlan_suspend_mode(true);
19929 }
19930
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019931
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019932 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19933 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
19934 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019935 pHddCtx->isWiphySuspended = TRUE;
19936
19937 EXIT();
19938
19939 return 0;
19940}
19941
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019942int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
19943 struct cfg80211_wowlan *wow)
19944{
19945 int ret;
19946
19947 vos_ssr_protect(__func__);
19948 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
19949 vos_ssr_unprotect(__func__);
19950
19951 return ret;
19952}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019953
19954#ifdef FEATURE_OEM_DATA_SUPPORT
19955static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019956 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019957{
19958 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19959
19960 ENTER();
19961
19962 if (wlan_hdd_validate_context(pHddCtx)) {
19963 return;
19964 }
19965 if (!pMsg)
19966 {
19967 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
19968 return;
19969 }
19970
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019971 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019972
19973 EXIT();
19974 return;
19975
19976}
19977
19978void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019979 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019980{
19981 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19982
19983 ENTER();
19984
19985 if (wlan_hdd_validate_context(pHddCtx)) {
19986 return;
19987 }
19988
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019989 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019990
19991 switch(evType) {
19992 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019993 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019994 break;
19995 default:
19996 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
19997 break;
19998 }
19999 EXIT();
20000}
20001#endif
20002
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020003#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20004 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020005/**
20006 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
20007 * @wiphy: Pointer to wiphy
20008 * @wdev: Pointer to wireless device structure
20009 *
20010 * This function is used to abort an ongoing scan
20011 *
20012 * Return: None
20013 */
20014static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
20015 struct wireless_dev *wdev)
20016{
20017 struct net_device *dev = wdev->netdev;
20018 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
20019 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
20020 int ret;
20021
20022 ENTER();
20023
20024 if (NULL == adapter) {
20025 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
20026 return;
20027 }
20028
20029 ret = wlan_hdd_validate_context(hdd_ctx);
20030 if (0 != ret)
20031 return;
20032
20033 wlan_hdd_scan_abort(adapter);
20034
20035 return;
20036}
20037
20038/**
20039 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
20040 * @wiphy: Pointer to wiphy
20041 * @wdev: Pointer to wireless device structure
20042 *
20043 * Return: None
20044 */
20045void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
20046 struct wireless_dev *wdev)
20047{
20048 vos_ssr_protect(__func__);
20049 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
20050 vos_ssr_unprotect(__func__);
20051
20052 return;
20053}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020054#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020055
Jeff Johnson295189b2012-06-20 16:38:30 -070020056/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020057static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070020058{
20059 .add_virtual_intf = wlan_hdd_add_virtual_intf,
20060 .del_virtual_intf = wlan_hdd_del_virtual_intf,
20061 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
20062 .change_station = wlan_hdd_change_station,
20063#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
20064 .add_beacon = wlan_hdd_cfg80211_add_beacon,
20065 .del_beacon = wlan_hdd_cfg80211_del_beacon,
20066 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020067#else
20068 .start_ap = wlan_hdd_cfg80211_start_ap,
20069 .change_beacon = wlan_hdd_cfg80211_change_beacon,
20070 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070020071#endif
20072 .change_bss = wlan_hdd_cfg80211_change_bss,
20073 .add_key = wlan_hdd_cfg80211_add_key,
20074 .get_key = wlan_hdd_cfg80211_get_key,
20075 .del_key = wlan_hdd_cfg80211_del_key,
20076 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080020077#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070020078 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080020079#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020080 .scan = wlan_hdd_cfg80211_scan,
20081 .connect = wlan_hdd_cfg80211_connect,
20082 .disconnect = wlan_hdd_cfg80211_disconnect,
20083 .join_ibss = wlan_hdd_cfg80211_join_ibss,
20084 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
20085 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
20086 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
20087 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070020088 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
20089 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053020090 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070020091#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
20092 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
20093 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
20094 .set_txq_params = wlan_hdd_set_txq_params,
20095#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020096 .get_station = wlan_hdd_cfg80211_get_station,
20097 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
20098 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070020099 .add_station = wlan_hdd_cfg80211_add_station,
20100#ifdef FEATURE_WLAN_LFR
20101 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
20102 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
20103 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
20104#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070020105#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
20106 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
20107#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020108#ifdef FEATURE_WLAN_TDLS
20109 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
20110 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
20111#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020112#ifdef WLAN_FEATURE_GTK_OFFLOAD
20113 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
20114#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020115#ifdef FEATURE_WLAN_SCAN_PNO
20116 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
20117 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
20118#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020119 .resume = wlan_hdd_cfg80211_resume_wlan,
20120 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020121 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070020122#ifdef WLAN_NL80211_TESTMODE
20123 .testmode_cmd = wlan_hdd_cfg80211_testmode,
20124#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020125 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020126#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
20127 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053020128 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053020129#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070020130};
20131