blob: 80fadbb3c8ca3dae22580de717c0ff104b43938a [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +05302 * Copyright (c) 2012-2019 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>
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053066#include <linux/etherdevice.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067#include <wlan_hdd_includes.h>
68#include <net/arp.h>
69#include <net/cfg80211.h>
70#include <linux/wireless.h>
71#include <wlan_hdd_wowl.h>
72#include <aniGlobal.h>
73#include "ccmApi.h"
74#include "sirParams.h"
75#include "dot11f.h"
76#include "wlan_hdd_assoc.h"
77#include "wlan_hdd_wext.h"
78#include "sme_Api.h"
79#include "wlan_hdd_p2p.h"
80#include "wlan_hdd_cfg80211.h"
81#include "wlan_hdd_hostapd.h"
82#include "sapInternal.h"
83#include "wlan_hdd_softap_tx_rx.h"
84#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053085#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053086#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053087#include "wlan_hdd_trace.h"
88#include "vos_types.h"
89#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070090#ifdef WLAN_BTAMP_FEATURE
91#include "bap_hdd_misc.h"
92#endif
93#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080094#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053095#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053096#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053097#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070098#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053099#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +0530100#include "wlan_logging_sock_svc.h"
Agrawal Ashishcfe83282016-09-29 13:03:45 +0530101#include "wlan_hdd_misc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530102
Jeff Johnson295189b2012-06-20 16:38:30 -0700103
104#define g_mode_rates_size (12)
105#define a_mode_rates_size (8)
106#define FREQ_BASE_80211G (2407)
107#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700108#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530109#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800111 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700112
113#define HDD2GHZCHAN(freq, chan, flag) { \
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530114 .band = HDD_NL80211_BAND_2GHZ, \
Jeff Johnson295189b2012-06-20 16:38:30 -0700115 .center_freq = (freq), \
116 .hw_value = (chan),\
117 .flags = (flag), \
118 .max_antenna_gain = 0 ,\
119 .max_power = 30, \
120}
121
122#define HDD5GHZCHAN(freq, chan, flag) { \
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530123 .band = HDD_NL80211_BAND_5GHZ, \
Jeff Johnson295189b2012-06-20 16:38:30 -0700124 .center_freq = (freq), \
125 .hw_value = (chan),\
126 .flags = (flag), \
127 .max_antenna_gain = 0 ,\
128 .max_power = 30, \
129}
130
131#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
132{\
133 .bitrate = rate, \
134 .hw_value = rate_id, \
135 .flags = flag, \
136}
137
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530138#ifdef WLAN_FEATURE_VOWIFI_11R
139#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
140#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
141#endif
142
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530143#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530144#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530145
Sunil Duttc69bccb2014-05-26 21:30:20 +0530146#ifdef WLAN_FEATURE_LINK_LAYER_STATS
147/*
148 * Used to allocate the size of 4096 for the link layer stats.
149 * The size of 4096 is considered assuming that all data per
150 * respective event fit with in the limit.Please take a call
151 * on the limit based on the data requirements on link layer
152 * statistics.
153 */
154#define LL_STATS_EVENT_BUF_SIZE 4096
155#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530156#ifdef WLAN_FEATURE_EXTSCAN
157/*
158 * Used to allocate the size of 4096 for the EXTScan NL data.
159 * The size of 4096 is considered assuming that all data per
160 * respective event fit with in the limit.Please take a call
161 * on the limit based on the data requirements.
162 */
163
164#define EXTSCAN_EVENT_BUF_SIZE 4096
165#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
166#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530167
Atul Mittal115287b2014-07-08 13:26:33 +0530168/*EXT TDLS*/
169/*
170 * Used to allocate the size of 4096 for the TDLS.
171 * The size of 4096 is considered assuming that all data per
172 * respective event fit with in the limit.Please take a call
173 * on the limit based on the data requirements on link layer
174 * statistics.
175 */
176#define EXTTDLS_EVENT_BUF_SIZE 4096
177
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530178/*
179 * Values for Mac spoofing feature
180 *
181 */
182#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
183#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
184#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530185#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
186
Anurag Chouhan343af7e2016-12-16 13:11:19 +0530187/*
188 * max_sched_scan_plans defined to 10
189 */
190#define MAX_SCHED_SCAN_PLANS 10
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530191
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530192static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700193{
194 WLAN_CIPHER_SUITE_WEP40,
195 WLAN_CIPHER_SUITE_WEP104,
196 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800197#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700198#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
199 WLAN_CIPHER_SUITE_KRK,
200 WLAN_CIPHER_SUITE_CCMP,
201#else
202 WLAN_CIPHER_SUITE_CCMP,
203#endif
204#ifdef FEATURE_WLAN_WAPI
205 WLAN_CIPHER_SUITE_SMS4,
206#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700207#ifdef WLAN_FEATURE_11W
208 WLAN_CIPHER_SUITE_AES_CMAC,
209#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700210};
211
Agrawal Ashish97dec502015-11-26 20:20:58 +0530212const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530213{
Jeff Johnson295189b2012-06-20 16:38:30 -0700214 HDD2GHZCHAN(2412, 1, 0) ,
215 HDD2GHZCHAN(2417, 2, 0) ,
216 HDD2GHZCHAN(2422, 3, 0) ,
217 HDD2GHZCHAN(2427, 4, 0) ,
218 HDD2GHZCHAN(2432, 5, 0) ,
219 HDD2GHZCHAN(2437, 6, 0) ,
220 HDD2GHZCHAN(2442, 7, 0) ,
221 HDD2GHZCHAN(2447, 8, 0) ,
222 HDD2GHZCHAN(2452, 9, 0) ,
223 HDD2GHZCHAN(2457, 10, 0) ,
224 HDD2GHZCHAN(2462, 11, 0) ,
225 HDD2GHZCHAN(2467, 12, 0) ,
226 HDD2GHZCHAN(2472, 13, 0) ,
227 HDD2GHZCHAN(2484, 14, 0) ,
228};
229
Agrawal Ashish97dec502015-11-26 20:20:58 +0530230const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700231{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700232 HDD5GHZCHAN(4920, 240, 0) ,
233 HDD5GHZCHAN(4940, 244, 0) ,
234 HDD5GHZCHAN(4960, 248, 0) ,
235 HDD5GHZCHAN(4980, 252, 0) ,
236 HDD5GHZCHAN(5040, 208, 0) ,
237 HDD5GHZCHAN(5060, 212, 0) ,
238 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 HDD5GHZCHAN(5180, 36, 0) ,
240 HDD5GHZCHAN(5200, 40, 0) ,
241 HDD5GHZCHAN(5220, 44, 0) ,
242 HDD5GHZCHAN(5240, 48, 0) ,
243 HDD5GHZCHAN(5260, 52, 0) ,
244 HDD5GHZCHAN(5280, 56, 0) ,
245 HDD5GHZCHAN(5300, 60, 0) ,
246 HDD5GHZCHAN(5320, 64, 0) ,
247 HDD5GHZCHAN(5500,100, 0) ,
248 HDD5GHZCHAN(5520,104, 0) ,
249 HDD5GHZCHAN(5540,108, 0) ,
250 HDD5GHZCHAN(5560,112, 0) ,
251 HDD5GHZCHAN(5580,116, 0) ,
252 HDD5GHZCHAN(5600,120, 0) ,
253 HDD5GHZCHAN(5620,124, 0) ,
254 HDD5GHZCHAN(5640,128, 0) ,
255 HDD5GHZCHAN(5660,132, 0) ,
256 HDD5GHZCHAN(5680,136, 0) ,
257 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800258#ifdef FEATURE_WLAN_CH144
259 HDD5GHZCHAN(5720,144, 0) ,
260#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 HDD5GHZCHAN(5745,149, 0) ,
262 HDD5GHZCHAN(5765,153, 0) ,
263 HDD5GHZCHAN(5785,157, 0) ,
264 HDD5GHZCHAN(5805,161, 0) ,
265 HDD5GHZCHAN(5825,165, 0) ,
266};
267
268static struct ieee80211_rate g_mode_rates[] =
269{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530270 HDD_G_MODE_RATETAB(10, 0x1, 0),
271 HDD_G_MODE_RATETAB(20, 0x2, 0),
272 HDD_G_MODE_RATETAB(55, 0x4, 0),
273 HDD_G_MODE_RATETAB(110, 0x8, 0),
274 HDD_G_MODE_RATETAB(60, 0x10, 0),
275 HDD_G_MODE_RATETAB(90, 0x20, 0),
276 HDD_G_MODE_RATETAB(120, 0x40, 0),
277 HDD_G_MODE_RATETAB(180, 0x80, 0),
278 HDD_G_MODE_RATETAB(240, 0x100, 0),
279 HDD_G_MODE_RATETAB(360, 0x200, 0),
280 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530282};
Jeff Johnson295189b2012-06-20 16:38:30 -0700283
284static struct ieee80211_rate a_mode_rates[] =
285{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530286 HDD_G_MODE_RATETAB(60, 0x10, 0),
287 HDD_G_MODE_RATETAB(90, 0x20, 0),
288 HDD_G_MODE_RATETAB(120, 0x40, 0),
289 HDD_G_MODE_RATETAB(180, 0x80, 0),
290 HDD_G_MODE_RATETAB(240, 0x100, 0),
291 HDD_G_MODE_RATETAB(360, 0x200, 0),
292 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 HDD_G_MODE_RATETAB(540, 0x800, 0),
294};
295
296static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
297{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530298 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700299 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530300 .band = HDD_NL80211_BAND_2GHZ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700301 .bitrates = g_mode_rates,
302 .n_bitrates = g_mode_rates_size,
303 .ht_cap.ht_supported = 1,
304 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
305 | IEEE80211_HT_CAP_GRN_FLD
306 | IEEE80211_HT_CAP_DSSSCCK40
Abhinav Kumar1ac5cb42018-09-21 16:11:03 +0530307 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
308 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
Jeff Johnson295189b2012-06-20 16:38:30 -0700309 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
310 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
311 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
312 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
313 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
Abhinav Kumar73d67c02019-02-22 12:42:41 +0530314 .vht_cap.vht_supported = 1,
315 .vht_cap.cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454
316 | IEEE80211_VHT_CAP_SHORT_GI_80,
Jeff Johnson295189b2012-06-20 16:38:30 -0700317};
318
Jeff Johnson295189b2012-06-20 16:38:30 -0700319static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
320{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530321 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700322 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530323 .band = HDD_NL80211_BAND_5GHZ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700324 .bitrates = a_mode_rates,
325 .n_bitrates = a_mode_rates_size,
326 .ht_cap.ht_supported = 1,
327 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
328 | IEEE80211_HT_CAP_GRN_FLD
329 | IEEE80211_HT_CAP_DSSSCCK40
330 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
331 | IEEE80211_HT_CAP_SGI_40
332 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
333 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
334 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
335 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
336 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
337 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
Abhinav Kumar73d67c02019-02-22 12:42:41 +0530338 .vht_cap.vht_supported = 1,
339 .vht_cap.cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454
340 | IEEE80211_VHT_CAP_SHORT_GI_80,
Jeff Johnson295189b2012-06-20 16:38:30 -0700341};
342
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530343/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700344 TX/RX direction for each kind of interface */
345static const struct ieee80211_txrx_stypes
346wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
347 [NL80211_IFTYPE_STATION] = {
348 .tx = 0xffff,
349 .rx = BIT(SIR_MAC_MGMT_ACTION) |
350 BIT(SIR_MAC_MGMT_PROBE_REQ),
351 },
352 [NL80211_IFTYPE_AP] = {
353 .tx = 0xffff,
354 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
355 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
356 BIT(SIR_MAC_MGMT_PROBE_REQ) |
357 BIT(SIR_MAC_MGMT_DISASSOC) |
358 BIT(SIR_MAC_MGMT_AUTH) |
359 BIT(SIR_MAC_MGMT_DEAUTH) |
360 BIT(SIR_MAC_MGMT_ACTION),
361 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700362 [NL80211_IFTYPE_ADHOC] = {
363 .tx = 0xffff,
364 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
365 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
366 BIT(SIR_MAC_MGMT_PROBE_REQ) |
367 BIT(SIR_MAC_MGMT_DISASSOC) |
368 BIT(SIR_MAC_MGMT_AUTH) |
369 BIT(SIR_MAC_MGMT_DEAUTH) |
370 BIT(SIR_MAC_MGMT_ACTION),
371 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700372 [NL80211_IFTYPE_P2P_CLIENT] = {
373 .tx = 0xffff,
374 .rx = BIT(SIR_MAC_MGMT_ACTION) |
375 BIT(SIR_MAC_MGMT_PROBE_REQ),
376 },
377 [NL80211_IFTYPE_P2P_GO] = {
378 /* This is also same as for SoftAP */
379 .tx = 0xffff,
380 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
381 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
382 BIT(SIR_MAC_MGMT_PROBE_REQ) |
383 BIT(SIR_MAC_MGMT_DISASSOC) |
384 BIT(SIR_MAC_MGMT_AUTH) |
385 BIT(SIR_MAC_MGMT_DEAUTH) |
386 BIT(SIR_MAC_MGMT_ACTION),
387 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700388};
389
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800390#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800391static const struct ieee80211_iface_limit
392wlan_hdd_iface_limit[] = {
393 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800394 /* max = 3 ; Our driver create two interfaces during driver init
395 * wlan0 and p2p0 interfaces. p2p0 is considered as station
396 * interface until a group is formed. In JB architecture, once the
397 * group is formed, interface type of p2p0 is changed to P2P GO or
398 * Client.
399 * When supplicant remove the group, it first issue a set interface
400 * cmd to change the mode back to Station. In JB this works fine as
401 * we advertize two station type interface during driver init.
402 * Some vendors create separate interface for P2P GO/Client,
403 * after group formation(Third one). But while group remove
404 * supplicant first tries to change the mode(3rd interface) to STATION
405 * But as we advertized only two sta type interfaces nl80211 was
406 * returning error for the third one which was leading to failure in
407 * delete interface. Ideally while removing the group, supplicant
408 * should not try to change the 3rd interface mode to Station type.
409 * Till we get a fix in wpa_supplicant, we advertize max STA
410 * interface type to 3
411 */
412 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800413 .types = BIT(NL80211_IFTYPE_STATION),
414 },
415 {
416 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700417 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800418 },
419 {
420 .max = 1,
421 .types = BIT(NL80211_IFTYPE_P2P_GO) |
422 BIT(NL80211_IFTYPE_P2P_CLIENT),
423 },
424};
425
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530426/* interface limits for sta + monitor SCC */
427static const struct ieee80211_iface_limit
428wlan_hdd_iface_sta_mon_limit[] = {
429 {
430 .max = 1,
431 .types = BIT(NL80211_IFTYPE_STATION),
432 },
433 {
434 .max = 1, /* Monitor interface */
435 .types = BIT(NL80211_IFTYPE_MONITOR),
436 },
437};
438
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800439/* By default, only single channel concurrency is allowed */
440static struct ieee80211_iface_combination
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530441wlan_hdd_iface_combination[] = {
442 {
443 .limits = wlan_hdd_iface_limit,
444 .num_different_channels = 1,
445 /*
446 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
447 * and p2p0 interfaces during driver init
448 * Some vendors create separate interface for P2P operations.
449 * wlan0: STA interface
450 * p2p0: P2P Device interface, action frames goes
451 * through this interface.
452 * p2p-xx: P2P interface, After GO negotiation this interface is
453 * created for p2p operations(GO/CLIENT interface).
454 */
455 .max_interfaces = WLAN_MAX_INTERFACES,
456 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
457 .beacon_int_infra_match = false,
458 },
459 {
460 .limits = wlan_hdd_iface_sta_mon_limit,
461 .num_different_channels = 1,
462 .max_interfaces = WLAN_STA_AND_MON_INTERFACES,
463 .n_limits = ARRAY_SIZE(wlan_hdd_iface_sta_mon_limit),
464 .beacon_int_infra_match = false,
465 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800466};
467#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800468
Nachiket Kukade5b2e7332018-04-06 14:40:22 +0530469#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
470static const struct wiphy_wowlan_support wowlan_support_cfg80211_init = {
Nachiket Kukade1e1b90e2018-05-10 15:26:13 +0530471 .flags = WIPHY_WOWLAN_ANY |
472 WIPHY_WOWLAN_MAGIC_PKT,
Nachiket Kukade5b2e7332018-04-06 14:40:22 +0530473 .n_patterns = WOWL_MAX_PTRNS_ALLOWED,
474 .pattern_min_len = 1,
475 .pattern_max_len = WOWL_PTRN_MAX_SIZE,
476};
477#endif
478
Jeff Johnson295189b2012-06-20 16:38:30 -0700479static struct cfg80211_ops wlan_hdd_cfg80211_ops;
480
481/* Data rate 100KBPS based on IE Index */
482struct index_data_rate_type
483{
484 v_U8_t beacon_rate_index;
485 v_U16_t supported_rate[4];
486};
487
488/* 11B, 11G Rate table include Basic rate and Extended rate
489 The IDX field is the rate index
490 The HI field is the rate when RSSI is strong or being ignored
491 (in this case we report actual rate)
492 The MID field is the rate when RSSI is moderate
493 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
494 The LO field is the rate when RSSI is low
495 (in this case we don't report rates, actual current rate used)
496 */
497static const struct
498{
499 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700500 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700501} supported_data_rate[] =
502{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700503/* IDX HI HM LM LO (RSSI-based index */
504 {2, { 10, 10, 10, 0}},
505 {4, { 20, 20, 10, 0}},
506 {11, { 55, 20, 10, 0}},
507 {12, { 60, 55, 20, 0}},
508 {18, { 90, 55, 20, 0}},
509 {22, {110, 55, 20, 0}},
510 {24, {120, 90, 60, 0}},
511 {36, {180, 120, 60, 0}},
512 {44, {220, 180, 60, 0}},
513 {48, {240, 180, 90, 0}},
514 {66, {330, 180, 90, 0}},
515 {72, {360, 240, 90, 0}},
516 {96, {480, 240, 120, 0}},
517 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700518};
519
520/* MCS Based rate table */
521static struct index_data_rate_type supported_mcs_rate[] =
522{
523/* MCS L20 L40 S20 S40 */
524 {0, {65, 135, 72, 150}},
525 {1, {130, 270, 144, 300}},
526 {2, {195, 405, 217, 450}},
527 {3, {260, 540, 289, 600}},
528 {4, {390, 810, 433, 900}},
529 {5, {520, 1080, 578, 1200}},
530 {6, {585, 1215, 650, 1350}},
531 {7, {650, 1350, 722, 1500}}
532};
533
Leo Chang6f8870f2013-03-26 18:11:36 -0700534#ifdef WLAN_FEATURE_11AC
535
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530536#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700537
538struct index_vht_data_rate_type
539{
540 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530541 v_U16_t supported_VHT80_rate[2];
542 v_U16_t supported_VHT40_rate[2];
543 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700544};
545
546typedef enum
547{
548 DATA_RATE_11AC_MAX_MCS_7,
549 DATA_RATE_11AC_MAX_MCS_8,
550 DATA_RATE_11AC_MAX_MCS_9,
551 DATA_RATE_11AC_MAX_MCS_NA
552} eDataRate11ACMaxMcs;
553
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530554/* SSID broadcast type */
555typedef enum eSSIDBcastType
556{
557 eBCAST_UNKNOWN = 0,
558 eBCAST_NORMAL = 1,
559 eBCAST_HIDDEN = 2,
560} tSSIDBcastType;
561
Leo Chang6f8870f2013-03-26 18:11:36 -0700562/* MCS Based VHT rate table */
563static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
564{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530565/* MCS L80 S80 L40 S40 L20 S40*/
566 {0, {293, 325}, {135, 150}, {65, 72}},
567 {1, {585, 650}, {270, 300}, {130, 144}},
568 {2, {878, 975}, {405, 450}, {195, 217}},
569 {3, {1170, 1300}, {540, 600}, {260, 289}},
570 {4, {1755, 1950}, {810, 900}, {390, 433}},
571 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
572 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
573 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
574 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
575 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700576};
577#endif /* WLAN_FEATURE_11AC */
578
c_hpothu79aab322014-07-14 21:11:01 +0530579/*array index points to MCS and array value points respective rssi*/
580static int rssiMcsTbl[][10] =
581{
582/*MCS 0 1 2 3 4 5 6 7 8 9*/
583 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
584 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
585 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
586};
587
Jeff Johnson295189b2012-06-20 16:38:30 -0700588extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530589#ifdef FEATURE_WLAN_SCAN_PNO
590static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
591#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700592
Leo Chang9056f462013-08-01 19:21:11 -0700593#ifdef WLAN_NL80211_TESTMODE
594enum wlan_hdd_tm_attr
595{
596 WLAN_HDD_TM_ATTR_INVALID = 0,
597 WLAN_HDD_TM_ATTR_CMD = 1,
598 WLAN_HDD_TM_ATTR_DATA = 2,
599 WLAN_HDD_TM_ATTR_TYPE = 3,
600 /* keep last */
601 WLAN_HDD_TM_ATTR_AFTER_LAST,
602 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
603};
604
605enum wlan_hdd_tm_cmd
606{
607 WLAN_HDD_TM_CMD_WLAN_HB = 1,
608};
609
610#define WLAN_HDD_TM_DATA_MAX_LEN 5000
611
612static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
613{
614 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
615 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
616 .len = WLAN_HDD_TM_DATA_MAX_LEN },
617};
618#endif /* WLAN_NL80211_TESTMODE */
619
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800620#ifdef FEATURE_WLAN_CH_AVOID
621/*
622 * FUNCTION: wlan_hdd_send_avoid_freq_event
623 * This is called when wlan driver needs to send vendor specific
624 * avoid frequency range event to userspace
625 */
626int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
627 tHddAvoidFreqList *pAvoidFreqList)
628{
629 struct sk_buff *vendor_event;
630
631 ENTER();
632
633 if (!pHddCtx)
634 {
635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
636 "%s: HDD context is null", __func__);
637 return -1;
638 }
639
640 if (!pAvoidFreqList)
641 {
642 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
643 "%s: pAvoidFreqList is null", __func__);
644 return -1;
645 }
646
647 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530648#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
649 NULL,
650#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800651 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530652 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800653 GFP_KERNEL);
654 if (!vendor_event)
655 {
656 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
657 "%s: cfg80211_vendor_event_alloc failed", __func__);
658 return -1;
659 }
660
661 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
662 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
663
664 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
665
666 EXIT();
667 return 0;
668}
669#endif /* FEATURE_WLAN_CH_AVOID */
670
Srinivas Dasari030bad32015-02-18 23:23:54 +0530671/*
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +0530672 * define short names for the global vendor params
673 * used by QCA_NL80211_VENDOR_SUBCMD_HANG
674 */
675#define HANG_REASON_INDEX QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX
676
677/**
678 * hdd_convert_hang_reason() - Convert cds recovery reason to vendor specific
679 * hang reason
680 * @reason: cds recovery reason
681 *
682 * Return: Vendor specific reason code
683 */
684static enum qca_wlan_vendor_hang_reason
685hdd_convert_hang_reason(enum vos_hang_reason reason)
686{
687 unsigned int ret_val;
688
689 switch (reason) {
690 case VOS_GET_MSG_BUFF_FAILURE:
691 ret_val = QCA_WLAN_HANG_GET_MSG_BUFF_FAILURE;
692 break;
693 case VOS_ACTIVE_LIST_TIMEOUT:
694 ret_val = QCA_WLAN_HANG_ACTIVE_LIST_TIMEOUT;
695 break;
696 case VOS_SCAN_REQ_EXPIRED:
697 ret_val = QCA_WLAN_HANG_SCAN_REQ_EXPIRED;
698 break;
699 case VOS_TRANSMISSIONS_TIMEOUT:
700 ret_val = QCA_WLAN_HANG_TRANSMISSIONS_TIMEOUT;
701 break;
702 case VOS_DXE_FAILURE:
703 ret_val = QCA_WLAN_HANG_DXE_FAILURE;
704 break;
705 case VOS_WDI_FAILURE:
706 ret_val = QCA_WLAN_HANG_WDI_FAILURE;
707 break;
708 case VOS_REASON_UNSPECIFIED:
709 default:
710 ret_val = QCA_WLAN_HANG_REASON_UNSPECIFIED;
711 }
712 return ret_val;
713}
714
715/**
716 * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace
717 * @hdd_ctx: Pointer to hdd context
718 * @reason: cds recovery reason
719 *
720 * Return: 0 on success or failure reason
721 */
722int wlan_hdd_send_hang_reason_event(hdd_context_t *hdd_ctx,
723 enum vos_hang_reason reason)
724{
725 struct sk_buff *vendor_event;
726 enum qca_wlan_vendor_hang_reason hang_reason;
727
728 ENTER();
729
730 if (!hdd_ctx) {
731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
732 "HDD context is null");
733 return -EINVAL;
734 }
735
736 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
737#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
738 NULL,
739#endif
740 sizeof(unsigned int),
741 HANG_REASON_INDEX,
742 GFP_KERNEL);
743 if (!vendor_event) {
744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
745 "cfg80211_vendor_event_alloc failed");
746 return -ENOMEM;
747 }
748
749 hang_reason = hdd_convert_hang_reason(reason);
750
751 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_HANG_REASON,
752 (unsigned int) hang_reason)) {
753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
754 "QCA_WLAN_VENDOR_ATTR_HANG_REASON put fail");
755 kfree_skb(vendor_event);
756 return -EINVAL;
757 }
758
759 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
760
761 EXIT();
762 return 0;
763}
764#undef HANG_REASON_INDEX
765
766/*
Srinivas Dasari030bad32015-02-18 23:23:54 +0530767 * FUNCTION: __wlan_hdd_cfg80211_nan_request
768 * This is called when wlan driver needs to send vendor specific
769 * nan request event.
770 */
771static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
772 struct wireless_dev *wdev,
773 const void *data, int data_len)
774{
775 tNanRequestReq nan_req;
776 VOS_STATUS status;
777 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530778 struct net_device *dev = wdev->netdev;
779 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
780 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530781 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
782
783 if (0 == data_len)
784 {
785 hddLog(VOS_TRACE_LEVEL_ERROR,
786 FL("NAN - Invalid Request, length = 0"));
787 return ret_val;
788 }
789
790 if (NULL == data)
791 {
792 hddLog(VOS_TRACE_LEVEL_ERROR,
793 FL("NAN - Invalid Request, data is NULL"));
794 return ret_val;
795 }
796
797 status = wlan_hdd_validate_context(pHddCtx);
798 if (0 != status)
799 {
800 hddLog(VOS_TRACE_LEVEL_ERROR,
801 FL("HDD context is not valid"));
802 return -EINVAL;
803 }
804
805 hddLog(LOG1, FL("Received NAN command"));
806 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
807 (tANI_U8 *)data, data_len);
808
809 /* check the NAN Capability */
810 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
811 {
812 hddLog(VOS_TRACE_LEVEL_ERROR,
813 FL("NAN is not supported by Firmware"));
814 return -EINVAL;
815 }
816
817 nan_req.request_data_len = data_len;
818 nan_req.request_data = data;
819
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530820 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530821 if (VOS_STATUS_SUCCESS == status)
822 {
823 ret_val = 0;
824 }
825 return ret_val;
826}
827
828/*
829 * FUNCTION: wlan_hdd_cfg80211_nan_request
830 * Wrapper to protect the nan vendor command from ssr
831 */
832static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
833 struct wireless_dev *wdev,
834 const void *data, int data_len)
835{
836 int ret;
837
838 vos_ssr_protect(__func__);
839 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
840 vos_ssr_unprotect(__func__);
841
842 return ret;
843}
844
845/*
846 * FUNCTION: wlan_hdd_cfg80211_nan_callback
847 * This is a callback function and it gets called
848 * when we need to report nan response event to
849 * upper layers.
850 */
851static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
852{
853 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
854 struct sk_buff *vendor_event;
855 int status;
856 tSirNanEvent *data;
857
858 ENTER();
859 if (NULL == msg)
860 {
861 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
862 FL(" msg received here is null"));
863 return;
864 }
865 data = msg;
866
867 status = wlan_hdd_validate_context(pHddCtx);
868
869 if (0 != status)
870 {
871 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
872 FL("HDD context is not valid"));
873 return;
874 }
875
876 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530877#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
878 NULL,
879#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530880 data->event_data_len +
881 NLMSG_HDRLEN,
882 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
883 GFP_KERNEL);
884
885 if (!vendor_event)
886 {
887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
888 FL("cfg80211_vendor_event_alloc failed"));
889 return;
890 }
891 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
892 data->event_data_len, data->event_data))
893 {
894 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
895 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
896 kfree_skb(vendor_event);
897 return;
898 }
899 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
900 EXIT();
901}
902
903/*
904 * FUNCTION: wlan_hdd_cfg80211_nan_init
905 * This function is called to register the callback to sme layer
906 */
907inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
908{
909 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
910}
911
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530912/*
913 * define short names for the global vendor params
914 * used by __wlan_hdd_cfg80211_get_station_cmd()
915 */
916#define STATION_INVALID \
917 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
918#define STATION_INFO \
919 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
920#define STATION_ASSOC_FAIL_REASON \
921 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +0530922#define STATION_REMOTE \
923 QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530924#define STATION_MAX \
925 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
926
927static const struct nla_policy
928hdd_get_station_policy[STATION_MAX + 1] = {
929 [STATION_INFO] = {.type = NLA_FLAG},
930 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
931};
932
933/**
934 * hdd_get_station_assoc_fail() - Handle get station assoc fail
935 * @hdd_ctx: HDD context within host driver
936 * @wdev: wireless device
937 *
938 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
939 * Validate cmd attributes and send the station info to upper layers.
940 *
941 * Return: Success(0) or reason code for failure
942 */
943static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
944 hdd_adapter_t *adapter)
945{
946 struct sk_buff *skb = NULL;
947 uint32_t nl_buf_len;
948 hdd_station_ctx_t *hdd_sta_ctx;
949
950 nl_buf_len = NLMSG_HDRLEN;
951 nl_buf_len += sizeof(uint32_t);
952 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
953
954 if (!skb) {
955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
956 return -ENOMEM;
957 }
958
959 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
960
961 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
962 hdd_sta_ctx->conn_info.assoc_status_code)) {
963 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
964 goto fail;
965 }
966 return cfg80211_vendor_cmd_reply(skb);
967fail:
968 if (skb)
969 kfree_skb(skb);
970 return -EINVAL;
971}
972
973/**
974 * hdd_map_auth_type() - transform auth type specific to
975 * vendor command
976 * @auth_type: csr auth type
977 *
978 * Return: Success(0) or reason code for failure
979 */
980static int hdd_convert_auth_type(uint32_t auth_type)
981{
982 uint32_t ret_val;
983
984 switch (auth_type) {
985 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
986 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
987 break;
988 case eCSR_AUTH_TYPE_SHARED_KEY:
989 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
990 break;
991 case eCSR_AUTH_TYPE_WPA:
992 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
993 break;
994 case eCSR_AUTH_TYPE_WPA_PSK:
995 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
996 break;
997 case eCSR_AUTH_TYPE_AUTOSWITCH:
998 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
999 break;
1000 case eCSR_AUTH_TYPE_WPA_NONE:
1001 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
1002 break;
1003 case eCSR_AUTH_TYPE_RSN:
1004 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
1005 break;
1006 case eCSR_AUTH_TYPE_RSN_PSK:
1007 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
1008 break;
1009 case eCSR_AUTH_TYPE_FT_RSN:
1010 ret_val = QCA_WLAN_AUTH_TYPE_FT;
1011 break;
1012 case eCSR_AUTH_TYPE_FT_RSN_PSK:
1013 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
1014 break;
1015 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
1016 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
1017 break;
1018 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
1019 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
1020 break;
1021#ifdef FEATURE_WLAN_ESE
1022 case eCSR_AUTH_TYPE_CCKM_WPA:
1023 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
1024 break;
1025 case eCSR_AUTH_TYPE_CCKM_RSN:
1026 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
1027 break;
1028#endif
1029 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
1030 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
1031 break;
1032 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
1033 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
1034 break;
1035 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
1036 case eCSR_AUTH_TYPE_FAILED:
1037 case eCSR_AUTH_TYPE_NONE:
1038 default:
1039 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
1040 break;
1041 }
1042 return ret_val;
1043}
1044
1045/**
1046 * hdd_map_dot_11_mode() - transform dot11mode type specific to
1047 * vendor command
1048 * @dot11mode: dot11mode
1049 *
1050 * Return: Success(0) or reason code for failure
1051 */
1052static int hdd_convert_dot11mode(uint32_t dot11mode)
1053{
1054 uint32_t ret_val;
1055
1056 switch (dot11mode) {
1057 case eCSR_CFG_DOT11_MODE_11A:
1058 ret_val = QCA_WLAN_802_11_MODE_11A;
1059 break;
1060 case eCSR_CFG_DOT11_MODE_11B:
1061 ret_val = QCA_WLAN_802_11_MODE_11B;
1062 break;
1063 case eCSR_CFG_DOT11_MODE_11G:
1064 ret_val = QCA_WLAN_802_11_MODE_11G;
1065 break;
1066 case eCSR_CFG_DOT11_MODE_11N:
1067 ret_val = QCA_WLAN_802_11_MODE_11N;
1068 break;
1069 case eCSR_CFG_DOT11_MODE_11AC:
1070 ret_val = QCA_WLAN_802_11_MODE_11AC;
1071 break;
1072 case eCSR_CFG_DOT11_MODE_AUTO:
1073 case eCSR_CFG_DOT11_MODE_ABG:
1074 default:
1075 ret_val = QCA_WLAN_802_11_MODE_INVALID;
1076 }
1077 return ret_val;
1078}
1079
1080/**
1081 * hdd_add_tx_bitrate() - add tx bitrate attribute
1082 * @skb: pointer to sk buff
1083 * @hdd_sta_ctx: pointer to hdd station context
1084 * @idx: attribute index
1085 *
1086 * Return: Success(0) or reason code for failure
1087 */
1088static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
1089 hdd_station_ctx_t *hdd_sta_ctx,
1090 int idx)
1091{
1092 struct nlattr *nla_attr;
1093 uint32_t bitrate, bitrate_compat;
1094
1095 nla_attr = nla_nest_start(skb, idx);
1096 if (!nla_attr)
1097 goto fail;
1098 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301099 bitrate = cfg80211_calculate_bitrate(
1100 &hdd_sta_ctx->cache_conn_info.txrate);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301101
1102 /* report 16-bit bitrate only if we can */
1103 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
1104 if (bitrate > 0 &&
1105 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
1106 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1107 goto fail;
1108 }
1109 if (bitrate_compat > 0 &&
1110 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
1111 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1112 goto fail;
1113 }
1114 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301115 hdd_sta_ctx->cache_conn_info.txrate.nss)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1117 goto fail;
1118 }
1119 nla_nest_end(skb, nla_attr);
1120 return 0;
1121fail:
1122 return -EINVAL;
1123}
1124
1125/**
1126 * hdd_add_sta_info() - add station info attribute
1127 * @skb: pointer to sk buff
1128 * @hdd_sta_ctx: pointer to hdd station context
1129 * @idx: attribute index
1130 *
1131 * Return: Success(0) or reason code for failure
1132 */
1133static int32_t hdd_add_sta_info(struct sk_buff *skb,
1134 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1135{
1136 struct nlattr *nla_attr;
1137
1138 nla_attr = nla_nest_start(skb, idx);
1139 if (!nla_attr)
1140 goto fail;
1141 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301142 (hdd_sta_ctx->cache_conn_info.signal + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1144 goto fail;
1145 }
1146 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1147 goto fail;
1148 nla_nest_end(skb, nla_attr);
1149 return 0;
1150fail:
1151 return -EINVAL;
1152}
1153
1154/**
1155 * hdd_add_survey_info() - add survey info attribute
1156 * @skb: pointer to sk buff
1157 * @hdd_sta_ctx: pointer to hdd station context
1158 * @idx: attribute index
1159 *
1160 * Return: Success(0) or reason code for failure
1161 */
1162static int32_t hdd_add_survey_info(struct sk_buff *skb,
1163 hdd_station_ctx_t *hdd_sta_ctx,
1164 int idx)
1165{
1166 struct nlattr *nla_attr;
1167
1168 nla_attr = nla_nest_start(skb, idx);
1169 if (!nla_attr)
1170 goto fail;
1171 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301172 hdd_sta_ctx->cache_conn_info.freq) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301173 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301174 (hdd_sta_ctx->cache_conn_info.noise + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1176 goto fail;
1177 }
1178 nla_nest_end(skb, nla_attr);
1179 return 0;
1180fail:
1181 return -EINVAL;
1182}
1183
1184/**
1185 * hdd_add_link_standard_info() - add link info attribute
1186 * @skb: pointer to sk buff
1187 * @hdd_sta_ctx: pointer to hdd station context
1188 * @idx: attribute index
1189 *
1190 * Return: Success(0) or reason code for failure
1191 */
1192static int32_t
1193hdd_add_link_standard_info(struct sk_buff *skb,
1194 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1195{
1196 struct nlattr *nla_attr;
1197
1198 nla_attr = nla_nest_start(skb, idx);
1199 if (!nla_attr)
1200 goto fail;
1201 if (nla_put(skb,
1202 NL80211_ATTR_SSID,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301203 hdd_sta_ctx->cache_conn_info.SSID.SSID.length,
1204 hdd_sta_ctx->cache_conn_info.SSID.SSID.ssId)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1206 goto fail;
1207 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301208 if (nla_put(skb, NL80211_ATTR_MAC, VOS_MAC_ADDR_SIZE,
1209 hdd_sta_ctx->cache_conn_info.bssId))
1210 goto fail;
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301211 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1212 goto fail;
1213 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1214 goto fail;
1215 nla_nest_end(skb, nla_attr);
1216 return 0;
1217fail:
1218 return -EINVAL;
1219}
1220
1221/**
1222 * hdd_add_ap_standard_info() - add ap info attribute
1223 * @skb: pointer to sk buff
1224 * @hdd_sta_ctx: pointer to hdd station context
1225 * @idx: attribute index
1226 *
1227 * Return: Success(0) or reason code for failure
1228 */
1229static int32_t
1230hdd_add_ap_standard_info(struct sk_buff *skb,
1231 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1232{
1233 struct nlattr *nla_attr;
1234
1235 nla_attr = nla_nest_start(skb, idx);
1236 if (!nla_attr)
1237 goto fail;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301238 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301239 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301240 sizeof(hdd_sta_ctx->cache_conn_info.vht_caps),
1241 &hdd_sta_ctx->cache_conn_info.vht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1243 goto fail;
1244 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301245 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301246 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301247 sizeof(hdd_sta_ctx->cache_conn_info.ht_caps),
1248 &hdd_sta_ctx->cache_conn_info.ht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1250 goto fail;
1251 }
1252 nla_nest_end(skb, nla_attr);
1253 return 0;
1254fail:
1255 return -EINVAL;
1256}
1257
1258/**
1259 * hdd_get_station_info() - send BSS information to supplicant
1260 * @hdd_ctx: pointer to hdd context
1261 * @adapter: pointer to adapter
1262 *
1263 * Return: 0 if success else error status
1264 */
1265static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1266 hdd_adapter_t *adapter)
1267{
1268 struct sk_buff *skb = NULL;
1269 uint8_t *tmp_hs20 = NULL;
1270 uint32_t nl_buf_len;
1271 hdd_station_ctx_t *hdd_sta_ctx;
1272
1273 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1274
1275 nl_buf_len = NLMSG_HDRLEN;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301276
1277 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.SSID.SSID.length) +
1278 VOS_MAC_ADDR_SIZE +
1279 sizeof(hdd_sta_ctx->cache_conn_info.freq) +
1280 sizeof(hdd_sta_ctx->cache_conn_info.noise) +
1281 sizeof(hdd_sta_ctx->cache_conn_info.signal) +
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301282 (sizeof(uint32_t) * 2) +
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301283 sizeof(hdd_sta_ctx->cache_conn_info.txrate.nss) +
1284 sizeof(hdd_sta_ctx->cache_conn_info.roam_count) +
1285 sizeof(hdd_sta_ctx->cache_conn_info.authType) +
1286 sizeof(hdd_sta_ctx->cache_conn_info.dot11Mode);
1287 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
1288 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.vht_caps);
1289 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
1290 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_caps);
1291 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) {
1292 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->
1293 cache_conn_info.hs20vendor_ie);
1294 nl_buf_len +=
1295 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie) -
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301296 1);
1297 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301298 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
1299 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_operation);
1300 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
1301 nl_buf_len +=
1302 sizeof(hdd_sta_ctx->cache_conn_info.vht_operation);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301303
1304
1305 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1306 if (!skb) {
1307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1308 __func__, __LINE__);
1309 return -ENOMEM;
1310 }
1311
1312 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1313 LINK_INFO_STANDARD_NL80211_ATTR)) {
1314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1315 goto fail;
1316 }
1317 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1318 AP_INFO_STANDARD_NL80211_ATTR)) {
1319 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1320 goto fail;
1321 }
1322 if (nla_put_u32(skb, INFO_ROAM_COUNT,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301323 hdd_sta_ctx->cache_conn_info.roam_count) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301324 nla_put_u32(skb, INFO_AKM,
1325 hdd_convert_auth_type(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301326 hdd_sta_ctx->cache_conn_info.authType)) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301327 nla_put_u32(skb, WLAN802_11_MODE,
1328 hdd_convert_dot11mode(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301329 hdd_sta_ctx->cache_conn_info.dot11Mode))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301330 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1331 goto fail;
1332 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301333 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301334 if (nla_put(skb, HT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301335 (sizeof(hdd_sta_ctx->cache_conn_info.ht_operation)),
1336 &hdd_sta_ctx->cache_conn_info.ht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1338 goto fail;
1339 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301340 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301341 if (nla_put(skb, VHT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301342 (sizeof(hdd_sta_ctx->
1343 cache_conn_info.vht_operation)),
1344 &hdd_sta_ctx->cache_conn_info.vht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301345 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1346 goto fail;
1347 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301348 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301349 if (nla_put(skb, AP_INFO_HS20_INDICATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301350 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie)
1351 - 1), tmp_hs20 + 1)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1353 goto fail;
1354 }
1355
1356 return cfg80211_vendor_cmd_reply(skb);
1357fail:
1358 if (skb)
1359 kfree_skb(skb);
1360 return -EINVAL;
1361}
1362
1363/**
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301364 * hdd_add_survey_info_sap_get_len - get data length used in
1365 * hdd_add_survey_info_sap()
1366 *
1367 * This function calculates the data length used in hdd_add_survey_info_sap()
1368 *
1369 * Return: total data length used in hdd_add_survey_info_sap()
1370 */
1371static uint32_t hdd_add_survey_info_sap_get_len(void)
1372{
1373 return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
1374}
1375
1376/**
1377 * hdd_add_survey_info - add survey info attribute
1378 * @skb: pointer to response skb buffer
1379 * @stainfo: station information
1380 * @idx: attribute type index for nla_next_start()
1381 *
1382 * This function adds survey info attribute to response skb buffer
1383 *
1384 * Return : 0 on success and errno on failure
1385 */
1386static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
1387 struct hdd_cache_sta_info *stainfo,
1388 int idx)
1389{
1390 struct nlattr *nla_attr;
1391
1392 nla_attr = nla_nest_start(skb, idx);
1393 if (!nla_attr)
1394 goto fail;
1395 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1396 stainfo->freq)) {
1397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1398 FL("put fail"));
1399 goto fail;
1400 }
1401 nla_nest_end(skb, nla_attr);
1402 return 0;
1403fail:
1404 return -EINVAL;
1405}
1406
1407/**
1408 * hdd_add_tx_bitrate_sap_get_len - get data length used in
1409 * hdd_add_tx_bitrate_sap()
1410 *
1411 * This function calculates the data length used in hdd_add_tx_bitrate_sap()
1412 *
1413 * Return: total data length used in hdd_add_tx_bitrate_sap()
1414 */
1415static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
1416{
1417 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
1418}
1419
1420/**
1421 * hdd_add_tx_bitrate_sap - add vht nss info attribute
1422 * @skb: pointer to response skb buffer
1423 * @stainfo: station information
1424 * @idx: attribute type index for nla_next_start()
1425 *
1426 * This function adds vht nss attribute to response skb buffer
1427 *
1428 * Return : 0 on success and errno on failure
1429 */
1430static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
1431 struct hdd_cache_sta_info *stainfo,
1432 int idx)
1433{
1434 struct nlattr *nla_attr;
1435
1436 nla_attr = nla_nest_start(skb, idx);
1437 if (!nla_attr)
1438 goto fail;
1439
1440 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1441 stainfo->nss)) {
1442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1443 FL("put fail"));
1444 goto fail;
1445 }
1446 nla_nest_end(skb, nla_attr);
1447 return 0;
1448fail:
1449 return -EINVAL;
1450}
1451
1452/**
1453 * hdd_add_sta_info_sap_get_len - get data length used in
1454 * hdd_add_sta_info_sap()
1455 *
1456 * This function calculates the data length used in hdd_add_sta_info_sap()
1457 *
1458 * Return: total data length used in hdd_add_sta_info_sap()
1459 */
1460static uint32_t hdd_add_sta_info_sap_get_len(void)
1461{
1462 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
1463 hdd_add_tx_bitrate_sap_get_len());
1464}
1465
1466/**
1467 * hdd_add_sta_info_sap - add sta signal info attribute
1468 * @skb: pointer to response skb buffer
1469 * @rssi: peer rssi value
1470 * @stainfo: station information
1471 * @idx: attribute type index for nla_next_start()
1472 *
1473 * This function adds sta signal attribute to response skb buffer
1474 *
1475 * Return : 0 on success and errno on failure
1476 */
1477static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
1478 struct hdd_cache_sta_info *stainfo, int idx)
1479{
1480 struct nlattr *nla_attr;
1481
1482 nla_attr = nla_nest_start(skb, idx);
1483 if (!nla_attr)
1484 goto fail;
1485
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05301486 /* upperlayer expects positive rssi value */
1487 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, (rssi + 96))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1489 FL("put fail"));
1490 goto fail;
1491 }
1492 if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE)) {
1493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1494 FL("put fail"));
1495 goto fail;
1496 }
1497
1498 nla_nest_end(skb, nla_attr);
1499 return 0;
1500fail:
1501 return -EINVAL;
1502}
1503
1504/**
1505 * hdd_add_link_standard_info_sap_get_len - get data length used in
1506 * hdd_add_link_standard_info_sap()
1507 *
1508 * This function calculates the data length used in
1509 * hdd_add_link_standard_info_sap()
1510 *
1511 * Return: total data length used in hdd_add_link_standard_info_sap()
1512 */
1513static uint32_t hdd_add_link_standard_info_sap_get_len(void)
1514{
1515 return ((NLA_HDRLEN) +
1516 hdd_add_survey_info_sap_get_len() +
1517 hdd_add_sta_info_sap_get_len() +
1518 (sizeof(uint32_t) + NLA_HDRLEN));
1519}
1520
1521/**
1522 * hdd_add_link_standard_info_sap - add add link info attribut
1523 * @skb: pointer to response skb buffer
1524 * @stainfo: station information
1525 * @idx: attribute type index for nla_next_start()
1526 *
1527 * This function adds link info attribut to response skb buffer
1528 *
1529 * Return : 0 on success and errno on failure
1530 */
1531static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
1532 struct hdd_cache_sta_info *stainfo,
1533 int idx)
1534{
1535 struct nlattr *nla_attr;
1536
1537 nla_attr = nla_nest_start(skb, idx);
1538 if (!nla_attr)
1539 goto fail;
1540 if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
1541 goto fail;
1542 if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
1543 goto fail;
1544
1545 if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
1546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1547 FL("put fail"));
1548 goto fail;
1549 }
1550
1551 nla_nest_end(skb, nla_attr);
1552 return 0;
1553fail:
1554 return -EINVAL;
1555}
1556
1557/**
1558 * hdd_add_ap_standard_info_sap_get_len - get data length used in
1559 * hdd_add_ap_standard_info_sap()
1560 * @stainfo: station information
1561 *
1562 * This function calculates the data length used in
1563 * hdd_add_ap_standard_info_sap()
1564 *
1565 * Return: total data length used in hdd_add_ap_standard_info_sap()
1566 */
1567static uint32_t hdd_add_ap_standard_info_sap_get_len(
1568 struct hdd_cache_sta_info *stainfo)
1569{
1570 uint32_t len;
1571
1572 len = NLA_HDRLEN;
1573 if (stainfo->vht_present)
1574 len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
1575 if (stainfo->ht_present)
1576 len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
1577
1578 return len;
1579}
1580
1581/**
1582 * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
1583 * @skb: pointer to response skb buffer
1584 * @stainfo: station information
1585 * @idx: attribute type index for nla_next_start()
1586 *
1587 * This function adds HT and VHT info attributes to response skb buffer
1588 *
1589 * Return : 0 on success and errno on failure
1590 */
1591static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
1592 struct hdd_cache_sta_info *stainfo,
1593 int idx)
1594{
1595 struct nlattr *nla_attr;
1596
1597 nla_attr = nla_nest_start(skb, idx);
1598 if (!nla_attr)
1599 goto fail;
1600
1601 if (stainfo->vht_present) {
1602 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1603 sizeof(stainfo->vht_caps),
1604 &stainfo->vht_caps)) {
1605 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1606 FL("put fail"));
1607 goto fail;
1608 }
1609 }
1610 if (stainfo->ht_present) {
1611 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1612 sizeof(stainfo->ht_caps),
1613 &stainfo->ht_caps)) {
1614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1615 FL("put fail"));
1616 goto fail;
1617 }
1618 }
1619 nla_nest_end(skb, nla_attr);
1620 return 0;
1621fail:
1622 return -EINVAL;
1623}
1624
1625/**
1626 * hdd_decode_ch_width - decode channel band width based
1627 * @ch_width: encoded enum value holding channel band width
1628 *
1629 * This function decodes channel band width from the given encoded enum value.
1630 *
1631 * Returns: decoded channel band width.
1632 */
1633static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
1634{
1635 switch (ch_width) {
1636 case 0:
1637 return 20;
1638 case 1:
1639 return 40;
1640 case 2:
1641 return 80;
1642 default:
1643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1644 "invalid enum: %d", ch_width);
1645 return 20;
1646 }
1647}
1648
1649/**
1650 * hdd_get_cached_station_remote() - get cached(deleted) peer's info
1651 * @hdd_ctx: hdd context
1652 * @adapter: hostapd interface
1653 * @mac_addr: mac address of requested peer
1654 *
1655 * This function collect and indicate the cached(deleted) peer's info
1656 *
1657 * Return: 0 on success, otherwise error value
1658 */
1659static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx,
1660 hdd_adapter_t *adapter,
1661 v_MACADDR_t mac_addr)
1662{
1663 struct hdd_cache_sta_info *stainfo;
1664 struct sk_buff *skb = NULL;
1665 uint32_t nl_buf_len;
1666 uint8_t cw;
1667 ptSapContext sap_ctx;
1668 v_CONTEXT_t vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
1669
1670 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
1671 if(sap_ctx == NULL){
1672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1673 FL("psapCtx is NULL"));
1674 return -ENOENT;
1675 }
1676
1677 stainfo = hdd_get_cache_stainfo(sap_ctx->cache_sta_info,
1678 mac_addr.bytes);
1679 if (!stainfo) {
1680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1681 "peer " MAC_ADDRESS_STR " not found",
1682 MAC_ADDR_ARRAY(mac_addr.bytes));
1683 return -EINVAL;
1684 }
1685 if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE) {
1686 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1687 "peer " MAC_ADDRESS_STR " is in connected state",
1688 MAC_ADDR_ARRAY(mac_addr.bytes));
1689 return -EINVAL;
1690 }
1691
1692
1693 nl_buf_len = NLMSG_HDRLEN + hdd_add_link_standard_info_sap_get_len() +
1694 hdd_add_ap_standard_info_sap_get_len(stainfo) +
1695 (sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
1696 (sizeof(cw) + NLA_HDRLEN) +
1697 (sizeof(stainfo->rx_rate) + NLA_HDRLEN);
1698
1699 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1700 if (!skb) {
1701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "cfg80211_vendor_cmd_alloc_reply_skb failed");
1702 return -ENOMEM;
1703 }
1704
1705 if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
1706 LINK_INFO_STANDARD_NL80211_ATTR)) {
1707 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "link standard put fail");
1708 goto fail;
1709 }
1710
1711 if (hdd_add_ap_standard_info_sap(skb, stainfo,
1712 AP_INFO_STANDARD_NL80211_ATTR)) {
1713 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ap standard put fail");
1714 goto fail;
1715 }
1716
1717 /* upper layer expects decoded channel BW */
1718 cw = hdd_decode_ch_width(stainfo->ch_width);
1719 if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE, stainfo->dot11_mode) ||
1720 nla_put_u8(skb, REMOTE_CH_WIDTH, cw)) {
1721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "remote ch put fail");
1722 goto fail;
1723 }
Hanumanth Reddy Pothula504fe152018-01-02 20:41:03 +05301724 if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, (stainfo->rx_rate * 100))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "rx rate put fail");
1726 goto fail;
1727 }
1728
1729 vos_mem_zero(stainfo, sizeof(*stainfo));
1730
1731 return cfg80211_vendor_cmd_reply(skb);
1732fail:
1733 if (skb)
1734 kfree_skb(skb);
1735
1736 return -EINVAL;
1737}
1738
1739/**
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301740 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1741 * @wiphy: corestack handler
1742 * @wdev: wireless device
1743 * @data: data
1744 * @data_len: data length
1745 *
1746 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1747 * Validate cmd attributes and send the station info to upper layers.
1748 *
1749 * Return: Success(0) or reason code for failure
1750 */
1751static int32_t
1752__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1753 struct wireless_dev *wdev,
1754 const void *data,
1755 int data_len)
1756{
1757 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1758 struct net_device *dev = wdev->netdev;
1759 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1760 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1761 int32_t status;
1762
1763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1764 if (VOS_FTM_MODE == hdd_get_conparam()) {
1765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1766 status = -EPERM;
1767 goto out;
1768 }
1769
1770 status = wlan_hdd_validate_context(hdd_ctx);
1771 if (0 != status)
1772 goto out;
1773
1774
1775 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1776 data, data_len, NULL);
1777 if (status) {
1778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1779 goto out;
1780 }
1781
1782 /* Parse and fetch Command Type*/
1783 if (tb[STATION_INFO]) {
1784 status = hdd_get_station_info(hdd_ctx, adapter);
1785 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1786 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301787 } else if (tb[STATION_REMOTE]) {
1788 v_MACADDR_t mac_addr;
1789
1790 if (adapter->device_mode != WLAN_HDD_SOFTAP &&
1791 adapter->device_mode != WLAN_HDD_P2P_GO) {
1792 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"invalid device_mode:%d",
1793 adapter->device_mode);
1794 status = -EINVAL;
1795 goto out;
1796 }
1797
1798 nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
1799 VOS_MAC_ADDRESS_LEN);
1800
1801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "STATION_REMOTE "MAC_ADDRESS_STR"",
1802 MAC_ADDR_ARRAY(mac_addr.bytes));
1803
1804 status = hdd_get_cached_station_remote(hdd_ctx, adapter,
1805 mac_addr);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301806 } else {
1807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1808 status = -EINVAL;
1809 goto out;
1810 }
1811 EXIT();
1812out:
1813 return status;
1814}
1815
1816/**
1817 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1818 * @wiphy: corestack handler
1819 * @wdev: wireless device
1820 * @data: data
1821 * @data_len: data length
1822 *
1823 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1824 * Validate cmd attributes and send the station info to upper layers.
1825 *
1826 * Return: Success(0) or reason code for failure
1827 */
1828static int32_t
1829hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1830 struct wireless_dev *wdev,
1831 const void *data,
1832 int data_len)
1833{
1834 int ret;
1835
1836 vos_ssr_protect(__func__);
1837 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1838 vos_ssr_unprotect(__func__);
1839
1840 return ret;
1841}
1842
1843/*
1844 * undef short names defined for get station command
1845 * used by __wlan_hdd_cfg80211_get_station_cmd()
1846 */
1847#undef STATION_INVALID
1848#undef STATION_INFO
1849#undef STATION_ASSOC_FAIL_REASON
1850#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301851
Sunil Duttc69bccb2014-05-26 21:30:20 +05301852#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1853
1854static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1855 struct sk_buff *vendor_event)
1856{
1857 if (nla_put_u8(vendor_event,
1858 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1859 stats->rate.preamble) ||
1860 nla_put_u8(vendor_event,
1861 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1862 stats->rate.nss) ||
1863 nla_put_u8(vendor_event,
1864 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1865 stats->rate.bw) ||
1866 nla_put_u8(vendor_event,
1867 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1868 stats->rate.rateMcsIdx) ||
1869 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1870 stats->rate.bitrate ) ||
1871 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1872 stats->txMpdu ) ||
1873 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1874 stats->rxMpdu ) ||
1875 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1876 stats->mpduLost ) ||
1877 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1878 stats->retries) ||
1879 nla_put_u32(vendor_event,
1880 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1881 stats->retriesShort ) ||
1882 nla_put_u32(vendor_event,
1883 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1884 stats->retriesLong))
1885 {
1886 hddLog(VOS_TRACE_LEVEL_ERROR,
1887 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1888 return FALSE;
1889 }
1890 return TRUE;
1891}
1892
1893static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1894 struct sk_buff *vendor_event)
1895{
1896 u32 i = 0;
1897 struct nlattr *rateInfo;
1898 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1899 stats->type) ||
1900 nla_put(vendor_event,
1901 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1902 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1903 nla_put_u32(vendor_event,
1904 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1905 stats->capabilities) ||
1906 nla_put_u32(vendor_event,
1907 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1908 stats->numRate))
1909 {
1910 hddLog(VOS_TRACE_LEVEL_ERROR,
1911 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1912 goto error;
1913 }
1914
1915 rateInfo = nla_nest_start(vendor_event,
1916 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301917 if(!rateInfo)
1918 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301919 for (i = 0; i < stats->numRate; i++)
1920 {
1921 struct nlattr *rates;
1922 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1923 stats->rateStats +
1924 (i * sizeof(tSirWifiRateStat)));
1925 rates = nla_nest_start(vendor_event, i);
Sourav Mohapatra37aa80a2018-10-31 10:57:00 +05301926
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301927 if(!rates)
1928 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301929
1930 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1931 {
1932 hddLog(VOS_TRACE_LEVEL_ERROR,
1933 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1934 return FALSE;
1935 }
1936 nla_nest_end(vendor_event, rates);
1937 }
1938 nla_nest_end(vendor_event, rateInfo);
1939
1940 return TRUE;
1941error:
1942 return FALSE;
1943}
1944
1945static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1946 struct sk_buff *vendor_event)
1947{
1948 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1949 stats->ac ) ||
1950 nla_put_u32(vendor_event,
1951 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1952 stats->txMpdu ) ||
1953 nla_put_u32(vendor_event,
1954 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1955 stats->rxMpdu ) ||
1956 nla_put_u32(vendor_event,
1957 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1958 stats->txMcast ) ||
1959 nla_put_u32(vendor_event,
1960 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1961 stats->rxMcast ) ||
1962 nla_put_u32(vendor_event,
1963 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1964 stats->rxAmpdu ) ||
1965 nla_put_u32(vendor_event,
1966 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1967 stats->txAmpdu ) ||
1968 nla_put_u32(vendor_event,
1969 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1970 stats->mpduLost )||
1971 nla_put_u32(vendor_event,
1972 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1973 stats->retries ) ||
1974 nla_put_u32(vendor_event,
1975 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1976 stats->retriesShort ) ||
1977 nla_put_u32(vendor_event,
1978 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1979 stats->retriesLong ) ||
1980 nla_put_u32(vendor_event,
1981 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1982 stats->contentionTimeMin ) ||
1983 nla_put_u32(vendor_event,
1984 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1985 stats->contentionTimeMax ) ||
1986 nla_put_u32(vendor_event,
1987 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1988 stats->contentionTimeAvg ) ||
1989 nla_put_u32(vendor_event,
1990 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1991 stats->contentionNumSamples ))
1992 {
1993 hddLog(VOS_TRACE_LEVEL_ERROR,
1994 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1995 return FALSE;
1996 }
1997 return TRUE;
1998}
1999
2000static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
2001 struct sk_buff *vendor_event)
2002{
Dino Myclec8f3f332014-07-21 16:48:27 +05302003 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302004 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
2005 nla_put(vendor_event,
2006 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
2007 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
2008 nla_put_u32(vendor_event,
2009 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
2010 stats->state ) ||
2011 nla_put_u32(vendor_event,
2012 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
2013 stats->roaming ) ||
2014 nla_put_u32(vendor_event,
2015 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
2016 stats->capabilities ) ||
2017 nla_put(vendor_event,
2018 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
2019 strlen(stats->ssid), stats->ssid) ||
2020 nla_put(vendor_event,
2021 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
2022 WNI_CFG_BSSID_LEN, stats->bssid) ||
2023 nla_put(vendor_event,
2024 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
2025 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
2026 nla_put(vendor_event,
2027 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
2028 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
2029 )
2030 {
2031 hddLog(VOS_TRACE_LEVEL_ERROR,
2032 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2033 return FALSE;
2034 }
2035 return TRUE;
2036}
2037
Dino Mycle3b9536d2014-07-09 22:05:24 +05302038static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
2039 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302040 struct sk_buff *vendor_event)
2041{
2042 int i = 0;
2043 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302044 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2045 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302046 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302047
Sunil Duttc69bccb2014-05-26 21:30:20 +05302048 if (FALSE == put_wifi_interface_info(
2049 &pWifiIfaceStat->info,
2050 vendor_event))
2051 {
2052 hddLog(VOS_TRACE_LEVEL_ERROR,
2053 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2054 return FALSE;
2055
2056 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05302057 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
2058 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
2059 if (NULL == pWifiIfaceStatTL)
2060 {
2061 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2062 return FALSE;
2063 }
2064
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302065 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
2066 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
2067 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
2068 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
2069
2070 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
2071 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
2072 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
2073 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302074
2075 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
2076 {
2077 if (VOS_STATUS_SUCCESS ==
2078 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2079 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
2080 {
2081 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
2082 * obtained from TL structure
2083 */
2084
2085 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
2086 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302087 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
2088
Srinivas Dasari98947432014-11-07 19:41:24 +05302089 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
2090 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
2091 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
2092 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
2093 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
2094 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
2095 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
2096 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302097
Srinivas Dasari98947432014-11-07 19:41:24 +05302098 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
2099 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
2100 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
2101 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
2102 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
2103 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
2104 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
2105 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302106
Srinivas Dasari98947432014-11-07 19:41:24 +05302107 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
2108 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
2109 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
2110 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
2111 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
2112 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
2113 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
2114 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302115 }
2116 else
2117 {
2118 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
2119 }
2120
Dino Mycle3b9536d2014-07-09 22:05:24 +05302121 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
2122 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
2123 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
2124 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
2125 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
2126 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
2127 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
2128 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
2129 }
2130 else
2131 {
2132 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
2133 }
2134
2135
Sunil Duttc69bccb2014-05-26 21:30:20 +05302136
2137 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302138 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2139 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
2140 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302141 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
2142 pWifiIfaceStat->beaconRx) ||
2143 nla_put_u32(vendor_event,
2144 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
2145 pWifiIfaceStat->mgmtRx) ||
2146 nla_put_u32(vendor_event,
2147 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
2148 pWifiIfaceStat->mgmtActionRx) ||
2149 nla_put_u32(vendor_event,
2150 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
2151 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302152 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302153 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
2154 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302155 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302156 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
2157 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302158 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302159 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
2160 pWifiIfaceStat->rssiAck))
2161 {
2162 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302163 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2164 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302165 return FALSE;
2166 }
2167
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302168#ifdef FEATURE_EXT_LL_STAT
2169 /*
2170 * Ensure when EXT_LL_STAT is supported by both host and fwr,
2171 * then host should send Leaky AP stats to upper layer,
2172 * otherwise no need to send these stats.
2173 */
2174 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
2175 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
2176 )
2177 {
2178 hddLog(VOS_TRACE_LEVEL_INFO,
2179 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
2180 pWifiIfaceStat->leakyApStat.is_leaky_ap,
2181 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
2182 pWifiIfaceStat->leakyApStat.rx_leak_window,
2183 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
2184 if (nla_put_u32(vendor_event,
2185 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
2186 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
2187 nla_put_u32(vendor_event,
2188 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
2189 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
2190 nla_put_u32(vendor_event,
2191 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
2192 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05302193 hdd_wlan_nla_put_u64(vendor_event,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302194 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
2195 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
2196 {
2197 hddLog(VOS_TRACE_LEVEL_ERROR,
2198 FL("EXT_LL_STAT put fail"));
2199 vos_mem_free(pWifiIfaceStatTL);
2200 return FALSE;
2201 }
2202 }
2203#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05302204 wmmInfo = nla_nest_start(vendor_event,
2205 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302206 if(!wmmInfo)
2207 {
2208 vos_mem_free(pWifiIfaceStatTL);
2209 return FALSE;
2210 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302211 for (i = 0; i < WIFI_AC_MAX; i++)
2212 {
2213 struct nlattr *wmmStats;
2214 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302215 if(!wmmStats)
2216 {
2217 vos_mem_free(pWifiIfaceStatTL);
2218 return FALSE;
2219 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302220 if (FALSE == put_wifi_wmm_ac_stat(
2221 &pWifiIfaceStat->AccessclassStats[i],
2222 vendor_event))
2223 {
2224 hddLog(VOS_TRACE_LEVEL_ERROR,
2225 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05302226 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302227 return FALSE;
2228 }
2229
2230 nla_nest_end(vendor_event, wmmStats);
2231 }
2232 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05302233 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302234 return TRUE;
2235}
2236
2237static tSirWifiInterfaceMode
2238 hdd_map_device_to_ll_iface_mode ( int deviceMode )
2239{
2240 switch (deviceMode)
2241 {
2242 case WLAN_HDD_INFRA_STATION:
2243 return WIFI_INTERFACE_STA;
2244 case WLAN_HDD_SOFTAP:
2245 return WIFI_INTERFACE_SOFTAP;
2246 case WLAN_HDD_P2P_CLIENT:
2247 return WIFI_INTERFACE_P2P_CLIENT;
2248 case WLAN_HDD_P2P_GO:
2249 return WIFI_INTERFACE_P2P_GO;
2250 case WLAN_HDD_IBSS:
2251 return WIFI_INTERFACE_IBSS;
2252 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05302253 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302254 }
2255}
2256
2257static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
2258 tpSirWifiInterfaceInfo pInfo)
2259{
2260 v_U8_t *staMac = NULL;
2261 hdd_station_ctx_t *pHddStaCtx;
2262 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2263 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
2264
2265 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
2266
2267 vos_mem_copy(pInfo->macAddr,
2268 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
2269
2270 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2271 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
2272 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
2273 {
2274 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2275 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
2276 {
2277 pInfo->state = WIFI_DISCONNECTED;
2278 }
2279 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
2280 {
2281 hddLog(VOS_TRACE_LEVEL_ERROR,
2282 "%s: Session ID %d, Connection is in progress", __func__,
2283 pAdapter->sessionId);
2284 pInfo->state = WIFI_ASSOCIATING;
2285 }
2286 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
2287 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
2288 {
2289 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
2290 hddLog(VOS_TRACE_LEVEL_ERROR,
2291 "%s: client " MAC_ADDRESS_STR
2292 " is in the middle of WPS/EAPOL exchange.", __func__,
2293 MAC_ADDR_ARRAY(staMac));
2294 pInfo->state = WIFI_AUTHENTICATING;
2295 }
2296 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
2297 {
2298 pInfo->state = WIFI_ASSOCIATED;
2299 vos_mem_copy(pInfo->bssid,
2300 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
2301 vos_mem_copy(pInfo->ssid,
2302 pHddStaCtx->conn_info.SSID.SSID.ssId,
2303 pHddStaCtx->conn_info.SSID.SSID.length);
2304 //NULL Terminate the string.
2305 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
2306 }
2307 }
2308 vos_mem_copy(pInfo->countryStr,
2309 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2310
2311 vos_mem_copy(pInfo->apCountryStr,
2312 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2313
2314 return TRUE;
2315}
2316
2317/*
2318 * hdd_link_layer_process_peer_stats () - This function is called after
2319 * receiving Link Layer Peer statistics from FW.This function converts
2320 * the firmware data to the NL data and sends the same to the kernel/upper
2321 * layers.
2322 */
2323static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
2324 v_VOID_t *pData)
2325{
2326 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302327 tpSirWifiPeerStat pWifiPeerStat;
2328 tpSirWifiPeerInfo pWifiPeerInfo;
2329 struct nlattr *peerInfo;
2330 struct sk_buff *vendor_event;
2331 int status, i;
2332
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302333 ENTER();
2334
Sunil Duttc69bccb2014-05-26 21:30:20 +05302335 status = wlan_hdd_validate_context(pHddCtx);
2336 if (0 != status)
2337 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302338 return;
2339 }
2340
2341 pWifiPeerStat = (tpSirWifiPeerStat) pData;
2342
2343 hddLog(VOS_TRACE_LEVEL_INFO,
2344 "LL_STATS_PEER_ALL : numPeers %u",
2345 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302346 /*
2347 * Allocate a size of 4096 for the peer stats comprising
2348 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
2349 * sizeof (tSirWifiRateStat).Each field is put with an
2350 * NL attribute.The size of 4096 is considered assuming
2351 * that number of rates shall not exceed beyond 50 with
2352 * the sizeof (tSirWifiRateStat) being 32.
2353 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302354 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2355 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302356 if (!vendor_event)
2357 {
2358 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302359 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05302360 __func__);
2361 return;
2362 }
2363 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302364 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2365 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
2366 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302367 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
2368 pWifiPeerStat->numPeers))
2369 {
2370 hddLog(VOS_TRACE_LEVEL_ERROR,
2371 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
2372 kfree_skb(vendor_event);
2373 return;
2374 }
2375
2376 peerInfo = nla_nest_start(vendor_event,
2377 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302378 if(!peerInfo)
2379 {
2380 hddLog(VOS_TRACE_LEVEL_ERROR,
2381 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
2382 __func__);
2383 kfree_skb(vendor_event);
2384 return;
2385 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302386
2387 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2388 pWifiPeerStat->peerInfo);
2389
2390 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
2391 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302392 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302393 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302394
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302395 if(!peers)
2396 {
2397 hddLog(VOS_TRACE_LEVEL_ERROR,
2398 "%s: peer stats put fail",
2399 __func__);
2400 kfree_skb(vendor_event);
2401 return;
2402 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302403 if (FALSE == put_wifi_peer_info(
2404 pWifiPeerInfo, vendor_event))
2405 {
2406 hddLog(VOS_TRACE_LEVEL_ERROR,
2407 "%s: put_wifi_peer_info put fail", __func__);
2408 kfree_skb(vendor_event);
2409 return;
2410 }
2411
Sourav Mohapatra37aa80a2018-10-31 10:57:00 +05302412 pWifiPeerInfo = (tpSirWifiPeerInfo)((uint8 *)pWifiPeerInfo +
2413 (sizeof(tSirWifiPeerInfo) - sizeof(tSirWifiRateStat)) +
2414 (numRate * sizeof(tSirWifiRateStat)));
2415
Sunil Duttc69bccb2014-05-26 21:30:20 +05302416 nla_nest_end(vendor_event, peers);
2417 }
2418 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302419 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302420 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302421}
2422
2423/*
2424 * hdd_link_layer_process_iface_stats () - This function is called after
2425 * receiving Link Layer Interface statistics from FW.This function converts
2426 * the firmware data to the NL data and sends the same to the kernel/upper
2427 * layers.
2428 */
2429static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
2430 v_VOID_t *pData)
2431{
2432 tpSirWifiIfaceStat pWifiIfaceStat;
2433 struct sk_buff *vendor_event;
2434 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2435 int status;
2436
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302437 ENTER();
2438
Sunil Duttc69bccb2014-05-26 21:30:20 +05302439 status = wlan_hdd_validate_context(pHddCtx);
2440 if (0 != status)
2441 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302442 return;
2443 }
2444 /*
2445 * Allocate a size of 4096 for the interface stats comprising
2446 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
2447 * assuming that all these fit with in the limit.Please take
2448 * a call on the limit based on the data requirements on
2449 * interface statistics.
2450 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302451 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2452 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302453 if (!vendor_event)
2454 {
2455 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302456 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302457 return;
2458 }
2459
2460 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
2461
Dino Mycle3b9536d2014-07-09 22:05:24 +05302462
2463 if (FALSE == hdd_get_interface_info( pAdapter,
2464 &pWifiIfaceStat->info))
2465 {
2466 hddLog(VOS_TRACE_LEVEL_ERROR,
2467 FL("hdd_get_interface_info get fail") );
2468 kfree_skb(vendor_event);
2469 return;
2470 }
2471
2472 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
2473 vendor_event))
2474 {
2475 hddLog(VOS_TRACE_LEVEL_ERROR,
2476 FL("put_wifi_iface_stats fail") );
2477 kfree_skb(vendor_event);
2478 return;
2479 }
2480
Sunil Duttc69bccb2014-05-26 21:30:20 +05302481 hddLog(VOS_TRACE_LEVEL_INFO,
2482 "WMI_LINK_STATS_IFACE Data");
2483
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302484 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302485
2486 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302487}
2488
2489/*
2490 * hdd_link_layer_process_radio_stats () - This function is called after
2491 * receiving Link Layer Radio statistics from FW.This function converts
2492 * the firmware data to the NL data and sends the same to the kernel/upper
2493 * layers.
2494 */
2495static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
2496 v_VOID_t *pData)
2497{
2498 int status, i;
2499 tpSirWifiRadioStat pWifiRadioStat;
2500 tpSirWifiChannelStats pWifiChannelStats;
2501 struct sk_buff *vendor_event;
2502 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2503 struct nlattr *chList;
2504
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302505 ENTER();
2506
Sunil Duttc69bccb2014-05-26 21:30:20 +05302507 status = wlan_hdd_validate_context(pHddCtx);
2508 if (0 != status)
2509 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302510 return;
2511 }
2512 pWifiRadioStat = (tpSirWifiRadioStat) pData;
2513
2514 hddLog(VOS_TRACE_LEVEL_INFO,
2515 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302516 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05302517 " radio is %d onTime is %u "
2518 " txTime is %u rxTime is %u "
2519 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05302520 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05302521 " onTimePnoScan is %u onTimeHs20 is %u "
2522 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302523 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302524 pWifiRadioStat->radio, pWifiRadioStat->onTime,
2525 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
2526 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302527 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302528 pWifiRadioStat->onTimeRoamScan,
2529 pWifiRadioStat->onTimePnoScan,
2530 pWifiRadioStat->onTimeHs20,
2531 pWifiRadioStat->numChannels);
2532 /*
2533 * Allocate a size of 4096 for the Radio stats comprising
2534 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
2535 * (tSirWifiChannelStats).Each channel data is put with an
2536 * NL attribute.The size of 4096 is considered assuming that
2537 * number of channels shall not exceed beyond 60 with the
2538 * sizeof (tSirWifiChannelStats) being 24 bytes.
2539 */
2540
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302541 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2542 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302543 if (!vendor_event)
2544 {
2545 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302546 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302547 return;
2548 }
2549
2550 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302551 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2552 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2553 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302554 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2555 pWifiRadioStat->radio) ||
2556 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302557 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2558 NUM_RADIOS) ||
2559 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302560 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2561 pWifiRadioStat->onTime) ||
2562 nla_put_u32(vendor_event,
2563 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2564 pWifiRadioStat->txTime) ||
2565 nla_put_u32(vendor_event,
2566 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2567 pWifiRadioStat->rxTime) ||
2568 nla_put_u32(vendor_event,
2569 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2570 pWifiRadioStat->onTimeScan) ||
2571 nla_put_u32(vendor_event,
2572 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2573 pWifiRadioStat->onTimeNbd) ||
2574 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302575 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2576 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302577 nla_put_u32(vendor_event,
2578 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2579 pWifiRadioStat->onTimeRoamScan) ||
2580 nla_put_u32(vendor_event,
2581 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2582 pWifiRadioStat->onTimePnoScan) ||
2583 nla_put_u32(vendor_event,
2584 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2585 pWifiRadioStat->onTimeHs20) ||
2586 nla_put_u32(vendor_event,
2587 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2588 pWifiRadioStat->numChannels))
2589 {
2590 hddLog(VOS_TRACE_LEVEL_ERROR,
2591 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2592 kfree_skb(vendor_event);
2593 return ;
2594 }
2595
2596 chList = nla_nest_start(vendor_event,
2597 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302598 if(!chList)
2599 {
2600 hddLog(VOS_TRACE_LEVEL_ERROR,
2601 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2602 __func__);
2603 kfree_skb(vendor_event);
2604 return;
2605 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302606 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2607 {
2608 struct nlattr *chInfo;
2609
2610 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2611 pWifiRadioStat->channels +
2612 (i * sizeof(tSirWifiChannelStats)));
2613
Sunil Duttc69bccb2014-05-26 21:30:20 +05302614 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302615 if(!chInfo)
2616 {
2617 hddLog(VOS_TRACE_LEVEL_ERROR,
2618 "%s: failed to put chInfo",
2619 __func__);
2620 kfree_skb(vendor_event);
2621 return;
2622 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302623
2624 if (nla_put_u32(vendor_event,
2625 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2626 pWifiChannelStats->channel.width) ||
2627 nla_put_u32(vendor_event,
2628 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2629 pWifiChannelStats->channel.centerFreq) ||
2630 nla_put_u32(vendor_event,
2631 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2632 pWifiChannelStats->channel.centerFreq0) ||
2633 nla_put_u32(vendor_event,
2634 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2635 pWifiChannelStats->channel.centerFreq1) ||
2636 nla_put_u32(vendor_event,
2637 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2638 pWifiChannelStats->onTime) ||
2639 nla_put_u32(vendor_event,
2640 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2641 pWifiChannelStats->ccaBusyTime))
2642 {
2643 hddLog(VOS_TRACE_LEVEL_ERROR,
2644 FL("cfg80211_vendor_event_alloc failed") );
2645 kfree_skb(vendor_event);
2646 return ;
2647 }
2648 nla_nest_end(vendor_event, chInfo);
2649 }
2650 nla_nest_end(vendor_event, chList);
2651
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302652 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302653
2654 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302655 return;
2656}
2657
2658/*
2659 * hdd_link_layer_stats_ind_callback () - This function is called after
2660 * receiving Link Layer indications from FW.This callback converts the firmware
2661 * data to the NL data and send the same to the kernel/upper layers.
2662 */
2663static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2664 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302665 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302666{
Dino Mycled3d50022014-07-07 12:58:25 +05302667 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2668 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302669 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302670 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302671 int status;
2672
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302673 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302674
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302675 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302676 if (0 != status)
2677 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302678 return;
2679 }
2680
Dino Mycled3d50022014-07-07 12:58:25 +05302681 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2682 if (NULL == pAdapter)
2683 {
2684 hddLog(VOS_TRACE_LEVEL_ERROR,
2685 FL(" MAC address %pM does not exist with host"),
2686 macAddr);
2687 return;
2688 }
2689
Sunil Duttc69bccb2014-05-26 21:30:20 +05302690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302691 "%s: Interface: %s LLStats indType: %d", __func__,
2692 pAdapter->dev->name, indType);
2693
Sunil Duttc69bccb2014-05-26 21:30:20 +05302694 switch (indType)
2695 {
2696 case SIR_HAL_LL_STATS_RESULTS_RSP:
2697 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302698 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302699 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2700 "respId = %u, moreResultToFollow = %u",
2701 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2702 macAddr, linkLayerStatsResults->respId,
2703 linkLayerStatsResults->moreResultToFollow);
2704
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302705 spin_lock(&hdd_context_lock);
2706 context = &pHddCtx->ll_stats_context;
2707 /* validate response received from target */
2708 if ((context->request_id != linkLayerStatsResults->respId) ||
2709 !(context->request_bitmap & linkLayerStatsResults->paramId))
2710 {
2711 spin_unlock(&hdd_context_lock);
2712 hddLog(LOGE,
2713 FL("Error : Request id %d response id %d request bitmap 0x%x"
2714 "response bitmap 0x%x"),
2715 context->request_id, linkLayerStatsResults->respId,
2716 context->request_bitmap, linkLayerStatsResults->paramId);
2717 return;
2718 }
2719 spin_unlock(&hdd_context_lock);
2720
Sunil Duttc69bccb2014-05-26 21:30:20 +05302721 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2722 {
2723 hdd_link_layer_process_radio_stats(pAdapter,
2724 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302725 spin_lock(&hdd_context_lock);
2726 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2727 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302728 }
2729 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2730 {
2731 hdd_link_layer_process_iface_stats(pAdapter,
2732 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302733 spin_lock(&hdd_context_lock);
2734 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2735 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302736 }
2737 else if ( linkLayerStatsResults->paramId &
2738 WMI_LINK_STATS_ALL_PEER )
2739 {
2740 hdd_link_layer_process_peer_stats(pAdapter,
2741 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302742 spin_lock(&hdd_context_lock);
2743 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2744 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302745 } /* WMI_LINK_STATS_ALL_PEER */
2746 else
2747 {
2748 hddLog(VOS_TRACE_LEVEL_ERROR,
2749 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2750 }
2751
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302752 spin_lock(&hdd_context_lock);
2753 /* complete response event if all requests are completed */
2754 if (0 == context->request_bitmap)
2755 complete(&context->response_event);
2756 spin_unlock(&hdd_context_lock);
2757
Sunil Duttc69bccb2014-05-26 21:30:20 +05302758 break;
2759 }
2760 default:
2761 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2762 break;
2763 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302764
2765 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302766 return;
2767}
2768
2769const struct
2770nla_policy
2771qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2772{
2773 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2774 { .type = NLA_U32 },
2775 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2776 { .type = NLA_U32 },
2777};
2778
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302779static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2780 struct wireless_dev *wdev,
2781 const void *data,
2782 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302783{
2784 int status;
2785 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302786 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302787 struct net_device *dev = wdev->netdev;
2788 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2789 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2790
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302791 ENTER();
2792
Sunil Duttc69bccb2014-05-26 21:30:20 +05302793 status = wlan_hdd_validate_context(pHddCtx);
2794 if (0 != status)
2795 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302796 return -EINVAL;
2797 }
2798
2799 if (NULL == pAdapter)
2800 {
2801 hddLog(VOS_TRACE_LEVEL_ERROR,
2802 FL("HDD adapter is Null"));
2803 return -ENODEV;
2804 }
Ashish Kumar Dhanotiyabdcafda2018-12-11 18:54:41 +05302805
2806 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION) {
2807 hddLog(VOS_TRACE_LEVEL_DEBUG,
2808 "Cannot set LL_STATS for device mode %d",
2809 pAdapter->device_mode);
2810 return -EINVAL;
2811 }
2812
Dino Mycledf0a5d92014-07-04 09:41:55 +05302813 /* check the LLStats Capability */
2814 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2815 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2816 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302817 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302818 FL("Link Layer Statistics not supported by Firmware"));
2819 return -EINVAL;
2820 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302821
2822 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2823 (struct nlattr *)data,
2824 data_len, qca_wlan_vendor_ll_set_policy))
2825 {
2826 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2827 return -EINVAL;
2828 }
2829 if (!tb_vendor
2830 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2831 {
2832 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2833 return -EINVAL;
2834 }
2835 if (!tb_vendor[
2836 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2837 {
2838 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2839 return -EINVAL;
2840 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302841 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302842 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302843
Dino Mycledf0a5d92014-07-04 09:41:55 +05302844 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302845 nla_get_u32(
2846 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2847
Dino Mycledf0a5d92014-07-04 09:41:55 +05302848 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302849 nla_get_u32(
2850 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2851
Dino Mycled3d50022014-07-07 12:58:25 +05302852 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2853 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302854
2855
2856 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302857 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2858 "Statistics Gathering = %d ",
2859 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2860 linkLayerStatsSetReq.mpduSizeThreshold,
2861 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302862
2863 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2864 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302865 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302866 {
2867 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2868 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302869 return -EINVAL;
2870
2871 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302872
Sunil Duttc69bccb2014-05-26 21:30:20 +05302873 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302874 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302875 {
2876 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2877 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302878 return -EINVAL;
2879 }
2880
2881 pAdapter->isLinkLayerStatsSet = 1;
2882
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302883 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302884 return 0;
2885}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302886static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2887 struct wireless_dev *wdev,
2888 const void *data,
2889 int data_len)
2890{
2891 int ret = 0;
2892
2893 vos_ssr_protect(__func__);
2894 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2895 vos_ssr_unprotect(__func__);
2896
2897 return ret;
2898}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302899
2900const struct
2901nla_policy
2902qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2903{
2904 /* Unsigned 32bit value provided by the caller issuing the GET stats
2905 * command. When reporting
2906 * the stats results, the driver uses the same value to indicate
2907 * which GET request the results
2908 * correspond to.
2909 */
2910 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2911
2912 /* Unsigned 32bit value . bit mask to identify what statistics are
2913 requested for retrieval */
2914 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2915};
2916
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302917static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2918 struct wireless_dev *wdev,
2919 const void *data,
2920 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302921{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302922 unsigned long rc;
2923 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302924 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2925 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302926 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302927 struct net_device *dev = wdev->netdev;
2928 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302929 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302930 int status;
2931
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302932 ENTER();
2933
Sunil Duttc69bccb2014-05-26 21:30:20 +05302934 status = wlan_hdd_validate_context(pHddCtx);
2935 if (0 != status)
2936 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302937 return -EINVAL ;
2938 }
2939
2940 if (NULL == pAdapter)
2941 {
2942 hddLog(VOS_TRACE_LEVEL_FATAL,
2943 "%s: HDD adapter is Null", __func__);
2944 return -ENODEV;
2945 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302946
2947 if (pHddStaCtx == NULL)
2948 {
2949 hddLog(VOS_TRACE_LEVEL_FATAL,
2950 "%s: HddStaCtx is Null", __func__);
2951 return -ENODEV;
2952 }
2953
Dino Mycledf0a5d92014-07-04 09:41:55 +05302954 /* check the LLStats Capability */
2955 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2956 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2957 {
2958 hddLog(VOS_TRACE_LEVEL_ERROR,
2959 FL("Link Layer Statistics not supported by Firmware"));
2960 return -EINVAL;
2961 }
2962
Sunil Duttc69bccb2014-05-26 21:30:20 +05302963
2964 if (!pAdapter->isLinkLayerStatsSet)
2965 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302966 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302967 "%s: isLinkLayerStatsSet : %d",
2968 __func__, pAdapter->isLinkLayerStatsSet);
2969 return -EINVAL;
2970 }
2971
Mukul Sharma10313ba2015-07-29 19:14:39 +05302972 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2973 {
2974 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2975 "%s: Roaming in progress, so unable to proceed this request", __func__);
2976 return -EBUSY;
2977 }
2978
Sunil Duttc69bccb2014-05-26 21:30:20 +05302979 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2980 (struct nlattr *)data,
2981 data_len, qca_wlan_vendor_ll_get_policy))
2982 {
2983 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2984 return -EINVAL;
2985 }
2986
2987 if (!tb_vendor
2988 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2989 {
2990 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2991 return -EINVAL;
2992 }
2993
2994 if (!tb_vendor
2995 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2996 {
2997 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2998 return -EINVAL;
2999 }
3000
Sunil Duttc69bccb2014-05-26 21:30:20 +05303001
Dino Mycledf0a5d92014-07-04 09:41:55 +05303002 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303003 nla_get_u32( tb_vendor[
3004 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05303005 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303006 nla_get_u32( tb_vendor[
3007 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
3008
Dino Mycled3d50022014-07-07 12:58:25 +05303009 vos_mem_copy(linkLayerStatsGetReq.macAddr,
3010 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05303011
3012 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05303013 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
3014 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303015 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303016
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303017 spin_lock(&hdd_context_lock);
3018 context = &pHddCtx->ll_stats_context;
3019 context->request_id = linkLayerStatsGetReq.reqId;
3020 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
3021 INIT_COMPLETION(context->response_event);
3022 spin_unlock(&hdd_context_lock);
3023
Sunil Duttc69bccb2014-05-26 21:30:20 +05303024 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303025 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303026 {
3027 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3028 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303029 return -EINVAL;
3030 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303031
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303032 rc = wait_for_completion_timeout(&context->response_event,
3033 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
3034 if (!rc)
3035 {
3036 hddLog(LOGE,
3037 FL("Target response timed out request id %d request bitmap 0x%x"),
3038 context->request_id, context->request_bitmap);
3039 return -ETIMEDOUT;
3040 }
3041
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303042 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303043 return 0;
3044}
3045
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303046static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
3047 struct wireless_dev *wdev,
3048 const void *data,
3049 int data_len)
3050{
3051 int ret = 0;
3052
3053 vos_ssr_protect(__func__);
3054 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
3055 vos_ssr_unprotect(__func__);
3056
3057 return ret;
3058}
3059
Sunil Duttc69bccb2014-05-26 21:30:20 +05303060const struct
3061nla_policy
3062qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
3063{
3064 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
3065 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
3066 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
3067 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
3068};
3069
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303070static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3071 struct wireless_dev *wdev,
3072 const void *data,
3073 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303074{
3075 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3076 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05303077 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303078 struct net_device *dev = wdev->netdev;
3079 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3080 u32 statsClearReqMask;
3081 u8 stopReq;
3082 int status;
3083
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303084 ENTER();
3085
Sunil Duttc69bccb2014-05-26 21:30:20 +05303086 status = wlan_hdd_validate_context(pHddCtx);
3087 if (0 != status)
3088 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303089 return -EINVAL;
3090 }
3091
3092 if (NULL == pAdapter)
3093 {
3094 hddLog(VOS_TRACE_LEVEL_FATAL,
3095 "%s: HDD adapter is Null", __func__);
3096 return -ENODEV;
3097 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05303098 /* check the LLStats Capability */
3099 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
3100 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
3101 {
3102 hddLog(VOS_TRACE_LEVEL_ERROR,
3103 FL("Enable LLStats Capability"));
3104 return -EINVAL;
3105 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05303106
3107 if (!pAdapter->isLinkLayerStatsSet)
3108 {
3109 hddLog(VOS_TRACE_LEVEL_FATAL,
3110 "%s: isLinkLayerStatsSet : %d",
3111 __func__, pAdapter->isLinkLayerStatsSet);
3112 return -EINVAL;
3113 }
3114
3115 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
3116 (struct nlattr *)data,
3117 data_len, qca_wlan_vendor_ll_clr_policy))
3118 {
3119 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
3120 return -EINVAL;
3121 }
3122
3123 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
3124
3125 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
3126 {
3127 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
3128 return -EINVAL;
3129
3130 }
3131
Sunil Duttc69bccb2014-05-26 21:30:20 +05303132
Dino Mycledf0a5d92014-07-04 09:41:55 +05303133 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303134 nla_get_u32(
3135 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
3136
Dino Mycledf0a5d92014-07-04 09:41:55 +05303137 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303138 nla_get_u8(
3139 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
3140
3141 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05303142 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303143
Dino Mycled3d50022014-07-07 12:58:25 +05303144 vos_mem_copy(linkLayerStatsClearReq.macAddr,
3145 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05303146
3147 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05303148 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
3149 "statsClearReqMask = 0x%X, stopReq = %d",
3150 linkLayerStatsClearReq.reqId,
3151 linkLayerStatsClearReq.macAddr,
3152 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303153 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303154
3155 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303156 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303157 {
3158 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05303159 hdd_station_ctx_t *pHddStaCtx;
3160
3161 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3162 if (VOS_STATUS_SUCCESS !=
3163 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
3164 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
3165 {
3166 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3167 "WLANTL_ClearInterfaceStats Failed", __func__);
3168 return -EINVAL;
3169 }
3170 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
3171 (statsClearReqMask & WIFI_STATS_IFACE)) {
3172 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
3173 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
3174 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
3175 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
3176 }
3177
Sunil Duttc69bccb2014-05-26 21:30:20 +05303178 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
3179 2 * sizeof(u32) +
3180 NLMSG_HDRLEN);
3181
3182 if (temp_skbuff != NULL)
3183 {
3184
3185 if (nla_put_u32(temp_skbuff,
3186 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
3187 statsClearReqMask) ||
3188 nla_put_u32(temp_skbuff,
3189 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
3190 stopReq))
3191 {
3192 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
3193 kfree_skb(temp_skbuff);
3194 return -EINVAL;
3195 }
3196 /* If the ask is to stop the stats collection as part of clear
3197 * (stopReq = 1) , ensure that no further requests of get
3198 * go to the firmware by having isLinkLayerStatsSet set to 0.
3199 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303200 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05303201 * case the firmware is just asked to clear the statistics.
3202 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05303203 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303204 pAdapter->isLinkLayerStatsSet = 0;
3205 return cfg80211_vendor_cmd_reply(temp_skbuff);
3206 }
3207 return -ENOMEM;
3208 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303209
3210 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303211 return -EINVAL;
3212}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303213static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3214 struct wireless_dev *wdev,
3215 const void *data,
3216 int data_len)
3217{
3218 int ret = 0;
3219
3220 vos_ssr_protect(__func__);
3221 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
3222 vos_ssr_unprotect(__func__);
3223
3224 return ret;
3225
3226
3227}
Sunil Duttc69bccb2014-05-26 21:30:20 +05303228#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
3229
Dino Mycle6fb96c12014-06-10 11:52:40 +05303230#ifdef WLAN_FEATURE_EXTSCAN
3231static const struct nla_policy
3232wlan_hdd_extscan_config_policy
3233 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
3234{
3235 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
3236 { .type = NLA_U32 },
3237 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
3238 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05303239 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
3240 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303241 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
3242 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
3243 { .type = NLA_U32 },
3244 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
3245 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
3246
3247 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
3248 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
3249 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
3250 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
3251 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303252 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
3253 { .type = NLA_U32 },
3254 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
3255 { .type = NLA_U32 },
3256 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
3257 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303258 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
3259 { .type = NLA_U32 },
3260 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
3261 { .type = NLA_U32 },
3262 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
3263 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303264 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
3265 { .type = NLA_U8 },
3266 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303267 { .type = NLA_U8 },
3268 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
3269 { .type = NLA_U8 },
3270 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
3271 { .type = NLA_U8 },
3272
3273 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
3274 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05303275 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
3276 .type = NLA_UNSPEC,
3277 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05303278 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
3279 { .type = NLA_S32 },
3280 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
3281 { .type = NLA_S32 },
3282 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
3283 { .type = NLA_U32 },
3284 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
3285 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303286 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
3287 { .type = NLA_U32 },
3288 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
3289 { .type = NLA_BINARY,
3290 .len = IEEE80211_MAX_SSID_LEN + 1 },
3291 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303292 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303293 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
3294 { .type = NLA_U32 },
3295 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
3296 { .type = NLA_U8 },
3297 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
3298 { .type = NLA_S32 },
3299 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
3300 { .type = NLA_S32 },
3301 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
3302 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303303};
3304
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303305/**
3306 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
3307 * @ctx: hdd global context
3308 * @data: capabilities data
3309 *
3310 * Return: none
3311 */
3312static void
3313wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303314{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303315 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303316 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303317 tSirEXTScanCapabilitiesEvent *data =
3318 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303319
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303320 ENTER();
3321
3322 if (wlan_hdd_validate_context(pHddCtx))
3323 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303324 return;
3325 }
3326
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303327 if (!pMsg)
3328 {
3329 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3330 return;
3331 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303332
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303333 vos_spin_lock_acquire(&hdd_context_lock);
3334
3335 context = &pHddCtx->ext_scan_context;
3336 /* validate response received from target*/
3337 if (context->request_id != data->requestId)
3338 {
3339 vos_spin_lock_release(&hdd_context_lock);
3340 hddLog(LOGE,
3341 FL("Target response id did not match: request_id %d resposne_id %d"),
3342 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303343 return;
3344 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303345 else
3346 {
3347 context->capability_response = *data;
3348 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303349 }
3350
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303351 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303352
Dino Mycle6fb96c12014-06-10 11:52:40 +05303353 return;
3354}
3355
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303356/*
3357 * define short names for the global vendor params
3358 * used by wlan_hdd_send_ext_scan_capability()
3359 */
3360#define PARAM_REQUEST_ID \
3361 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3362#define PARAM_STATUS \
3363 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
3364#define MAX_SCAN_CACHE_SIZE \
3365 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
3366#define MAX_SCAN_BUCKETS \
3367 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
3368#define MAX_AP_CACHE_PER_SCAN \
3369 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
3370#define MAX_RSSI_SAMPLE_SIZE \
3371 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
3372#define MAX_SCAN_RPT_THRHOLD \
3373 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
3374#define MAX_HOTLIST_BSSIDS \
3375 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
3376#define MAX_BSSID_HISTORY_ENTRIES \
3377 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
3378#define MAX_HOTLIST_SSIDS \
3379 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303380#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
3381 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303382
3383static int wlan_hdd_send_ext_scan_capability(void *ctx)
3384{
3385 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3386 struct sk_buff *skb = NULL;
3387 int ret;
3388 tSirEXTScanCapabilitiesEvent *data;
3389 tANI_U32 nl_buf_len;
3390
3391 ret = wlan_hdd_validate_context(pHddCtx);
3392 if (0 != ret)
3393 {
3394 return ret;
3395 }
3396
3397 data = &(pHddCtx->ext_scan_context.capability_response);
3398
3399 nl_buf_len = NLMSG_HDRLEN;
3400 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
3401 (sizeof(data->status) + NLA_HDRLEN) +
3402 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
3403 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
3404 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
3405 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
3406 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
3407 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
3408 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
3409 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
3410
3411 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
3412
3413 if (!skb)
3414 {
3415 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
3416 return -ENOMEM;
3417 }
3418
3419 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
3420 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
3421 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
3422 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
3423 data->maxRssiSampleSize, data->maxScanReportingThreshold);
3424 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
3425 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
3426 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
3427
3428 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
3429 nla_put_u32(skb, PARAM_STATUS, data->status) ||
3430 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
3431 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
3432 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
3433 data->maxApPerScan) ||
3434 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
3435 data->maxRssiSampleSize) ||
3436 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
3437 data->maxScanReportingThreshold) ||
3438 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
3439 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
3440 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303441 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
3442 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303443 {
3444 hddLog(LOGE, FL("nla put fail"));
3445 goto nla_put_failure;
3446 }
3447
3448 cfg80211_vendor_cmd_reply(skb);
3449 return 0;
3450
3451nla_put_failure:
3452 kfree_skb(skb);
3453 return -EINVAL;;
3454}
3455
3456/*
3457 * done with short names for the global vendor params
3458 * used by wlan_hdd_send_ext_scan_capability()
3459 */
3460#undef PARAM_REQUEST_ID
3461#undef PARAM_STATUS
3462#undef MAX_SCAN_CACHE_SIZE
3463#undef MAX_SCAN_BUCKETS
3464#undef MAX_AP_CACHE_PER_SCAN
3465#undef MAX_RSSI_SAMPLE_SIZE
3466#undef MAX_SCAN_RPT_THRHOLD
3467#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303468#undef MAX_BSSID_HISTORY_ENTRIES
3469#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05303470
3471static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
3472{
3473 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
3474 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303475 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303476 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303477
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303478 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303479
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303480 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303481 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303482
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303483 if (!pMsg)
3484 {
3485 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303486 return;
3487 }
3488
Dino Mycle6fb96c12014-06-10 11:52:40 +05303489 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3490 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
3491
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303492 context = &pHddCtx->ext_scan_context;
3493 spin_lock(&hdd_context_lock);
3494 if (context->request_id == pData->requestId) {
3495 context->response_status = pData->status ? -EINVAL : 0;
3496 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303497 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303498 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303499
3500 /*
3501 * Store the Request ID for comparing with the requestID obtained
3502 * in other requests.HDD shall return a failure is the extscan_stop
3503 * request is issued with a different requestId as that of the
3504 * extscan_start request. Also, This requestId shall be used while
3505 * indicating the full scan results to the upper layers.
3506 * The requestId is stored with the assumption that the firmware
3507 * shall return the ext scan start request's requestId in ext scan
3508 * start response.
3509 */
3510 if (pData->status == 0)
3511 pMac->sme.extScanStartReqId = pData->requestId;
3512
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303513 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303514 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303515}
3516
3517
3518static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
3519{
3520 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
3521 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303522 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303523
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303524 ENTER();
3525
3526 if (wlan_hdd_validate_context(pHddCtx)){
3527 return;
3528 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303529
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303530 if (!pMsg)
3531 {
3532 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303533 return;
3534 }
3535
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303536 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3537 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303538
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303539 context = &pHddCtx->ext_scan_context;
3540 spin_lock(&hdd_context_lock);
3541 if (context->request_id == pData->requestId) {
3542 context->response_status = pData->status ? -EINVAL : 0;
3543 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303544 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303545 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303546
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303547 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303548 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303549}
3550
Dino Mycle6fb96c12014-06-10 11:52:40 +05303551static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3552 void *pMsg)
3553{
3554 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303555 tpSirEXTScanSetBssidHotListRspParams pData =
3556 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303557 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303558
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303559 ENTER();
3560
3561 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303562 return;
3563 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303564
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303565 if (!pMsg)
3566 {
3567 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3568 return;
3569 }
3570
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303571 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3572 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303573
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303574 context = &pHddCtx->ext_scan_context;
3575 spin_lock(&hdd_context_lock);
3576 if (context->request_id == pData->requestId) {
3577 context->response_status = pData->status ? -EINVAL : 0;
3578 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303579 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303580 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303581
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303582 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303583 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303584}
3585
3586static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3587 void *pMsg)
3588{
3589 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303590 tpSirEXTScanResetBssidHotlistRspParams pData =
3591 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303592 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303593
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303594 ENTER();
3595
3596 if (wlan_hdd_validate_context(pHddCtx)) {
3597 return;
3598 }
3599 if (!pMsg)
3600 {
3601 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303602 return;
3603 }
3604
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303605 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3606 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303607
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303608 context = &pHddCtx->ext_scan_context;
3609 spin_lock(&hdd_context_lock);
3610 if (context->request_id == pData->requestId) {
3611 context->response_status = pData->status ? -EINVAL : 0;
3612 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303613 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303614 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303615
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303616 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303617 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303618}
3619
Dino Mycle6fb96c12014-06-10 11:52:40 +05303620static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3621 void *pMsg)
3622{
3623 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3624 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303625 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303626 tANI_S32 totalResults;
3627 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303628 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3629 struct hdd_ext_scan_context *context;
3630 bool ignore_cached_results = false;
3631 tExtscanCachedScanResult *result;
3632 struct nlattr *nla_results;
3633 tANI_U16 ieLength= 0;
3634 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303635
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303636 ENTER();
3637
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303638 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303639 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303640
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303641 if (!pMsg)
3642 {
3643 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3644 return;
3645 }
3646
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303647 spin_lock(&hdd_context_lock);
3648 context = &pHddCtx->ext_scan_context;
3649 ignore_cached_results = context->ignore_cached_results;
3650 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303651
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303652 if (ignore_cached_results) {
3653 hddLog(LOGE,
3654 FL("Ignore the cached results received after timeout"));
3655 return;
3656 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303657
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303658 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3659 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303660
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303661 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303662
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303663 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3664 scan_id_index++) {
3665 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303666
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303667 totalResults = result->num_results;
3668 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3669 result->scan_id, result->flags, totalResults);
3670 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303671
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303672 do{
3673 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3674 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3675 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303676
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303677 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3678 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3679
3680 if (!skb) {
3681 hddLog(VOS_TRACE_LEVEL_ERROR,
3682 FL("cfg80211_vendor_event_alloc failed"));
3683 return;
3684 }
3685
3686 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3687
3688 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3689 pData->requestId) ||
3690 nla_put_u32(skb,
3691 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3692 resultsPerEvent)) {
3693 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3694 goto fail;
3695 }
3696 if (nla_put_u8(skb,
3697 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3698 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303699 {
3700 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3701 goto fail;
3702 }
3703
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303704 if (nla_put_u32(skb,
3705 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3706 result->scan_id)) {
3707 hddLog(LOGE, FL("put fail"));
3708 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303709 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303710
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303711 nla_results = nla_nest_start(skb,
3712 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3713 if (!nla_results)
3714 goto fail;
3715
3716 if (resultsPerEvent) {
3717 struct nlattr *aps;
3718 struct nlattr *nla_result;
3719
3720 nla_result = nla_nest_start(skb, scan_id_index);
3721 if(!nla_result)
3722 goto fail;
3723
3724 if (nla_put_u32(skb,
3725 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3726 result->scan_id) ||
3727 nla_put_u32(skb,
3728 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3729 result->flags) ||
3730 nla_put_u32(skb,
3731 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3732 totalResults)) {
3733 hddLog(LOGE, FL("put fail"));
3734 goto fail;
3735 }
3736
3737 aps = nla_nest_start(skb,
3738 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3739 if (!aps)
3740 {
3741 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3742 goto fail;
3743 }
3744
3745 head_ptr = (tpSirWifiScanResult) &(result->ap);
3746
3747 for (j = 0; j < resultsPerEvent; j++, i++) {
3748 struct nlattr *ap;
3749 pSirWifiScanResult = head_ptr + i;
3750
3751 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303752 * Firmware returns timestamp from extscan_start till
3753 * BSSID was cached (in micro seconds). Add this with
3754 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303755 * to derive the time since boot when the
3756 * BSSID was cached.
3757 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303758 pSirWifiScanResult->ts +=
3759 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303760 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3761 "Ssid (%s)"
3762 "Bssid: %pM "
3763 "Channel (%u)"
3764 "Rssi (%d)"
3765 "RTT (%u)"
3766 "RTT_SD (%u)"
3767 "Beacon Period %u"
3768 "Capability 0x%x "
3769 "Ie length %d",
3770 i,
3771 pSirWifiScanResult->ts,
3772 pSirWifiScanResult->ssid,
3773 pSirWifiScanResult->bssid,
3774 pSirWifiScanResult->channel,
3775 pSirWifiScanResult->rssi,
3776 pSirWifiScanResult->rtt,
3777 pSirWifiScanResult->rtt_sd,
3778 pSirWifiScanResult->beaconPeriod,
3779 pSirWifiScanResult->capability,
3780 ieLength);
3781
3782 ap = nla_nest_start(skb, j + 1);
3783 if (!ap)
3784 {
3785 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3786 goto fail;
3787 }
3788
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303789 if (hdd_wlan_nla_put_u64(skb,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303790 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3791 pSirWifiScanResult->ts) )
3792 {
3793 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3794 goto fail;
3795 }
3796 if (nla_put(skb,
3797 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3798 sizeof(pSirWifiScanResult->ssid),
3799 pSirWifiScanResult->ssid) )
3800 {
3801 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3802 goto fail;
3803 }
3804 if (nla_put(skb,
3805 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3806 sizeof(pSirWifiScanResult->bssid),
3807 pSirWifiScanResult->bssid) )
3808 {
3809 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3810 goto fail;
3811 }
3812 if (nla_put_u32(skb,
3813 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3814 pSirWifiScanResult->channel) )
3815 {
3816 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3817 goto fail;
3818 }
3819 if (nla_put_s32(skb,
3820 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3821 pSirWifiScanResult->rssi) )
3822 {
3823 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3824 goto fail;
3825 }
3826 if (nla_put_u32(skb,
3827 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3828 pSirWifiScanResult->rtt) )
3829 {
3830 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3831 goto fail;
3832 }
3833 if (nla_put_u32(skb,
3834 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3835 pSirWifiScanResult->rtt_sd))
3836 {
3837 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3838 goto fail;
3839 }
3840 if (nla_put_u32(skb,
3841 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3842 pSirWifiScanResult->beaconPeriod))
3843 {
3844 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3845 goto fail;
3846 }
3847 if (nla_put_u32(skb,
3848 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3849 pSirWifiScanResult->capability))
3850 {
3851 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3852 goto fail;
3853 }
3854 if (nla_put_u32(skb,
3855 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3856 ieLength))
3857 {
3858 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3859 goto fail;
3860 }
3861
3862 if (ieLength)
3863 if (nla_put(skb,
3864 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3865 ieLength, ie)) {
3866 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3867 goto fail;
3868 }
3869
3870 nla_nest_end(skb, ap);
3871 }
3872 nla_nest_end(skb, aps);
3873 nla_nest_end(skb, nla_result);
3874 }
3875
3876 nla_nest_end(skb, nla_results);
3877
3878 cfg80211_vendor_cmd_reply(skb);
3879
3880 } while (totalResults > 0);
3881 }
3882
3883 if (!pData->moreData) {
3884 spin_lock(&hdd_context_lock);
3885 context->response_status = 0;
3886 complete(&context->response_event);
3887 spin_unlock(&hdd_context_lock);
3888 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303889
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303890 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303891 return;
3892fail:
3893 kfree_skb(skb);
3894 return;
3895}
3896
3897static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3898 void *pMsg)
3899{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303900 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303901 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3902 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303903 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303904
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303905 ENTER();
3906
3907 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303908 hddLog(LOGE,
3909 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303910 return;
3911 }
3912 if (!pMsg)
3913 {
3914 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303915 return;
3916 }
3917
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303918 if (pData->bss_found)
3919 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3920 else
3921 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3922
Dino Mycle6fb96c12014-06-10 11:52:40 +05303923 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303924#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3925 NULL,
3926#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303927 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303928 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303929
3930 if (!skb) {
3931 hddLog(VOS_TRACE_LEVEL_ERROR,
3932 FL("cfg80211_vendor_event_alloc failed"));
3933 return;
3934 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303935
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303936 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3937 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3938 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3939 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3940
3941 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303942 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3943 "Ssid (%s) "
3944 "Bssid (" MAC_ADDRESS_STR ") "
3945 "Channel (%u) "
3946 "Rssi (%d) "
3947 "RTT (%u) "
3948 "RTT_SD (%u) ",
3949 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303950 pData->bssHotlist[i].ts,
3951 pData->bssHotlist[i].ssid,
3952 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3953 pData->bssHotlist[i].channel,
3954 pData->bssHotlist[i].rssi,
3955 pData->bssHotlist[i].rtt,
3956 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303957 }
3958
3959 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3960 pData->requestId) ||
3961 nla_put_u32(skb,
3962 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303963 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303964 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3965 goto fail;
3966 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303967 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303968 struct nlattr *aps;
3969
3970 aps = nla_nest_start(skb,
3971 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3972 if (!aps)
3973 goto fail;
3974
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303975 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303976 struct nlattr *ap;
3977
3978 ap = nla_nest_start(skb, i + 1);
3979 if (!ap)
3980 goto fail;
3981
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303982 if (hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303983 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303984 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303985 nla_put(skb,
3986 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303987 sizeof(pData->bssHotlist[i].ssid),
3988 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303989 nla_put(skb,
3990 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303991 sizeof(pData->bssHotlist[i].bssid),
3992 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303993 nla_put_u32(skb,
3994 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303995 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303996 nla_put_s32(skb,
3997 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303998 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303999 nla_put_u32(skb,
4000 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304001 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304002 nla_put_u32(skb,
4003 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304004 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304005 goto fail;
4006
4007 nla_nest_end(skb, ap);
4008 }
4009 nla_nest_end(skb, aps);
4010
4011 if (nla_put_u8(skb,
4012 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
4013 pData->moreData))
4014 goto fail;
4015 }
4016
4017 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304018 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304019 return;
4020
4021fail:
4022 kfree_skb(skb);
4023 return;
4024
4025}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304026
4027static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
4028 void *pMsg)
4029{
4030 struct sk_buff *skb;
4031 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4032 tpSirWifiFullScanResultEvent pData =
4033 (tpSirWifiFullScanResultEvent) (pMsg);
4034
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304035 ENTER();
4036
4037 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304038 hddLog(LOGE,
4039 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304040 return;
4041 }
4042 if (!pMsg)
4043 {
4044 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304045 return;
4046 }
4047
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304048 /*
4049 * If the full scan result including IE data exceeds NL 4K size
4050 * limitation, drop that beacon/probe rsp frame.
4051 */
4052 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
4053 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
4054 return;
4055 }
4056
Dino Mycle6fb96c12014-06-10 11:52:40 +05304057 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304058#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4059 NULL,
4060#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304061 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4062 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
4063 GFP_KERNEL);
4064
4065 if (!skb) {
4066 hddLog(VOS_TRACE_LEVEL_ERROR,
4067 FL("cfg80211_vendor_event_alloc failed"));
4068 return;
4069 }
4070
Dino Mycle6fb96c12014-06-10 11:52:40 +05304071 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
4072 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
4073 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
4074 "Ssid (%s)"
4075 "Bssid (" MAC_ADDRESS_STR ")"
4076 "Channel (%u)"
4077 "Rssi (%d)"
4078 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304079 "RTT_SD (%u)"
4080 "Bcn Period %d"
4081 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05304082 pData->ap.ts,
4083 pData->ap.ssid,
4084 MAC_ADDR_ARRAY(pData->ap.bssid),
4085 pData->ap.channel,
4086 pData->ap.rssi,
4087 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304088 pData->ap.rtt_sd,
4089 pData->ap.beaconPeriod,
4090 pData->ap.capability);
4091
Dino Mycle6fb96c12014-06-10 11:52:40 +05304092 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
4093 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4094 pData->requestId) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304095 hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304096 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
4097 pData->ap.ts) ||
4098 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
4099 sizeof(pData->ap.ssid),
4100 pData->ap.ssid) ||
4101 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
4102 WNI_CFG_BSSID_LEN,
4103 pData->ap.bssid) ||
4104 nla_put_u32(skb,
4105 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
4106 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05304107 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304108 pData->ap.rssi) ||
4109 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
4110 pData->ap.rtt) ||
4111 nla_put_u32(skb,
4112 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
4113 pData->ap.rtt_sd) ||
4114 nla_put_u16(skb,
4115 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
4116 pData->ap.beaconPeriod) ||
4117 nla_put_u16(skb,
4118 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
4119 pData->ap.capability) ||
4120 nla_put_u32(skb,
4121 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304122 pData->ieLength) ||
4123 nla_put_u8(skb,
4124 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
4125 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304126 {
4127 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4128 goto nla_put_failure;
4129 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304130
4131 if (pData->ieLength) {
4132 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
4133 pData->ieLength,
4134 pData->ie))
4135 {
4136 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4137 goto nla_put_failure;
4138 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304139 }
4140
4141 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304142 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304143 return;
4144
4145nla_put_failure:
4146 kfree_skb(skb);
4147 return;
4148}
4149
4150static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
4151 void *pMsg)
4152{
4153 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4154 struct sk_buff *skb = NULL;
4155 tpSirEXTScanResultsAvailableIndParams pData =
4156 (tpSirEXTScanResultsAvailableIndParams) pMsg;
4157
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304158 ENTER();
4159
4160 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304161 hddLog(LOGE,
4162 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304163 return;
4164 }
4165 if (!pMsg)
4166 {
4167 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304168 return;
4169 }
4170
4171 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304172#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4173 NULL,
4174#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304175 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4176 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
4177 GFP_KERNEL);
4178
4179 if (!skb) {
4180 hddLog(VOS_TRACE_LEVEL_ERROR,
4181 FL("cfg80211_vendor_event_alloc failed"));
4182 return;
4183 }
4184
Dino Mycle6fb96c12014-06-10 11:52:40 +05304185 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
4186 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
4187 pData->numResultsAvailable);
4188 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4189 pData->requestId) ||
4190 nla_put_u32(skb,
4191 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
4192 pData->numResultsAvailable)) {
4193 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4194 goto nla_put_failure;
4195 }
4196
4197 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304198 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304199 return;
4200
4201nla_put_failure:
4202 kfree_skb(skb);
4203 return;
4204}
4205
4206static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
4207{
4208 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4209 struct sk_buff *skb = NULL;
4210 tpSirEXTScanProgressIndParams pData =
4211 (tpSirEXTScanProgressIndParams) pMsg;
4212
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304213 ENTER();
4214
4215 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304216 hddLog(LOGE,
4217 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304218 return;
4219 }
4220 if (!pMsg)
4221 {
4222 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304223 return;
4224 }
4225
4226 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304227#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4228 NULL,
4229#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304230 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4231 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
4232 GFP_KERNEL);
4233
4234 if (!skb) {
4235 hddLog(VOS_TRACE_LEVEL_ERROR,
4236 FL("cfg80211_vendor_event_alloc failed"));
4237 return;
4238 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304239 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304240 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
4241 pData->extScanEventType);
4242 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
4243 pData->status);
4244
4245 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
4246 pData->extScanEventType) ||
4247 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05304248 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4249 pData->requestId) ||
4250 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304251 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
4252 pData->status)) {
4253 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4254 goto nla_put_failure;
4255 }
4256
4257 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304258 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304259 return;
4260
4261nla_put_failure:
4262 kfree_skb(skb);
4263 return;
4264}
4265
4266void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
4267 void *pMsg)
4268{
4269 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4270
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304271 ENTER();
4272
Dino Mycle6fb96c12014-06-10 11:52:40 +05304273 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304274 return;
4275 }
4276
4277 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
4278
4279
4280 switch(evType) {
4281 case SIR_HAL_EXTSCAN_START_RSP:
4282 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
4283 break;
4284
4285 case SIR_HAL_EXTSCAN_STOP_RSP:
4286 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
4287 break;
4288 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
4289 /* There is no need to send this response to upper layer
4290 Just log the message */
4291 hddLog(VOS_TRACE_LEVEL_INFO,
4292 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
4293 break;
4294 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
4295 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
4296 break;
4297
4298 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
4299 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
4300 break;
4301
Dino Mycle6fb96c12014-06-10 11:52:40 +05304302 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304303 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304304 break;
4305 case SIR_HAL_EXTSCAN_PROGRESS_IND:
4306 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
4307 break;
4308 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
4309 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
4310 break;
4311 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
4312 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
4313 break;
4314 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
4315 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
4316 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304317 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
4318 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
4319 break;
4320 default:
4321 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
4322 break;
4323 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304324 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304325}
4326
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05304327static bool wlan_hdd_is_extscan_supported(hdd_adapter_t *adapter,
4328 hdd_context_t *hdd_ctx)
4329{
4330 int status;
4331
4332 status = wlan_hdd_validate_context(hdd_ctx);
4333 if (status)
4334 return false;
4335
4336 if (!adapter) {
4337 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid adapter"));
4338 return false;
4339 }
4340
4341 if (adapter->device_mode != WLAN_HDD_INFRA_STATION) {
4342 hddLog(VOS_TRACE_LEVEL_INFO,
4343 FL("ext scans only supported on STA ifaces"));
4344 return false;
4345 }
4346
4347 if (VOS_FTM_MODE == hdd_get_conparam()) {
4348 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4349 return false;
4350 }
4351
4352 /* check the EXTScan Capability */
4353 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
4354 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4355 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED))) {
4356 hddLog(VOS_TRACE_LEVEL_ERROR,
4357 FL("EXTScan not enabled/supported by Firmware"));
4358 return false;
4359 }
4360 return true;
4361}
4362
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304363static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4364 struct wireless_dev *wdev,
4365 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304366{
Dino Myclee8843b32014-07-04 14:21:45 +05304367 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304368 struct net_device *dev = wdev->netdev;
4369 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4370 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4371 struct nlattr
4372 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4373 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304374 struct hdd_ext_scan_context *context;
4375 unsigned long rc;
4376 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304377
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304378 ENTER();
4379
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05304380 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304381 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05304382
Dino Mycle6fb96c12014-06-10 11:52:40 +05304383 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4384 data, dataLen,
4385 wlan_hdd_extscan_config_policy)) {
4386 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4387 return -EINVAL;
4388 }
4389
4390 /* Parse and fetch request Id */
4391 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4392 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4393 return -EINVAL;
4394 }
4395
Dino Myclee8843b32014-07-04 14:21:45 +05304396 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304397 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304398 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304399
Dino Myclee8843b32014-07-04 14:21:45 +05304400 reqMsg.sessionId = pAdapter->sessionId;
4401 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304402
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304403 vos_spin_lock_acquire(&hdd_context_lock);
4404 context = &pHddCtx->ext_scan_context;
4405 context->request_id = reqMsg.requestId;
4406 INIT_COMPLETION(context->response_event);
4407 vos_spin_lock_release(&hdd_context_lock);
4408
Dino Myclee8843b32014-07-04 14:21:45 +05304409 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304410 if (!HAL_STATUS_SUCCESS(status)) {
4411 hddLog(VOS_TRACE_LEVEL_ERROR,
4412 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304413 return -EINVAL;
4414 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304415
4416 rc = wait_for_completion_timeout(&context->response_event,
4417 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4418 if (!rc) {
4419 hddLog(LOGE, FL("Target response timed out"));
4420 return -ETIMEDOUT;
4421 }
4422
4423 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
4424 if (ret)
4425 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
4426
4427 return ret;
4428
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304429 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304430 return 0;
4431}
4432
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304433static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4434 struct wireless_dev *wdev,
4435 const void *data, int dataLen)
4436{
4437 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304438
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304439 vos_ssr_protect(__func__);
4440 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
4441 vos_ssr_unprotect(__func__);
4442
4443 return ret;
4444}
4445
4446static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4447 struct wireless_dev *wdev,
4448 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304449{
Dino Myclee8843b32014-07-04 14:21:45 +05304450 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304451 struct net_device *dev = wdev->netdev;
4452 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4453 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4454 struct nlattr
4455 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4456 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304457 struct hdd_ext_scan_context *context;
4458 unsigned long rc;
4459 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304460
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304461 ENTER();
4462
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05304463 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304464 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05304465
Dino Mycle6fb96c12014-06-10 11:52:40 +05304466 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4467 data, dataLen,
4468 wlan_hdd_extscan_config_policy)) {
4469 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4470 return -EINVAL;
4471 }
4472 /* Parse and fetch request Id */
4473 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4474 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4475 return -EINVAL;
4476 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304477
Dino Myclee8843b32014-07-04 14:21:45 +05304478 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304479 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4480
Dino Myclee8843b32014-07-04 14:21:45 +05304481 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304482
Dino Myclee8843b32014-07-04 14:21:45 +05304483 reqMsg.sessionId = pAdapter->sessionId;
4484 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304485
4486 /* Parse and fetch flush parameter */
4487 if (!tb
4488 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
4489 {
4490 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
4491 goto failed;
4492 }
Dino Myclee8843b32014-07-04 14:21:45 +05304493 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304494 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
4495
Dino Myclee8843b32014-07-04 14:21:45 +05304496 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304497
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304498 spin_lock(&hdd_context_lock);
4499 context = &pHddCtx->ext_scan_context;
4500 context->request_id = reqMsg.requestId;
4501 context->ignore_cached_results = false;
4502 INIT_COMPLETION(context->response_event);
4503 spin_unlock(&hdd_context_lock);
4504
Dino Myclee8843b32014-07-04 14:21:45 +05304505 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304506 if (!HAL_STATUS_SUCCESS(status)) {
4507 hddLog(VOS_TRACE_LEVEL_ERROR,
4508 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304509 return -EINVAL;
4510 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304511
4512 rc = wait_for_completion_timeout(&context->response_event,
4513 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4514 if (!rc) {
4515 hddLog(LOGE, FL("Target response timed out"));
4516 retval = -ETIMEDOUT;
4517 spin_lock(&hdd_context_lock);
4518 context->ignore_cached_results = true;
4519 spin_unlock(&hdd_context_lock);
4520 } else {
4521 spin_lock(&hdd_context_lock);
4522 retval = context->response_status;
4523 spin_unlock(&hdd_context_lock);
4524 }
4525
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304526 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304527 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304528
4529failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05304530 return -EINVAL;
4531}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304532static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4533 struct wireless_dev *wdev,
4534 const void *data, int dataLen)
4535{
4536 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304537
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304538 vos_ssr_protect(__func__);
4539 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
4540 vos_ssr_unprotect(__func__);
4541
4542 return ret;
4543}
4544
4545static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304546 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05304547 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304548{
4549 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
4550 struct net_device *dev = wdev->netdev;
4551 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4552 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4553 struct nlattr
4554 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4555 struct nlattr
4556 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4557 struct nlattr *apTh;
4558 eHalStatus status;
4559 tANI_U8 i = 0;
4560 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304561 struct hdd_ext_scan_context *context;
4562 tANI_U32 request_id;
4563 unsigned long rc;
4564 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304565
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304566 ENTER();
4567
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05304568 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304569 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05304570
Dino Mycle6fb96c12014-06-10 11:52:40 +05304571 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4572 data, dataLen,
4573 wlan_hdd_extscan_config_policy)) {
4574 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4575 return -EINVAL;
4576 }
4577
4578 /* Parse and fetch request Id */
4579 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4580 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4581 return -EINVAL;
4582 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304583 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4584 vos_mem_malloc(sizeof(*pReqMsg));
4585 if (!pReqMsg) {
4586 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4587 return -ENOMEM;
4588 }
4589
Dino Myclee8843b32014-07-04 14:21:45 +05304590
Dino Mycle6fb96c12014-06-10 11:52:40 +05304591 pReqMsg->requestId = nla_get_u32(
4592 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4593 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4594
4595 /* Parse and fetch number of APs */
4596 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4597 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4598 goto fail;
4599 }
4600
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304601 /* Parse and fetch lost ap sample size */
4602 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4603 hddLog(LOGE, FL("attr lost ap sample size failed"));
4604 goto fail;
4605 }
4606
4607 pReqMsg->lostBssidSampleSize = nla_get_u32(
4608 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4609 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4610
Dino Mycle6fb96c12014-06-10 11:52:40 +05304611 pReqMsg->sessionId = pAdapter->sessionId;
4612 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4613
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304614 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304615 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304616 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4617 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4618 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4619 goto fail;
4620 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304621 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304622
4623 nla_for_each_nested(apTh,
4624 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304625 if (i == pReqMsg->numBssid) {
4626 hddLog(LOGW, FL("Ignoring excess AP"));
4627 break;
4628 }
4629
Dino Mycle6fb96c12014-06-10 11:52:40 +05304630 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4631 nla_data(apTh), nla_len(apTh),
4632 NULL)) {
4633 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4634 goto fail;
4635 }
4636
4637 /* Parse and fetch MAC address */
4638 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4639 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4640 goto fail;
4641 }
4642 memcpy(pReqMsg->ap[i].bssid, nla_data(
4643 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4644 sizeof(tSirMacAddr));
4645 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4646
4647 /* Parse and fetch low RSSI */
4648 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4649 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4650 goto fail;
4651 }
4652 pReqMsg->ap[i].low = nla_get_s32(
4653 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4654 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4655
4656 /* Parse and fetch high RSSI */
4657 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4658 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4659 goto fail;
4660 }
4661 pReqMsg->ap[i].high = nla_get_s32(
4662 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4663 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4664 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304665 i++;
4666 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304667
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304668 if (i < pReqMsg->numBssid) {
4669 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4670 i, pReqMsg->numBssid);
4671 pReqMsg->numBssid = i;
4672 }
4673
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304674 context = &pHddCtx->ext_scan_context;
4675 spin_lock(&hdd_context_lock);
4676 INIT_COMPLETION(context->response_event);
4677 context->request_id = request_id = pReqMsg->requestId;
4678 spin_unlock(&hdd_context_lock);
4679
Dino Mycle6fb96c12014-06-10 11:52:40 +05304680 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4681 if (!HAL_STATUS_SUCCESS(status)) {
4682 hddLog(VOS_TRACE_LEVEL_ERROR,
4683 FL("sme_SetBssHotlist failed(err=%d)"), status);
4684 vos_mem_free(pReqMsg);
4685 return -EINVAL;
4686 }
4687
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304688 /* request was sent -- wait for the response */
4689 rc = wait_for_completion_timeout(&context->response_event,
4690 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4691
4692 if (!rc) {
4693 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4694 retval = -ETIMEDOUT;
4695 } else {
4696 spin_lock(&hdd_context_lock);
4697 if (context->request_id == request_id)
4698 retval = context->response_status;
4699 else
4700 retval = -EINVAL;
4701 spin_unlock(&hdd_context_lock);
4702 }
4703
Dino Myclee8843b32014-07-04 14:21:45 +05304704 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304705 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304706 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304707
4708fail:
4709 vos_mem_free(pReqMsg);
4710 return -EINVAL;
4711}
4712
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304713static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4714 struct wireless_dev *wdev,
4715 const void *data, int dataLen)
4716{
4717 int ret = 0;
4718
4719 vos_ssr_protect(__func__);
4720 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4721 dataLen);
4722 vos_ssr_unprotect(__func__);
4723
4724 return ret;
4725}
4726
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304727static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304728 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304729 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304730{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304731 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4732 struct net_device *dev = wdev->netdev;
4733 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4734 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4735 uint8_t num_channels = 0;
4736 uint8_t num_chan_new = 0;
4737 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304738 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304739 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304740 tWifiBand wifiBand;
4741 eHalStatus status;
4742 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304743 tANI_U8 i,j,k;
4744 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304745
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304746 ENTER();
4747
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05304748 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304749 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05304750
Dino Mycle6fb96c12014-06-10 11:52:40 +05304751 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4752 data, dataLen,
4753 wlan_hdd_extscan_config_policy)) {
4754 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4755 return -EINVAL;
4756 }
4757
4758 /* Parse and fetch request Id */
4759 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4760 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4761 return -EINVAL;
4762 }
4763 requestId = nla_get_u32(
4764 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4765 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4766
4767 /* Parse and fetch wifi band */
4768 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4769 {
4770 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4771 return -EINVAL;
4772 }
4773 wifiBand = nla_get_u32(
4774 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4775 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4776
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304777 /* Parse and fetch max channels */
4778 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4779 {
4780 hddLog(LOGE, FL("attr max channels failed"));
4781 return -EINVAL;
4782 }
4783 maxChannels = nla_get_u32(
4784 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4785 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4786
Dino Mycle6fb96c12014-06-10 11:52:40 +05304787 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304788 wifiBand, chan_list,
4789 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304790 if (eHAL_STATUS_SUCCESS != status) {
4791 hddLog(VOS_TRACE_LEVEL_ERROR,
4792 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4793 return -EINVAL;
4794 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304795
Agrawal Ashish16abf782016-08-18 22:42:59 +05304796 num_channels = VOS_MIN(num_channels, maxChannels);
4797 num_chan_new = num_channels;
4798 /* remove the indoor only channels if iface is SAP */
4799 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4800 {
4801 num_chan_new = 0;
4802 for (i = 0; i < num_channels; i++)
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304803 for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) {
Agrawal Ashish16abf782016-08-18 22:42:59 +05304804 if (wiphy->bands[j] == NULL)
4805 continue;
4806 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4807 if ((chan_list[i] ==
4808 wiphy->bands[j]->channels[k].center_freq) &&
4809 (!(wiphy->bands[j]->channels[k].flags &
4810 IEEE80211_CHAN_INDOOR_ONLY))) {
4811 chan_list[num_chan_new] = chan_list[i];
4812 num_chan_new++;
4813 }
4814 }
4815 }
4816 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304817
Agrawal Ashish16abf782016-08-18 22:42:59 +05304818 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4819 for (i = 0; i < num_chan_new; i++)
4820 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4821 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304822
4823 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304824 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304825 NLMSG_HDRLEN);
4826
4827 if (!replySkb) {
4828 hddLog(VOS_TRACE_LEVEL_ERROR,
4829 FL("valid channels: buffer alloc fail"));
4830 return -EINVAL;
4831 }
4832 if (nla_put_u32(replySkb,
4833 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304834 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304835 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304836 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304837
4838 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4839 kfree_skb(replySkb);
4840 return -EINVAL;
4841 }
4842
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304843 ret = cfg80211_vendor_cmd_reply(replySkb);
4844
4845 EXIT();
4846 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304847}
4848
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304849static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4850 struct wireless_dev *wdev,
4851 const void *data, int dataLen)
4852{
4853 int ret = 0;
4854
4855 vos_ssr_protect(__func__);
4856 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4857 dataLen);
4858 vos_ssr_unprotect(__func__);
4859
4860 return ret;
4861}
4862
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304863static int hdd_extscan_start_fill_bucket_channel_spec(
4864 hdd_context_t *pHddCtx,
4865 tpSirEXTScanStartReqParams pReqMsg,
4866 struct nlattr **tb)
4867{
4868 struct nlattr *bucket[
4869 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4870 struct nlattr *channel[
4871 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4872 struct nlattr *buckets;
4873 struct nlattr *channels;
4874 int rem1, rem2;
4875 eHalStatus status;
4876 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304877 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304878 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4879 tANI_U32 passive_max_chn_time, active_max_chn_time;
4880
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304881 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304882 bktIndex = 0;
4883
4884 nla_for_each_nested(buckets,
4885 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304886 if (bktIndex >= expected_buckets) {
4887 hddLog(LOGW, FL("ignoring excess buckets"));
4888 break;
4889 }
4890
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304891 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304892 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4893 nla_data(buckets), nla_len(buckets),
4894 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304895 hddLog(LOGE, FL("nla_parse failed"));
4896 return -EINVAL;
4897 }
4898
4899 /* Parse and fetch bucket spec */
4900 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4901 hddLog(LOGE, FL("attr bucket index failed"));
4902 return -EINVAL;
4903 }
4904 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4905 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4906 hddLog(LOG1, FL("Bucket spec Index %d"),
4907 pReqMsg->buckets[bktIndex].bucket);
4908
4909 /* Parse and fetch wifi band */
4910 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4911 hddLog(LOGE, FL("attr wifi band failed"));
4912 return -EINVAL;
4913 }
4914 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4915 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4916 hddLog(LOG1, FL("Wifi band %d"),
4917 pReqMsg->buckets[bktIndex].band);
4918
4919 /* Parse and fetch period */
4920 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4921 hddLog(LOGE, FL("attr period failed"));
4922 return -EINVAL;
4923 }
4924 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4925 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4926 hddLog(LOG1, FL("period %d"),
4927 pReqMsg->buckets[bktIndex].period);
4928
4929 /* Parse and fetch report events */
4930 if (!bucket[
4931 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4932 hddLog(LOGE, FL("attr report events failed"));
4933 return -EINVAL;
4934 }
4935 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4936 bucket[
4937 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4938 hddLog(LOG1, FL("report events %d"),
4939 pReqMsg->buckets[bktIndex].reportEvents);
4940
4941 /* Parse and fetch max period */
4942 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4943 hddLog(LOGE, FL("attr max period failed"));
4944 return -EINVAL;
4945 }
4946 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4947 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4948 hddLog(LOG1, FL("max period %u"),
4949 pReqMsg->buckets[bktIndex].max_period);
4950
4951 /* Parse and fetch exponent */
4952 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4953 hddLog(LOGE, FL("attr exponent failed"));
4954 return -EINVAL;
4955 }
4956 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4957 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4958 hddLog(LOG1, FL("exponent %u"),
4959 pReqMsg->buckets[bktIndex].exponent);
4960
4961 /* Parse and fetch step count */
4962 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4963 hddLog(LOGE, FL("attr step count failed"));
4964 return -EINVAL;
4965 }
4966 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4967 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4968 hddLog(LOG1, FL("Step count %u"),
4969 pReqMsg->buckets[bktIndex].step_count);
4970
4971 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4972 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4973
4974 /* Framework shall pass the channel list if the input WiFi band is
4975 * WIFI_BAND_UNSPECIFIED.
4976 * If the input WiFi band is specified (any value other than
4977 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4978 */
4979 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4980 numChannels = 0;
4981 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4982 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4983 pReqMsg->buckets[bktIndex].band,
4984 chanList, &numChannels);
4985 if (!HAL_STATUS_SUCCESS(status)) {
4986 hddLog(LOGE,
4987 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4988 status);
4989 return -EINVAL;
4990 }
4991
4992 pReqMsg->buckets[bktIndex].numChannels =
4993 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4994 hddLog(LOG1, FL("Num channels %d"),
4995 pReqMsg->buckets[bktIndex].numChannels);
4996
4997 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4998 j++) {
4999 pReqMsg->buckets[bktIndex].channels[j].channel =
5000 chanList[j];
5001 pReqMsg->buckets[bktIndex].channels[j].
5002 chnlClass = 0;
5003 if (CSR_IS_CHANNEL_DFS(
5004 vos_freq_to_chan(chanList[j]))) {
5005 pReqMsg->buckets[bktIndex].channels[j].
5006 passive = 1;
5007 pReqMsg->buckets[bktIndex].channels[j].
5008 dwellTimeMs = passive_max_chn_time;
5009 } else {
5010 pReqMsg->buckets[bktIndex].channels[j].
5011 passive = 0;
5012 pReqMsg->buckets[bktIndex].channels[j].
5013 dwellTimeMs = active_max_chn_time;
5014 }
5015
5016 hddLog(LOG1,
5017 "Channel %u Passive %u Dwell time %u ms",
5018 pReqMsg->buckets[bktIndex].channels[j].channel,
5019 pReqMsg->buckets[bktIndex].channels[j].passive,
5020 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5021 }
5022
5023 bktIndex++;
5024 continue;
5025 }
5026
5027 /* Parse and fetch number of channels */
5028 if (!bucket[
5029 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
5030 hddLog(LOGE, FL("attr num channels failed"));
5031 return -EINVAL;
5032 }
5033
5034 pReqMsg->buckets[bktIndex].numChannels =
5035 nla_get_u32(bucket[
5036 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
5037 hddLog(LOG1, FL("num channels %d"),
5038 pReqMsg->buckets[bktIndex].numChannels);
5039
5040 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
5041 hddLog(LOGE, FL("attr channel spec failed"));
5042 return -EINVAL;
5043 }
5044
5045 j = 0;
5046 nla_for_each_nested(channels,
5047 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
5048 if (nla_parse(channel,
5049 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5050 nla_data(channels), nla_len(channels),
5051 wlan_hdd_extscan_config_policy)) {
5052 hddLog(LOGE, FL("nla_parse failed"));
5053 return -EINVAL;
5054 }
5055
5056 /* Parse and fetch channel */
5057 if (!channel[
5058 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
5059 hddLog(LOGE, FL("attr channel failed"));
5060 return -EINVAL;
5061 }
5062 pReqMsg->buckets[bktIndex].channels[j].channel =
5063 nla_get_u32(channel[
5064 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
5065 hddLog(LOG1, FL("channel %u"),
5066 pReqMsg->buckets[bktIndex].channels[j].channel);
5067
5068 /* Parse and fetch dwell time */
5069 if (!channel[
5070 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
5071 hddLog(LOGE, FL("attr dwelltime failed"));
5072 return -EINVAL;
5073 }
5074 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
5075 nla_get_u32(channel[
5076 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
5077
5078 hddLog(LOG1, FL("Dwell time (%u ms)"),
5079 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5080
5081
5082 /* Parse and fetch channel spec passive */
5083 if (!channel[
5084 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
5085 hddLog(LOGE,
5086 FL("attr channel spec passive failed"));
5087 return -EINVAL;
5088 }
5089 pReqMsg->buckets[bktIndex].channels[j].passive =
5090 nla_get_u8(channel[
5091 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
5092 hddLog(LOG1, FL("Chnl spec passive %u"),
5093 pReqMsg->buckets[bktIndex].channels[j].passive);
5094
5095 j++;
5096 }
5097
Dundi Raviteja18d0c062018-11-13 19:56:45 +05305098 if (j != pReqMsg->buckets[bktIndex].numChannels) {
5099 hddLog(LOG1, FL("Input parameters didn't match"));
5100 return -EINVAL;
5101 }
5102
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305103 bktIndex++;
5104 }
5105
5106 return 0;
5107}
5108
5109
5110/*
5111 * define short names for the global vendor params
5112 * used by wlan_hdd_cfg80211_extscan_start()
5113 */
5114#define PARAM_MAX \
5115QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
5116#define PARAM_REQUEST_ID \
5117QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
5118#define PARAM_BASE_PERIOD \
5119QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
5120#define PARAM_MAX_AP_PER_SCAN \
5121QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
5122#define PARAM_RPT_THRHLD_PERCENT \
5123QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
5124#define PARAM_RPT_THRHLD_NUM_SCANS \
5125QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
5126#define PARAM_NUM_BUCKETS \
5127QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
5128
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305129static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305130 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305131 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305132{
Dino Myclee8843b32014-07-04 14:21:45 +05305133 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305134 struct net_device *dev = wdev->netdev;
5135 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5136 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5137 struct nlattr *tb[PARAM_MAX + 1];
5138 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305139 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305140 tANI_U32 request_id;
5141 struct hdd_ext_scan_context *context;
5142 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305143
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305144 ENTER();
5145
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05305146 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305147 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05305148
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305149 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305150 data, dataLen,
5151 wlan_hdd_extscan_config_policy)) {
5152 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5153 return -EINVAL;
5154 }
5155
5156 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305157 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305158 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5159 return -EINVAL;
5160 }
5161
Dino Myclee8843b32014-07-04 14:21:45 +05305162 pReqMsg = (tpSirEXTScanStartReqParams)
5163 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305164 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305165 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5166 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305167 }
5168
5169 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305170 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305171 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5172
5173 pReqMsg->sessionId = pAdapter->sessionId;
5174 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5175
5176 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305177 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305178 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5179 goto fail;
5180 }
5181 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305182 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305183 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5184 pReqMsg->basePeriod);
5185
5186 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305187 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305188 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5189 goto fail;
5190 }
5191 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305192 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305193 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5194 pReqMsg->maxAPperScan);
5195
5196 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305197 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305198 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5199 goto fail;
5200 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305201 pReqMsg->reportThresholdPercent = nla_get_u8(
5202 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305203 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305204 pReqMsg->reportThresholdPercent);
5205
5206 /* Parse and fetch report threshold num scans */
5207 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5208 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5209 goto fail;
5210 }
5211 pReqMsg->reportThresholdNumScans = nla_get_u8(
5212 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5213 hddLog(LOG1, FL("Report Threshold num scans %d"),
5214 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305215
5216 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305217 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305218 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5219 goto fail;
5220 }
5221 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305222 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305223 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5224 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5225 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5226 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5227 }
5228 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5229 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305230
Dino Mycle6fb96c12014-06-10 11:52:40 +05305231 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5232 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5233 goto fail;
5234 }
5235
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305236 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305237
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305238 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5239 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305240
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305241 context = &pHddCtx->ext_scan_context;
5242 spin_lock(&hdd_context_lock);
5243 INIT_COMPLETION(context->response_event);
5244 context->request_id = request_id = pReqMsg->requestId;
5245 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305246
Dino Mycle6fb96c12014-06-10 11:52:40 +05305247 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5248 if (!HAL_STATUS_SUCCESS(status)) {
5249 hddLog(VOS_TRACE_LEVEL_ERROR,
5250 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305251 goto fail;
5252 }
5253
Srinivas Dasari91727c12016-03-23 17:59:06 +05305254 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5255
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305256 /* request was sent -- wait for the response */
5257 rc = wait_for_completion_timeout(&context->response_event,
5258 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5259
5260 if (!rc) {
5261 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5262 retval = -ETIMEDOUT;
5263 } else {
5264 spin_lock(&hdd_context_lock);
5265 if (context->request_id == request_id)
5266 retval = context->response_status;
5267 else
5268 retval = -EINVAL;
5269 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305270 }
5271
Dino Myclee8843b32014-07-04 14:21:45 +05305272 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305273 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305274 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305275
5276fail:
5277 vos_mem_free(pReqMsg);
5278 return -EINVAL;
5279}
5280
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305281/*
5282 * done with short names for the global vendor params
5283 * used by wlan_hdd_cfg80211_extscan_start()
5284 */
5285#undef PARAM_MAX
5286#undef PARAM_REQUEST_ID
5287#undef PARAM_BASE_PERIOD
5288#undef PARAMS_MAX_AP_PER_SCAN
5289#undef PARAMS_RPT_THRHLD_PERCENT
5290#undef PARAMS_RPT_THRHLD_NUM_SCANS
5291#undef PARAMS_NUM_BUCKETS
5292
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305293static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5294 struct wireless_dev *wdev,
5295 const void *data, int dataLen)
5296{
5297 int ret = 0;
5298
5299 vos_ssr_protect(__func__);
5300 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5301 vos_ssr_unprotect(__func__);
5302
5303 return ret;
5304}
5305
5306static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305307 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305308 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305309{
Dino Myclee8843b32014-07-04 14:21:45 +05305310 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305311 struct net_device *dev = wdev->netdev;
5312 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5313 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5314 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5315 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305316 int retval;
5317 unsigned long rc;
5318 struct hdd_ext_scan_context *context;
5319 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305320
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305321 ENTER();
5322
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05305323 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305324 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05305325
Dino Mycle6fb96c12014-06-10 11:52:40 +05305326 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5327 data, dataLen,
5328 wlan_hdd_extscan_config_policy)) {
5329 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5330 return -EINVAL;
5331 }
5332
5333 /* Parse and fetch request Id */
5334 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5335 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5336 return -EINVAL;
5337 }
5338
Dino Myclee8843b32014-07-04 14:21:45 +05305339 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305340 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305341 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305342
Dino Myclee8843b32014-07-04 14:21:45 +05305343 reqMsg.sessionId = pAdapter->sessionId;
5344 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305345
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305346 context = &pHddCtx->ext_scan_context;
5347 spin_lock(&hdd_context_lock);
5348 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305349 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305350 spin_unlock(&hdd_context_lock);
5351
Dino Myclee8843b32014-07-04 14:21:45 +05305352 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305353 if (!HAL_STATUS_SUCCESS(status)) {
5354 hddLog(VOS_TRACE_LEVEL_ERROR,
5355 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305356 return -EINVAL;
5357 }
5358
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305359 /* request was sent -- wait for the response */
5360 rc = wait_for_completion_timeout(&context->response_event,
5361 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5362
5363 if (!rc) {
5364 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5365 retval = -ETIMEDOUT;
5366 } else {
5367 spin_lock(&hdd_context_lock);
5368 if (context->request_id == request_id)
5369 retval = context->response_status;
5370 else
5371 retval = -EINVAL;
5372 spin_unlock(&hdd_context_lock);
5373 }
5374
5375 return retval;
5376
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305377 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305378 return 0;
5379}
5380
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305381static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5382 struct wireless_dev *wdev,
5383 const void *data, int dataLen)
5384{
5385 int ret = 0;
5386
5387 vos_ssr_protect(__func__);
5388 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5389 vos_ssr_unprotect(__func__);
5390
5391 return ret;
5392}
5393
5394static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305395 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305396 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305397{
Dino Myclee8843b32014-07-04 14:21:45 +05305398 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305399 struct net_device *dev = wdev->netdev;
5400 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5401 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5402 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5403 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305404 struct hdd_ext_scan_context *context;
5405 tANI_U32 request_id;
5406 unsigned long rc;
5407 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305408
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305409 ENTER();
5410
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05305411 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305412 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05305413
Dino Mycle6fb96c12014-06-10 11:52:40 +05305414 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5415 data, dataLen,
5416 wlan_hdd_extscan_config_policy)) {
5417 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5418 return -EINVAL;
5419 }
5420
5421 /* Parse and fetch request Id */
5422 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5423 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5424 return -EINVAL;
5425 }
5426
Dino Myclee8843b32014-07-04 14:21:45 +05305427 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305428 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305429 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305430
Dino Myclee8843b32014-07-04 14:21:45 +05305431 reqMsg.sessionId = pAdapter->sessionId;
5432 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305433
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305434 context = &pHddCtx->ext_scan_context;
5435 spin_lock(&hdd_context_lock);
5436 INIT_COMPLETION(context->response_event);
5437 context->request_id = request_id = reqMsg.requestId;
5438 spin_unlock(&hdd_context_lock);
5439
Dino Myclee8843b32014-07-04 14:21:45 +05305440 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305441 if (!HAL_STATUS_SUCCESS(status)) {
5442 hddLog(VOS_TRACE_LEVEL_ERROR,
5443 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305444 return -EINVAL;
5445 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305446
5447 /* request was sent -- wait for the response */
5448 rc = wait_for_completion_timeout(&context->response_event,
5449 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5450 if (!rc) {
5451 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5452 retval = -ETIMEDOUT;
5453 } else {
5454 spin_lock(&hdd_context_lock);
5455 if (context->request_id == request_id)
5456 retval = context->response_status;
5457 else
5458 retval = -EINVAL;
5459 spin_unlock(&hdd_context_lock);
5460 }
5461
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305462 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305463 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305464}
5465
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305466static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5467 struct wireless_dev *wdev,
5468 const void *data, int dataLen)
5469{
5470 int ret = 0;
5471
5472 vos_ssr_protect(__func__);
5473 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5474 vos_ssr_unprotect(__func__);
5475
5476 return ret;
5477}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305478#endif /* WLAN_FEATURE_EXTSCAN */
5479
Atul Mittal115287b2014-07-08 13:26:33 +05305480/*EXT TDLS*/
5481static const struct nla_policy
5482wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5483{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305484 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5485 .type = NLA_UNSPEC,
5486 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305487 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5488 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5489 {.type = NLA_S32 },
5490 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5491 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5492
5493};
5494
5495static const struct nla_policy
5496wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5497{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305498 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5499 .type = NLA_UNSPEC,
5500 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305501
5502};
5503
5504static const struct nla_policy
5505wlan_hdd_tdls_config_state_change_policy[
5506 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5507{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305508 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5509 .type = NLA_UNSPEC,
5510 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305511 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5512 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305513 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5514 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5515 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305516
5517};
5518
5519static const struct nla_policy
5520wlan_hdd_tdls_config_get_status_policy[
5521 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5522{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305523 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5524 .type = NLA_UNSPEC,
5525 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305526 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5527 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305528 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5529 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5530 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305531
5532};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305533
5534static const struct nla_policy
5535wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5536{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305537 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5538 .type = NLA_UNSPEC,
5539 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305540};
5541
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305542static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305543 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305544 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305545 int data_len)
5546{
5547
5548 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Sourav Mohapatraaf2cc672018-10-30 17:43:29 +05305549 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev);
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305550 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5551
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305552 ENTER();
5553
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305554 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305555 return -EINVAL;
5556 }
Sourav Mohapatraaf2cc672018-10-30 17:43:29 +05305557
5558 if (!adapter) {
5559 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5560 return -EINVAL;
5561 }
5562
5563 if (adapter->device_mode != WLAN_HDD_INFRA_STATION) {
5564 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN allowed only in STA"));
5565 return -ENOTSUPP;
5566 }
5567
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305568 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305569 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305570 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305571 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305572 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305573 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305574 return -ENOTSUPP;
5575 }
5576
5577 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5578 data, data_len, wlan_hdd_mac_config)) {
5579 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5580 return -EINVAL;
5581 }
5582
5583 /* Parse and fetch mac address */
5584 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5585 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5586 return -EINVAL;
5587 }
5588
5589 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5590 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5591 VOS_MAC_ADDR_LAST_3_BYTES);
5592
Siddharth Bhal76972212014-10-15 16:22:51 +05305593 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5594
5595 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305596 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5597 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305598 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5599 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5600 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5601 {
5602 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5603 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5604 VOS_MAC_ADDRESS_LEN);
5605 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305606 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305607
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305608 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5609 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305610
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305611 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305612 return 0;
5613}
5614
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305615static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5616 struct wireless_dev *wdev,
5617 const void *data,
5618 int data_len)
5619{
5620 int ret = 0;
5621
5622 vos_ssr_protect(__func__);
5623 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5624 vos_ssr_unprotect(__func__);
5625
5626 return ret;
5627}
5628
5629static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305630 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305631 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305632 int data_len)
5633{
5634 u8 peer[6] = {0};
5635 struct net_device *dev = wdev->netdev;
5636 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5637 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5638 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5639 eHalStatus ret;
5640 tANI_S32 state;
5641 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305642 tANI_S32 global_operating_class = 0;
5643 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305644 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305645 int retVal;
5646
5647 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305648
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305649 if (!pAdapter) {
5650 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5651 return -EINVAL;
5652 }
5653
Atul Mittal115287b2014-07-08 13:26:33 +05305654 ret = wlan_hdd_validate_context(pHddCtx);
5655 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305656 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305657 return -EINVAL;
5658 }
5659 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305660 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305661 return -ENOTSUPP;
5662 }
5663 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5664 data, data_len,
5665 wlan_hdd_tdls_config_get_status_policy)) {
5666 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5667 return -EINVAL;
5668 }
5669
5670 /* Parse and fetch mac address */
5671 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5672 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5673 return -EINVAL;
5674 }
5675
5676 memcpy(peer, nla_data(
5677 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5678 sizeof(peer));
5679 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5680
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305681 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305682
Atul Mittal115287b2014-07-08 13:26:33 +05305683 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305684 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305685 NLMSG_HDRLEN);
5686
5687 if (!skb) {
5688 hddLog(VOS_TRACE_LEVEL_ERROR,
5689 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5690 return -EINVAL;
5691 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305692 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 +05305693 reason,
5694 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305695 global_operating_class,
5696 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305697 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305698 if (nla_put_s32(skb,
5699 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5700 state) ||
5701 nla_put_s32(skb,
5702 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5703 reason) ||
5704 nla_put_s32(skb,
5705 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5706 global_operating_class) ||
5707 nla_put_s32(skb,
5708 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5709 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305710
5711 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5712 goto nla_put_failure;
5713 }
5714
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305715 retVal = cfg80211_vendor_cmd_reply(skb);
5716 EXIT();
5717 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305718
5719nla_put_failure:
5720 kfree_skb(skb);
5721 return -EINVAL;
5722}
5723
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305724static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5725 struct wireless_dev *wdev,
5726 const void *data,
5727 int data_len)
5728{
5729 int ret = 0;
5730
5731 vos_ssr_protect(__func__);
5732 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5733 vos_ssr_unprotect(__func__);
5734
5735 return ret;
5736}
5737
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305738static int wlan_hdd_cfg80211_exttdls_callback(
5739#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5740 const tANI_U8* mac,
5741#else
5742 tANI_U8* mac,
5743#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305744 tANI_S32 state,
5745 tANI_S32 reason,
5746 void *ctx)
5747{
5748 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305749 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305750 tANI_S32 global_operating_class = 0;
5751 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305752 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305753
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305754 ENTER();
5755
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305756 if (!pAdapter) {
5757 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5758 return -EINVAL;
5759 }
5760
5761 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305762 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305763 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305764 return -EINVAL;
5765 }
5766
5767 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305769 return -ENOTSUPP;
5770 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305771 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5772#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5773 NULL,
5774#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305775 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5776 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5777 GFP_KERNEL);
5778
5779 if (!skb) {
5780 hddLog(VOS_TRACE_LEVEL_ERROR,
5781 FL("cfg80211_vendor_event_alloc failed"));
5782 return -EINVAL;
5783 }
5784 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305785 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5786 reason,
5787 state,
5788 global_operating_class,
5789 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305790 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5791 MAC_ADDR_ARRAY(mac));
5792
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305793 if (nla_put(skb,
5794 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5795 VOS_MAC_ADDR_SIZE, mac) ||
5796 nla_put_s32(skb,
5797 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5798 state) ||
5799 nla_put_s32(skb,
5800 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5801 reason) ||
5802 nla_put_s32(skb,
5803 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5804 channel) ||
5805 nla_put_s32(skb,
5806 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5807 global_operating_class)
5808 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305809 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5810 goto nla_put_failure;
5811 }
5812
5813 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305814 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305815 return (0);
5816
5817nla_put_failure:
5818 kfree_skb(skb);
5819 return -EINVAL;
5820}
5821
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305822static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305823 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305824 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305825 int data_len)
5826{
5827 u8 peer[6] = {0};
5828 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305829 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5830 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5831 eHalStatus status;
5832 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305833 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305834 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305835
5836 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305837
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305838 if (!dev) {
5839 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5840 return -EINVAL;
5841 }
5842
5843 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5844 if (!pAdapter) {
5845 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5846 return -EINVAL;
5847 }
5848
Atul Mittal115287b2014-07-08 13:26:33 +05305849 status = wlan_hdd_validate_context(pHddCtx);
5850 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305851 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305852 return -EINVAL;
5853 }
5854 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305855 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305856 return -ENOTSUPP;
5857 }
5858 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5859 data, data_len,
5860 wlan_hdd_tdls_config_enable_policy)) {
5861 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5862 return -EINVAL;
5863 }
5864
5865 /* Parse and fetch mac address */
5866 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5867 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5868 return -EINVAL;
5869 }
5870
5871 memcpy(peer, nla_data(
5872 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5873 sizeof(peer));
5874 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5875
5876 /* Parse and fetch channel */
5877 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5878 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5879 return -EINVAL;
5880 }
5881 pReqMsg.channel = nla_get_s32(
5882 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5883 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5884
5885 /* Parse and fetch global operating class */
5886 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5888 return -EINVAL;
5889 }
5890 pReqMsg.global_operating_class = nla_get_s32(
5891 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5892 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5893 pReqMsg.global_operating_class);
5894
5895 /* Parse and fetch latency ms */
5896 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5897 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5898 return -EINVAL;
5899 }
5900 pReqMsg.max_latency_ms = nla_get_s32(
5901 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5902 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5903 pReqMsg.max_latency_ms);
5904
5905 /* Parse and fetch required bandwidth kbps */
5906 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5907 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5908 return -EINVAL;
5909 }
5910
5911 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5912 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5913 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5914 pReqMsg.min_bandwidth_kbps);
5915
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305916 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305917 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305918 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305919 wlan_hdd_cfg80211_exttdls_callback);
5920
5921 EXIT();
5922 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305923}
5924
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305925static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5926 struct wireless_dev *wdev,
5927 const void *data,
5928 int data_len)
5929{
5930 int ret = 0;
5931
5932 vos_ssr_protect(__func__);
5933 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5934 vos_ssr_unprotect(__func__);
5935
5936 return ret;
5937}
5938
5939static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305940 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305941 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305942 int data_len)
5943{
5944 u8 peer[6] = {0};
5945 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305946 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5947 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5948 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305949 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305950 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305951
5952 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305953
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305954 if (!dev) {
5955 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5956 return -EINVAL;
5957 }
5958
5959 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5960 if (!pAdapter) {
5961 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5962 return -EINVAL;
5963 }
5964
Atul Mittal115287b2014-07-08 13:26:33 +05305965 status = wlan_hdd_validate_context(pHddCtx);
5966 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305967 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305968 return -EINVAL;
5969 }
5970 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305971 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305972 return -ENOTSUPP;
5973 }
5974 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5975 data, data_len,
5976 wlan_hdd_tdls_config_disable_policy)) {
5977 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5978 return -EINVAL;
5979 }
5980 /* Parse and fetch mac address */
5981 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5982 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5983 return -EINVAL;
5984 }
5985
5986 memcpy(peer, nla_data(
5987 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5988 sizeof(peer));
5989 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5990
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305991 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5992
5993 EXIT();
5994 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305995}
5996
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305997static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5998 struct wireless_dev *wdev,
5999 const void *data,
6000 int data_len)
6001{
6002 int ret = 0;
6003
6004 vos_ssr_protect(__func__);
6005 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
6006 vos_ssr_unprotect(__func__);
6007
6008 return ret;
6009}
6010
Dasari Srinivas7875a302014-09-26 17:50:57 +05306011static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306012__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05306013 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306014 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05306015{
6016 struct net_device *dev = wdev->netdev;
6017 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6018 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6019 struct sk_buff *skb = NULL;
6020 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306021 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306022
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306023 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306024
6025 ret = wlan_hdd_validate_context(pHddCtx);
6026 if (0 != ret)
6027 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306028 return ret;
6029 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306030 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
6031 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
6032 fset |= WIFI_FEATURE_INFRA;
6033 }
6034
6035 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
6036 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
6037 fset |= WIFI_FEATURE_INFRA_5G;
6038 }
6039
6040#ifdef WLAN_FEATURE_P2P
6041 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
6042 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
6043 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
6044 fset |= WIFI_FEATURE_P2P;
6045 }
6046#endif
6047
6048 /* Soft-AP is supported currently by default */
6049 fset |= WIFI_FEATURE_SOFT_AP;
6050
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05306051 /* HOTSPOT is a supplicant feature, enable it by default */
6052 fset |= WIFI_FEATURE_HOTSPOT;
6053
Dasari Srinivas7875a302014-09-26 17:50:57 +05306054#ifdef WLAN_FEATURE_EXTSCAN
6055 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05306056 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
6057 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
6058 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306059 fset |= WIFI_FEATURE_EXTSCAN;
6060 }
6061#endif
6062
Dasari Srinivas7875a302014-09-26 17:50:57 +05306063 if (sme_IsFeatureSupportedByFW(NAN)) {
6064 hddLog(LOG1, FL("NAN is supported by firmware"));
6065 fset |= WIFI_FEATURE_NAN;
6066 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306067
6068 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05306069 if (sme_IsFeatureSupportedByFW(RTT) &&
6070 pHddCtx->cfg_ini->enable_rtt_support) {
6071 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306072 fset |= WIFI_FEATURE_D2AP_RTT;
6073 }
6074
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05306075 if (sme_IsFeatureSupportedByFW(RTT3)) {
6076 hddLog(LOG1, FL("RTT3 is supported by firmware"));
6077 fset |= WIFI_FEATURE_RTT3;
6078 }
6079
Dasari Srinivas7875a302014-09-26 17:50:57 +05306080#ifdef FEATURE_WLAN_BATCH_SCAN
6081 if (fset & WIFI_FEATURE_EXTSCAN) {
6082 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
6083 fset &= ~WIFI_FEATURE_BATCH_SCAN;
6084 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
6085 hddLog(LOG1, FL("Batch scan is supported by firmware"));
6086 fset |= WIFI_FEATURE_BATCH_SCAN;
6087 }
6088#endif
6089
6090#ifdef FEATURE_WLAN_SCAN_PNO
6091 if (pHddCtx->cfg_ini->configPNOScanSupport &&
6092 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
6093 hddLog(LOG1, FL("PNO is supported by firmware"));
6094 fset |= WIFI_FEATURE_PNO;
6095 }
6096#endif
6097
6098 /* STA+STA is supported currently by default */
6099 fset |= WIFI_FEATURE_ADDITIONAL_STA;
6100
6101#ifdef FEATURE_WLAN_TDLS
6102 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6103 sme_IsFeatureSupportedByFW(TDLS)) {
6104 hddLog(LOG1, FL("TDLS is supported by firmware"));
6105 fset |= WIFI_FEATURE_TDLS;
6106 }
6107
6108 /* TDLS_OFFCHANNEL is not supported currently by default */
6109#endif
6110
6111#ifdef WLAN_AP_STA_CONCURRENCY
6112 /* AP+STA concurrency is supported currently by default */
6113 fset |= WIFI_FEATURE_AP_STA;
6114#endif
6115
Mukul Sharma5add0532015-08-17 15:57:47 +05306116#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306117 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6118 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306119 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6120 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306121 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306122#endif
6123
Dasari Srinivas7875a302014-09-26 17:50:57 +05306124 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6125 NLMSG_HDRLEN);
6126
6127 if (!skb) {
6128 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6129 return -EINVAL;
6130 }
6131 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6132
6133 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6134 hddLog(LOGE, FL("nla put fail"));
6135 goto nla_put_failure;
6136 }
6137
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306138 ret = cfg80211_vendor_cmd_reply(skb);
6139 EXIT();
6140 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306141
6142nla_put_failure:
6143 kfree_skb(skb);
6144 return -EINVAL;
6145}
6146
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306147static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306148wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6149 struct wireless_dev *wdev,
6150 const void *data, int data_len)
6151{
6152 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306153 vos_ssr_protect(__func__);
6154 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6155 vos_ssr_unprotect(__func__);
6156
6157 return ret;
6158}
6159
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306160
6161static const struct
6162nla_policy
6163qca_wlan_vendor_wifi_logger_get_ring_data_policy
6164[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6165 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6166 = {.type = NLA_U32 },
6167};
6168
6169static int
6170 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6171 struct wireless_dev *wdev,
6172 const void *data,
6173 int data_len)
6174{
6175 int ret;
6176 VOS_STATUS status;
6177 uint32_t ring_id;
6178 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6179 struct nlattr *tb
6180 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6181
6182 ENTER();
6183
6184 ret = wlan_hdd_validate_context(hdd_ctx);
6185 if (0 != ret) {
6186 return ret;
6187 }
6188
6189 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6190 data, data_len,
6191 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6192 hddLog(LOGE, FL("Invalid attribute"));
6193 return -EINVAL;
6194 }
6195
6196 /* Parse and fetch ring id */
6197 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6198 hddLog(LOGE, FL("attr ATTR failed"));
6199 return -EINVAL;
6200 }
6201
6202 ring_id = nla_get_u32(
6203 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6204
6205 hddLog(LOG1, FL("Bug report triggered by framework"));
6206
6207 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6208 WLAN_LOG_INDICATOR_FRAMEWORK,
6209 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306210 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306211 );
6212 if (VOS_STATUS_SUCCESS != status) {
6213 hddLog(LOGE, FL("Failed to trigger bug report"));
6214
6215 return -EINVAL;
6216 }
6217
6218 return 0;
6219
6220
6221}
6222
6223
6224static int
6225 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6226 struct wireless_dev *wdev,
6227 const void *data,
6228 int data_len)
6229{
6230 int ret = 0;
6231
6232 vos_ssr_protect(__func__);
6233 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6234 wdev, data, data_len);
6235 vos_ssr_unprotect(__func__);
6236
6237 return ret;
6238
6239}
6240
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306241#define MAX_CONCURRENT_MATRIX \
6242 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6243#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6244 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6245static const struct nla_policy
6246wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6247 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6248};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306249
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306250static int
6251__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306252 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306253 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306254{
6255 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6256 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306257 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306258 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306259 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6260 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306261
6262 ENTER();
6263
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306264 ret = wlan_hdd_validate_context(pHddCtx);
6265 if (0 != ret)
6266 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306267 return ret;
6268 }
6269
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306270 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6271 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306272 hddLog(LOGE, FL("Invalid ATTR"));
6273 return -EINVAL;
6274 }
6275
6276 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306277 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306278 hddLog(LOGE, FL("Attr max feature set size failed"));
6279 return -EINVAL;
6280 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306281 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306282 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6283
6284 /* Fill feature combination matrix */
6285 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306286 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6287 WIFI_FEATURE_P2P;
6288
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306289 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6290 WIFI_FEATURE_SOFT_AP;
6291
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306292 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6293 WIFI_FEATURE_SOFT_AP;
6294
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306295 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6296 WIFI_FEATURE_SOFT_AP |
6297 WIFI_FEATURE_P2P;
6298
6299 /* Add more feature combinations here */
6300
6301 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6302 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6303 hddLog(LOG1, "Feature set matrix");
6304 for (i = 0; i < feature_sets; i++)
6305 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6306
6307 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6308 sizeof(u32) * feature_sets +
6309 NLMSG_HDRLEN);
6310
6311 if (reply_skb) {
6312 if (nla_put_u32(reply_skb,
6313 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6314 feature_sets) ||
6315 nla_put(reply_skb,
6316 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6317 sizeof(u32) * feature_sets, feature_set_matrix)) {
6318 hddLog(LOGE, FL("nla put fail"));
6319 kfree_skb(reply_skb);
6320 return -EINVAL;
6321 }
6322
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306323 ret = cfg80211_vendor_cmd_reply(reply_skb);
6324 EXIT();
6325 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306326 }
6327 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6328 return -ENOMEM;
6329
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306330}
6331
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306332#undef MAX_CONCURRENT_MATRIX
6333#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6334
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306335static int
6336wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6337 struct wireless_dev *wdev,
6338 const void *data, int data_len)
6339{
6340 int ret = 0;
6341
6342 vos_ssr_protect(__func__);
6343 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6344 data_len);
6345 vos_ssr_unprotect(__func__);
6346
6347 return ret;
6348}
6349
c_manjeecfd1efb2015-09-25 19:32:34 +05306350
6351static int
6352__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6353 struct wireless_dev *wdev,
6354 const void *data, int data_len)
6355{
6356 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6357 int ret;
6358 ENTER();
6359
6360 ret = wlan_hdd_validate_context(pHddCtx);
6361 if (0 != ret)
6362 {
6363 return ret;
6364 }
6365
6366 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6367 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6368 {
6369 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306370 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306371 }
6372 /*call common API for FW mem dump req*/
6373 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6374
Abhishek Singhc783fa72015-12-09 18:07:34 +05306375 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306376 {
6377 /*indicate to userspace the status of fw mem dump */
6378 wlan_indicate_mem_dump_complete(true);
6379 }
6380 else
6381 {
6382 /*else send failure to userspace */
6383 wlan_indicate_mem_dump_complete(false);
6384 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306385 EXIT();
6386 return ret;
6387}
6388
6389/**
6390 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6391 * @wiphy: pointer to wireless wiphy structure.
6392 * @wdev: pointer to wireless_dev structure.
6393 * @data: Pointer to the NL data.
6394 * @data_len:Length of @data
6395 *
6396 * This is called when wlan driver needs to get the firmware memory dump
6397 * via vendor specific command.
6398 *
6399 * Return: 0 on success, error number otherwise.
6400 */
6401
6402static int
6403wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6404 struct wireless_dev *wdev,
6405 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306406{
6407 int ret = 0;
6408 vos_ssr_protect(__func__);
6409 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6410 data_len);
6411 vos_ssr_unprotect(__func__);
6412 return ret;
6413}
c_manjeecfd1efb2015-09-25 19:32:34 +05306414
Sushant Kaushik8e644982015-09-23 12:18:54 +05306415static const struct
6416nla_policy
6417qca_wlan_vendor_wifi_logger_start_policy
6418[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6419 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6420 = {.type = NLA_U32 },
6421 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6422 = {.type = NLA_U32 },
6423 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6424 = {.type = NLA_U32 },
6425};
6426
6427/**
6428 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6429 * or disable the collection of packet statistics from the firmware
6430 * @wiphy: WIPHY structure pointer
6431 * @wdev: Wireless device structure pointer
6432 * @data: Pointer to the data received
6433 * @data_len: Length of the data received
6434 *
6435 * This function is used to enable or disable the collection of packet
6436 * statistics from the firmware
6437 *
6438 * Return: 0 on success and errno on failure
6439 */
6440static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6441 struct wireless_dev *wdev,
6442 const void *data,
6443 int data_len)
6444{
6445 eHalStatus status;
6446 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6447 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6448 tAniWifiStartLog start_log;
6449
6450 status = wlan_hdd_validate_context(hdd_ctx);
6451 if (0 != status) {
6452 return -EINVAL;
6453 }
6454
6455 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6456 data, data_len,
6457 qca_wlan_vendor_wifi_logger_start_policy)) {
6458 hddLog(LOGE, FL("Invalid attribute"));
6459 return -EINVAL;
6460 }
6461
6462 /* Parse and fetch ring id */
6463 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6464 hddLog(LOGE, FL("attr ATTR failed"));
6465 return -EINVAL;
6466 }
6467 start_log.ringId = nla_get_u32(
6468 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6469 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6470
6471 /* Parse and fetch verbose level */
6472 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6473 hddLog(LOGE, FL("attr verbose_level failed"));
6474 return -EINVAL;
6475 }
6476 start_log.verboseLevel = nla_get_u32(
6477 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6478 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6479
6480 /* Parse and fetch flag */
6481 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6482 hddLog(LOGE, FL("attr flag failed"));
6483 return -EINVAL;
6484 }
6485 start_log.flag = nla_get_u32(
6486 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6487 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6488
6489 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306490 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6491 !vos_isPktStatsEnabled()))
6492
Sushant Kaushik8e644982015-09-23 12:18:54 +05306493 {
6494 hddLog(LOGE, FL("per pkt stats not enabled"));
6495 return -EINVAL;
6496 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306497
Sushant Kaushik33200572015-08-05 16:46:20 +05306498 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306499 return 0;
6500}
6501
6502/**
6503 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6504 * or disable the collection of packet statistics from the firmware
6505 * @wiphy: WIPHY structure pointer
6506 * @wdev: Wireless device structure pointer
6507 * @data: Pointer to the data received
6508 * @data_len: Length of the data received
6509 *
6510 * This function is used to enable or disable the collection of packet
6511 * statistics from the firmware
6512 *
6513 * Return: 0 on success and errno on failure
6514 */
6515static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6516 struct wireless_dev *wdev,
6517 const void *data,
6518 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306519{
6520 int ret = 0;
6521
6522 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306523
6524 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6525 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306526 vos_ssr_unprotect(__func__);
6527
6528 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306529}
6530
6531
Agarwal Ashish738843c2014-09-25 12:27:56 +05306532static const struct nla_policy
6533wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6534 +1] =
6535{
6536 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6537};
6538
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306539static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306540 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306541 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306542 int data_len)
6543{
6544 struct net_device *dev = wdev->netdev;
6545 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6546 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6547 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6548 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6549 eHalStatus status;
6550 u32 dfsFlag = 0;
6551
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306552 ENTER();
6553
Agarwal Ashish738843c2014-09-25 12:27:56 +05306554 status = wlan_hdd_validate_context(pHddCtx);
6555 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306556 return -EINVAL;
6557 }
6558 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6559 data, data_len,
6560 wlan_hdd_set_no_dfs_flag_config_policy)) {
6561 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6562 return -EINVAL;
6563 }
6564
6565 /* Parse and fetch required bandwidth kbps */
6566 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6567 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6568 return -EINVAL;
6569 }
6570
6571 dfsFlag = nla_get_u32(
6572 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6573 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6574 dfsFlag);
6575
6576 pHddCtx->disable_dfs_flag = dfsFlag;
6577
6578 sme_disable_dfs_channel(hHal, dfsFlag);
6579 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306580
6581 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306582 return 0;
6583}
Atul Mittal115287b2014-07-08 13:26:33 +05306584
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306585static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6586 struct wireless_dev *wdev,
6587 const void *data,
6588 int data_len)
6589{
6590 int ret = 0;
6591
6592 vos_ssr_protect(__func__);
6593 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6594 vos_ssr_unprotect(__func__);
6595
6596 return ret;
6597
6598}
6599
Mukul Sharma2a271632014-10-13 14:59:01 +05306600const struct
6601nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6602{
6603 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306604 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6605 .type = NLA_UNSPEC,
6606 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306607};
6608
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306609static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306610 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306611{
6612
6613 u8 bssid[6] = {0};
6614 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6615 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6616 eHalStatus status = eHAL_STATUS_SUCCESS;
6617 v_U32_t isFwrRoamEnabled = FALSE;
6618 int ret;
6619
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306620 ENTER();
6621
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306622 ret = wlan_hdd_validate_context(pHddCtx);
6623 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306624 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306625 }
6626
6627 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6628 data, data_len,
6629 qca_wlan_vendor_attr);
6630 if (ret){
6631 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6632 return -EINVAL;
6633 }
6634
6635 /* Parse and fetch Enable flag */
6636 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6637 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6638 return -EINVAL;
6639 }
6640
6641 isFwrRoamEnabled = nla_get_u32(
6642 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6643
6644 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6645
6646 /* Parse and fetch bssid */
6647 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6648 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6649 return -EINVAL;
6650 }
6651
6652 memcpy(bssid, nla_data(
6653 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6654 sizeof(bssid));
6655 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6656
6657 //Update roaming
6658 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306659 if (!HAL_STATUS_SUCCESS(status)) {
6660 hddLog(LOGE,
6661 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6662 return -EINVAL;
6663 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306664 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306665 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306666}
6667
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306668static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6669 struct wireless_dev *wdev, const void *data, int data_len)
6670{
6671 int ret = 0;
6672
6673 vos_ssr_protect(__func__);
6674 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6675 vos_ssr_unprotect(__func__);
6676
6677 return ret;
6678}
6679
Sushant Kaushik847890c2015-09-28 16:05:17 +05306680static const struct
6681nla_policy
6682qca_wlan_vendor_get_wifi_info_policy[
6683 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6684 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6685 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6686};
6687
6688
6689/**
6690 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6691 * @wiphy: pointer to wireless wiphy structure.
6692 * @wdev: pointer to wireless_dev structure.
6693 * @data: Pointer to the data to be passed via vendor interface
6694 * @data_len:Length of the data to be passed
6695 *
6696 * This is called when wlan driver needs to send wifi driver related info
6697 * (driver/fw version) to the user space application upon request.
6698 *
6699 * Return: Return the Success or Failure code.
6700 */
6701static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6702 struct wireless_dev *wdev,
6703 const void *data, int data_len)
6704{
6705 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6706 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6707 tSirVersionString version;
6708 uint32 version_len;
6709 uint8 attr;
6710 int status;
6711 struct sk_buff *reply_skb = NULL;
6712
6713 if (VOS_FTM_MODE == hdd_get_conparam()) {
6714 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6715 return -EINVAL;
6716 }
6717
6718 status = wlan_hdd_validate_context(hdd_ctx);
6719 if (0 != status) {
6720 hddLog(LOGE, FL("HDD context is not valid"));
6721 return -EINVAL;
6722 }
6723
6724 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6725 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6726 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6727 return -EINVAL;
6728 }
6729
6730 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6731 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6732 QWLAN_VERSIONSTR);
6733 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6734 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6735 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6736 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6737 hdd_ctx->fw_Version);
6738 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6739 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6740 } else {
6741 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6742 return -EINVAL;
6743 }
6744
6745 version_len = strlen(version);
6746 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6747 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6748 if (!reply_skb) {
6749 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6750 return -ENOMEM;
6751 }
6752
6753 if (nla_put(reply_skb, attr, version_len, version)) {
6754 hddLog(LOGE, FL("nla put fail"));
6755 kfree_skb(reply_skb);
6756 return -EINVAL;
6757 }
6758
6759 return cfg80211_vendor_cmd_reply(reply_skb);
6760}
6761
6762/**
6763 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6764 * @wiphy: pointer to wireless wiphy structure.
6765 * @wdev: pointer to wireless_dev structure.
6766 * @data: Pointer to the data to be passed via vendor interface
6767 * @data_len:Length of the data to be passed
6768 * @data_len: Length of the data received
6769 *
6770 * This function is used to enable or disable the collection of packet
6771 * statistics from the firmware
6772 *
6773 * Return: 0 on success and errno on failure
6774 */
6775
6776static int
6777wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6778 struct wireless_dev *wdev,
6779 const void *data, int data_len)
6780
6781
6782{
6783 int ret = 0;
6784
6785 vos_ssr_protect(__func__);
6786 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6787 wdev, data, data_len);
6788 vos_ssr_unprotect(__func__);
6789
6790 return ret;
6791}
6792
6793
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306794/*
6795 * define short names for the global vendor params
6796 * used by __wlan_hdd_cfg80211_monitor_rssi()
6797 */
6798#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6799#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6800#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6801#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6802#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6803
6804/**---------------------------------------------------------------------------
6805
6806 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6807 monitor start is completed successfully.
6808
6809 \return - None
6810
6811 --------------------------------------------------------------------------*/
6812void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6813{
6814 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6815
6816 if (NULL == pHddCtx)
6817 {
6818 hddLog(VOS_TRACE_LEVEL_ERROR,
6819 "%s: HDD context is NULL",__func__);
6820 return;
6821 }
6822
6823 if (VOS_STATUS_SUCCESS == status)
6824 {
6825 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6826 }
6827 else
6828 {
6829 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6830 }
6831
6832 return;
6833}
6834
6835/**---------------------------------------------------------------------------
6836
6837 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6838 stop is completed successfully.
6839
6840 \return - None
6841
6842 --------------------------------------------------------------------------*/
6843void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6844{
6845 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6846
6847 if (NULL == pHddCtx)
6848 {
6849 hddLog(VOS_TRACE_LEVEL_ERROR,
6850 "%s: HDD context is NULL",__func__);
6851 return;
6852 }
6853
6854 if (VOS_STATUS_SUCCESS == status)
6855 {
6856 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6857 }
6858 else
6859 {
6860 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6861 }
6862
6863 return;
6864}
6865
6866/**
6867 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6868 * @wiphy: Pointer to wireless phy
6869 * @wdev: Pointer to wireless device
6870 * @data: Pointer to data
6871 * @data_len: Data length
6872 *
6873 * Return: 0 on success, negative errno on failure
6874 */
6875
6876static int
6877__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6878 struct wireless_dev *wdev,
6879 const void *data,
6880 int data_len)
6881{
6882 struct net_device *dev = wdev->netdev;
6883 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6884 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6885 hdd_station_ctx_t *pHddStaCtx;
6886 struct nlattr *tb[PARAM_MAX + 1];
6887 tpSirRssiMonitorReq pReq;
6888 eHalStatus status;
6889 int ret;
6890 uint32_t control;
6891 static const struct nla_policy policy[PARAM_MAX + 1] = {
6892 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6893 [PARAM_CONTROL] = { .type = NLA_U32 },
6894 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6895 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6896 };
6897
6898 ENTER();
6899
6900 ret = wlan_hdd_validate_context(hdd_ctx);
6901 if (0 != ret) {
6902 return -EINVAL;
6903 }
6904
6905 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6906 hddLog(LOGE, FL("Not in Connected state!"));
6907 return -ENOTSUPP;
6908 }
6909
6910 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6911 hddLog(LOGE, FL("Invalid ATTR"));
6912 return -EINVAL;
6913 }
6914
6915 if (!tb[PARAM_REQUEST_ID]) {
6916 hddLog(LOGE, FL("attr request id failed"));
6917 return -EINVAL;
6918 }
6919
6920 if (!tb[PARAM_CONTROL]) {
6921 hddLog(LOGE, FL("attr control failed"));
6922 return -EINVAL;
6923 }
6924
6925 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6926
6927 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6928 if(NULL == pReq)
6929 {
6930 hddLog(LOGE,
6931 FL("vos_mem_alloc failed "));
6932 return eHAL_STATUS_FAILED_ALLOC;
6933 }
6934 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6935
6936 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6937 pReq->sessionId = pAdapter->sessionId;
6938 pReq->rssiMonitorCbContext = hdd_ctx;
6939 control = nla_get_u32(tb[PARAM_CONTROL]);
6940 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6941
6942 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6943 pReq->requestId, pReq->sessionId, control);
6944
6945 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6946 if (!tb[PARAM_MIN_RSSI]) {
6947 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306948 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306949 }
6950
6951 if (!tb[PARAM_MAX_RSSI]) {
6952 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306953 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306954 }
6955
6956 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6957 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6958 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6959
6960 if (!(pReq->minRssi < pReq->maxRssi)) {
6961 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6962 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306963 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306964 }
6965 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6966 pReq->minRssi, pReq->maxRssi);
6967 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6968
6969 }
6970 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6971 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6972 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6973 }
6974 else {
6975 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306976 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306977 }
6978
6979 if (!HAL_STATUS_SUCCESS(status)) {
6980 hddLog(LOGE,
6981 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306982 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306983 }
6984
6985 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306986fail:
6987 vos_mem_free(pReq);
6988 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306989}
6990
6991/*
6992 * done with short names for the global vendor params
6993 * used by __wlan_hdd_cfg80211_monitor_rssi()
6994 */
6995#undef PARAM_MAX
6996#undef PARAM_CONTROL
6997#undef PARAM_REQUEST_ID
6998#undef PARAM_MAX_RSSI
6999#undef PARAM_MIN_RSSI
7000
7001/**
7002 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
7003 * @wiphy: wiphy structure pointer
7004 * @wdev: Wireless device structure pointer
7005 * @data: Pointer to the data received
7006 * @data_len: Length of @data
7007 *
7008 * Return: 0 on success; errno on failure
7009 */
7010static int
7011wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
7012 const void *data, int data_len)
7013{
7014 int ret;
7015
7016 vos_ssr_protect(__func__);
7017 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
7018 vos_ssr_unprotect(__func__);
7019
7020 return ret;
7021}
7022
7023/**
7024 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
7025 * @hddctx: HDD context
7026 * @data: rssi breached event data
7027 *
7028 * This function reads the rssi breached event %data and fill in the skb with
7029 * NL attributes and send up the NL event.
7030 * This callback execute in atomic context and must not invoke any
7031 * blocking calls.
7032 *
7033 * Return: none
7034 */
7035void hdd_rssi_threshold_breached_cb(void *hddctx,
7036 struct rssi_breach_event *data)
7037{
7038 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
7039 int status;
7040 struct sk_buff *skb;
7041
7042 ENTER();
7043 status = wlan_hdd_validate_context(pHddCtx);
7044
7045 if (0 != status) {
7046 return;
7047 }
7048
7049 if (!data) {
7050 hddLog(LOGE, FL("data is null"));
7051 return;
7052 }
7053
7054 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
7055#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7056 NULL,
7057#endif
7058 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
7059 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
7060 GFP_KERNEL);
7061
7062 if (!skb) {
7063 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
7064 return;
7065 }
7066
7067 hddLog(LOG1, "Req Id: %u Current rssi: %d",
7068 data->request_id, data->curr_rssi);
7069 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
7070 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
7071
7072 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
7073 data->request_id) ||
7074 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
7075 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
7076 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
7077 data->curr_rssi)) {
7078 hddLog(LOGE, FL("nla put fail"));
7079 goto fail;
7080 }
7081
7082 cfg80211_vendor_event(skb, GFP_KERNEL);
7083 return;
7084
7085fail:
7086 kfree_skb(skb);
7087 return;
7088}
7089
7090
7091
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307092/**
7093 * __wlan_hdd_cfg80211_setband() - set band
7094 * @wiphy: Pointer to wireless phy
7095 * @wdev: Pointer to wireless device
7096 * @data: Pointer to data
7097 * @data_len: Data length
7098 *
7099 * Return: 0 on success, negative errno on failure
7100 */
7101static int
7102__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7103 struct wireless_dev *wdev,
7104 const void *data,
7105 int data_len)
7106{
7107 struct net_device *dev = wdev->netdev;
7108 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7109 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7110 int ret;
7111 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7112 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7113
7114 ENTER();
7115
7116 ret = wlan_hdd_validate_context(hdd_ctx);
7117 if (0 != ret) {
7118 hddLog(LOGE, FL("HDD context is not valid"));
7119 return ret;
7120 }
7121
7122 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7123 policy)) {
7124 hddLog(LOGE, FL("Invalid ATTR"));
7125 return -EINVAL;
7126 }
7127
7128 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7129 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7130 return -EINVAL;
7131 }
7132
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307133 hdd_ctx->isSetBandByNL = TRUE;
7134 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307135 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307136 hdd_ctx->isSetBandByNL = FALSE;
7137
7138 EXIT();
7139 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307140}
7141
7142/**
7143 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7144 * @wiphy: wiphy structure pointer
7145 * @wdev: Wireless device structure pointer
7146 * @data: Pointer to the data received
7147 * @data_len: Length of @data
7148 *
7149 * Return: 0 on success; errno on failure
7150 */
7151static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7152 struct wireless_dev *wdev,
7153 const void *data,
7154 int data_len)
7155{
7156 int ret = 0;
7157
7158 vos_ssr_protect(__func__);
7159 ret = __wlan_hdd_cfg80211_setband(wiphy,
7160 wdev, data, data_len);
7161 vos_ssr_unprotect(__func__);
7162
7163 return ret;
7164}
7165
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307166#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7167/**
7168 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7169 * @hdd_ctx: HDD context
7170 * @request_id: [input] request id
7171 * @pattern_id: [output] pattern id
7172 *
7173 * This function loops through request id to pattern id array
7174 * if the slot is available, store the request id and return pattern id
7175 * if entry exists, return the pattern id
7176 *
7177 * Return: 0 on success and errno on failure
7178 */
7179static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7180 uint32_t request_id,
7181 uint8_t *pattern_id)
7182{
7183 uint32_t i;
7184
7185 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7186 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7187 {
7188 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7189 {
7190 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7191 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7192 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7193 return 0;
7194 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7195 request_id) {
7196 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7197 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7198 return 0;
7199 }
7200 }
7201 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7202 return -EINVAL;
7203}
7204
7205/**
7206 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7207 * @hdd_ctx: HDD context
7208 * @request_id: [input] request id
7209 * @pattern_id: [output] pattern id
7210 *
7211 * This function loops through request id to pattern id array
7212 * reset request id to 0 (slot available again) and
7213 * return pattern id
7214 *
7215 * Return: 0 on success and errno on failure
7216 */
7217static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7218 uint32_t request_id,
7219 uint8_t *pattern_id)
7220{
7221 uint32_t i;
7222
7223 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7224 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7225 {
7226 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7227 {
7228 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7229 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7230 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7231 return 0;
7232 }
7233 }
7234 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7235 return -EINVAL;
7236}
7237
7238
7239/*
7240 * define short names for the global vendor params
7241 * used by __wlan_hdd_cfg80211_offloaded_packets()
7242 */
7243#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7244#define PARAM_REQUEST_ID \
7245 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7246#define PARAM_CONTROL \
7247 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7248#define PARAM_IP_PACKET \
7249 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7250#define PARAM_SRC_MAC_ADDR \
7251 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7252#define PARAM_DST_MAC_ADDR \
7253 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7254#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7255
7256/**
7257 * wlan_hdd_add_tx_ptrn() - add tx pattern
7258 * @adapter: adapter pointer
7259 * @hdd_ctx: hdd context
7260 * @tb: nl attributes
7261 *
7262 * This function reads the NL attributes and forms a AddTxPtrn message
7263 * posts it to SME.
7264 *
7265 */
7266static int
7267wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7268 struct nlattr **tb)
7269{
7270 struct sSirAddPeriodicTxPtrn *add_req;
7271 eHalStatus status;
7272 uint32_t request_id, ret, len;
7273 uint8_t pattern_id = 0;
7274 v_MACADDR_t dst_addr;
7275 uint16_t eth_type = htons(ETH_P_IP);
7276
7277 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7278 {
7279 hddLog(LOGE, FL("Not in Connected state!"));
7280 return -ENOTSUPP;
7281 }
7282
7283 add_req = vos_mem_malloc(sizeof(*add_req));
7284 if (!add_req)
7285 {
7286 hddLog(LOGE, FL("memory allocation failed"));
7287 return -ENOMEM;
7288 }
7289
7290 /* Parse and fetch request Id */
7291 if (!tb[PARAM_REQUEST_ID])
7292 {
7293 hddLog(LOGE, FL("attr request id failed"));
7294 goto fail;
7295 }
7296
7297 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7298 hddLog(LOG1, FL("Request Id: %u"), request_id);
7299 if (request_id == 0)
7300 {
7301 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307302 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307303 }
7304
7305 if (!tb[PARAM_PERIOD])
7306 {
7307 hddLog(LOGE, FL("attr period failed"));
7308 goto fail;
7309 }
7310 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7311 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7312 if (add_req->usPtrnIntervalMs == 0)
7313 {
7314 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7315 goto fail;
7316 }
7317
7318 if (!tb[PARAM_SRC_MAC_ADDR])
7319 {
7320 hddLog(LOGE, FL("attr source mac address failed"));
7321 goto fail;
7322 }
7323 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7324 VOS_MAC_ADDR_SIZE);
7325 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7326 MAC_ADDR_ARRAY(add_req->macAddress));
7327
7328 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7329 VOS_MAC_ADDR_SIZE))
7330 {
7331 hddLog(LOGE,
7332 FL("input src mac address and connected ap bssid are different"));
7333 goto fail;
7334 }
7335
7336 if (!tb[PARAM_DST_MAC_ADDR])
7337 {
7338 hddLog(LOGE, FL("attr dst mac address failed"));
7339 goto fail;
7340 }
7341 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7342 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7343 MAC_ADDR_ARRAY(dst_addr.bytes));
7344
7345 if (!tb[PARAM_IP_PACKET])
7346 {
7347 hddLog(LOGE, FL("attr ip packet failed"));
7348 goto fail;
7349 }
7350 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7351 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7352
7353 if (add_req->ucPtrnSize < 0 ||
7354 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7355 HDD_ETH_HEADER_LEN))
7356 {
7357 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7358 add_req->ucPtrnSize);
7359 goto fail;
7360 }
7361
7362 len = 0;
7363 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7364 len += VOS_MAC_ADDR_SIZE;
7365 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7366 VOS_MAC_ADDR_SIZE);
7367 len += VOS_MAC_ADDR_SIZE;
7368 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7369 len += 2;
7370
7371 /*
7372 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7373 * ------------------------------------------------------------
7374 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7375 * ------------------------------------------------------------
7376 */
7377 vos_mem_copy(&add_req->ucPattern[len],
7378 nla_data(tb[PARAM_IP_PACKET]),
7379 add_req->ucPtrnSize);
7380 add_req->ucPtrnSize += len;
7381
7382 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7383 add_req->ucPattern, add_req->ucPtrnSize);
7384
7385 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7386 if (ret)
7387 {
7388 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7389 goto fail;
7390 }
7391 add_req->ucPtrnId = pattern_id;
7392 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7393
7394 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7395 if (!HAL_STATUS_SUCCESS(status))
7396 {
7397 hddLog(LOGE,
7398 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7399 goto fail;
7400 }
7401
7402 EXIT();
7403 vos_mem_free(add_req);
7404 return 0;
7405
7406fail:
7407 vos_mem_free(add_req);
7408 return -EINVAL;
7409}
7410
7411/**
7412 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7413 * @adapter: adapter pointer
7414 * @hdd_ctx: hdd context
7415 * @tb: nl attributes
7416 *
7417 * This function reads the NL attributes and forms a DelTxPtrn message
7418 * posts it to SME.
7419 *
7420 */
7421static int
7422wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7423 struct nlattr **tb)
7424{
7425 struct sSirDelPeriodicTxPtrn *del_req;
7426 eHalStatus status;
7427 uint32_t request_id, ret;
7428 uint8_t pattern_id = 0;
7429
7430 /* Parse and fetch request Id */
7431 if (!tb[PARAM_REQUEST_ID])
7432 {
7433 hddLog(LOGE, FL("attr request id failed"));
7434 return -EINVAL;
7435 }
7436 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7437 if (request_id == 0)
7438 {
7439 hddLog(LOGE, FL("request_id cannot be zero"));
7440 return -EINVAL;
7441 }
7442
7443 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7444 if (ret)
7445 {
7446 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7447 return -EINVAL;
7448 }
7449
7450 del_req = vos_mem_malloc(sizeof(*del_req));
7451 if (!del_req)
7452 {
7453 hddLog(LOGE, FL("memory allocation failed"));
7454 return -ENOMEM;
7455 }
7456
7457 vos_mem_set(del_req, sizeof(*del_req), 0);
7458 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7459 VOS_MAC_ADDR_SIZE);
7460 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7461 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7462 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7463 request_id, pattern_id, del_req->ucPatternIdBitmap);
7464
7465 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7466 if (!HAL_STATUS_SUCCESS(status))
7467 {
7468 hddLog(LOGE,
7469 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7470 goto fail;
7471 }
7472
7473 EXIT();
7474 vos_mem_free(del_req);
7475 return 0;
7476
7477fail:
7478 vos_mem_free(del_req);
7479 return -EINVAL;
7480}
7481
7482
7483/**
7484 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7485 * @wiphy: Pointer to wireless phy
7486 * @wdev: Pointer to wireless device
7487 * @data: Pointer to data
7488 * @data_len: Data length
7489 *
7490 * Return: 0 on success, negative errno on failure
7491 */
7492static int
7493__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7494 struct wireless_dev *wdev,
7495 const void *data,
7496 int data_len)
7497{
7498 struct net_device *dev = wdev->netdev;
7499 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7500 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7501 struct nlattr *tb[PARAM_MAX + 1];
7502 uint8_t control;
7503 int ret;
7504 static const struct nla_policy policy[PARAM_MAX + 1] =
7505 {
7506 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7507 [PARAM_CONTROL] = { .type = NLA_U32 },
7508 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7509 .len = VOS_MAC_ADDR_SIZE },
7510 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7511 .len = VOS_MAC_ADDR_SIZE },
7512 [PARAM_PERIOD] = { .type = NLA_U32 },
7513 };
7514
7515 ENTER();
7516
7517 ret = wlan_hdd_validate_context(hdd_ctx);
7518 if (0 != ret)
7519 {
7520 hddLog(LOGE, FL("HDD context is not valid"));
7521 return ret;
7522 }
7523
7524 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7525 {
7526 hddLog(LOGE,
7527 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7528 return -ENOTSUPP;
7529 }
7530
7531 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7532 {
7533 hddLog(LOGE, FL("Invalid ATTR"));
7534 return -EINVAL;
7535 }
7536
7537 if (!tb[PARAM_CONTROL])
7538 {
7539 hddLog(LOGE, FL("attr control failed"));
7540 return -EINVAL;
7541 }
7542 control = nla_get_u32(tb[PARAM_CONTROL]);
7543 hddLog(LOG1, FL("Control: %d"), control);
7544
7545 if (control == WLAN_START_OFFLOADED_PACKETS)
7546 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7547 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7548 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7549 else
7550 {
7551 hddLog(LOGE, FL("Invalid control: %d"), control);
7552 return -EINVAL;
7553 }
7554}
7555
7556/*
7557 * done with short names for the global vendor params
7558 * used by __wlan_hdd_cfg80211_offloaded_packets()
7559 */
7560#undef PARAM_MAX
7561#undef PARAM_REQUEST_ID
7562#undef PARAM_CONTROL
7563#undef PARAM_IP_PACKET
7564#undef PARAM_SRC_MAC_ADDR
7565#undef PARAM_DST_MAC_ADDR
7566#undef PARAM_PERIOD
7567
7568/**
7569 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7570 * @wiphy: wiphy structure pointer
7571 * @wdev: Wireless device structure pointer
7572 * @data: Pointer to the data received
7573 * @data_len: Length of @data
7574 *
7575 * Return: 0 on success; errno on failure
7576 */
7577static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7578 struct wireless_dev *wdev,
7579 const void *data,
7580 int data_len)
7581{
7582 int ret = 0;
7583
7584 vos_ssr_protect(__func__);
7585 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7586 wdev, data, data_len);
7587 vos_ssr_unprotect(__func__);
7588
7589 return ret;
7590}
7591#endif
7592
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307593static const struct
7594nla_policy
7595qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307596 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7597 .type = NLA_BINARY,
7598 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307599};
7600
7601/**
7602 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7603 * get link properties like nss, rate flags and operating frequency for
7604 * the connection with the given peer.
7605 * @wiphy: WIPHY structure pointer
7606 * @wdev: Wireless device structure pointer
7607 * @data: Pointer to the data received
7608 * @data_len: Length of the data received
7609 *
7610 * This function return the above link properties on success.
7611 *
7612 * Return: 0 on success and errno on failure
7613 */
7614static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7615 struct wireless_dev *wdev,
7616 const void *data,
7617 int data_len)
7618{
7619 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7620 struct net_device *dev = wdev->netdev;
7621 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7622 hdd_station_ctx_t *hdd_sta_ctx;
7623 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7624 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7625 uint32_t sta_id;
7626 struct sk_buff *reply_skb;
7627 uint32_t rate_flags = 0;
7628 uint8_t nss;
7629 uint8_t final_rate_flags = 0;
7630 uint32_t freq;
7631 v_CONTEXT_t pVosContext = NULL;
7632 ptSapContext pSapCtx = NULL;
7633
7634 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7635 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7636 return -EINVAL;
7637 }
7638
7639 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7640 qca_wlan_vendor_attr_policy)) {
7641 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7642 return -EINVAL;
7643 }
7644
7645 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7646 hddLog(VOS_TRACE_LEVEL_ERROR,
7647 FL("Attribute peerMac not provided for mode=%d"),
7648 adapter->device_mode);
7649 return -EINVAL;
7650 }
7651
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307652 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7653 hddLog(VOS_TRACE_LEVEL_ERROR,
7654 FL("Attribute peerMac is invalid=%d"),
7655 adapter->device_mode);
7656 return -EINVAL;
7657 }
7658
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307659 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7660 sizeof(peer_mac));
7661 hddLog(VOS_TRACE_LEVEL_INFO,
7662 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7663 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7664
7665 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7666 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7667 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7668 if ((hdd_sta_ctx->conn_info.connState !=
7669 eConnectionState_Associated) ||
7670 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7671 VOS_MAC_ADDRESS_LEN)) {
7672 hddLog(VOS_TRACE_LEVEL_ERROR,
7673 FL("Not Associated to mac "MAC_ADDRESS_STR),
7674 MAC_ADDR_ARRAY(peer_mac));
7675 return -EINVAL;
7676 }
7677
7678 nss = 1; //pronto supports only one spatial stream
7679 freq = vos_chan_to_freq(
7680 hdd_sta_ctx->conn_info.operationChannel);
7681 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7682
7683 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7684 adapter->device_mode == WLAN_HDD_SOFTAP) {
7685
7686 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7687 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7688 if(pSapCtx == NULL){
7689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7690 FL("psapCtx is NULL"));
7691 return -ENOENT;
7692 }
7693
7694
7695 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7696 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7697 !vos_is_macaddr_broadcast(
7698 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7699 vos_mem_compare(
7700 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7701 peer_mac, VOS_MAC_ADDRESS_LEN))
7702 break;
7703 }
7704
7705 if (WLAN_MAX_STA_COUNT == sta_id) {
7706 hddLog(VOS_TRACE_LEVEL_ERROR,
7707 FL("No active peer with mac="MAC_ADDRESS_STR),
7708 MAC_ADDR_ARRAY(peer_mac));
7709 return -EINVAL;
7710 }
7711
7712 nss = 1; //pronto supports only one spatial stream
7713 freq = vos_chan_to_freq(
7714 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7715 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7716 } else {
7717 hddLog(VOS_TRACE_LEVEL_ERROR,
7718 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7719 MAC_ADDR_ARRAY(peer_mac));
7720 return -EINVAL;
7721 }
7722
7723 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7724 if (rate_flags & eHAL_TX_RATE_VHT80) {
7725 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307726#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7727 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307728 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307729#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307730 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7731 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307732#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7733 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307734 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307735#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307736 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7737 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7738 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7739 final_rate_flags |= RATE_INFO_FLAGS_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307740#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7741 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307742 if (rate_flags & eHAL_TX_RATE_HT40)
7743 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307744#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307745 }
7746
7747 if (rate_flags & eHAL_TX_RATE_SGI) {
7748 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7749 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7750 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7751 }
7752 }
7753
7754 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7755 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7756
7757 if (NULL == reply_skb) {
7758 hddLog(VOS_TRACE_LEVEL_ERROR,
7759 FL("getLinkProperties: skb alloc failed"));
7760 return -EINVAL;
7761 }
7762
7763 if (nla_put_u8(reply_skb,
7764 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7765 nss) ||
7766 nla_put_u8(reply_skb,
7767 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7768 final_rate_flags) ||
7769 nla_put_u32(reply_skb,
7770 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7771 freq)) {
7772 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7773 kfree_skb(reply_skb);
7774 return -EINVAL;
7775 }
7776
7777 return cfg80211_vendor_cmd_reply(reply_skb);
7778}
7779
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307780#define BEACON_MISS_THRESH_2_4 \
7781 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7782#define BEACON_MISS_THRESH_5_0 \
7783 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307784#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7785#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7786#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7787#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307788#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7789 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307790#define PARAM_FORCE_RSN_IE \
7791 QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307792/*
7793 * hdd_set_qpower() - Process the qpower command and invoke the SME api
7794 * @hdd_ctx: hdd context
7795 * @enable: Value received in the command, 1 for disable and 2 for enable
7796 *
7797 * Return: void
7798 */
7799static void hdd_set_qpower(hdd_context_t *hdd_ctx, uint8_t enable)
7800{
7801 if (!hdd_ctx) {
7802 hddLog(LOGE, "hdd_ctx NULL");
7803 return;
7804 }
7805
7806 sme_set_qpower(hdd_ctx->hHal, enable);
7807}
7808
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307809/**
7810 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7811 * vendor command
7812 *
7813 * @wiphy: wiphy device pointer
7814 * @wdev: wireless device pointer
7815 * @data: Vendor command data buffer
7816 * @data_len: Buffer length
7817 *
7818 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7819 *
7820 * Return: EOK or other error codes.
7821 */
7822
7823static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7824 struct wireless_dev *wdev,
7825 const void *data,
7826 int data_len)
7827{
7828 struct net_device *dev = wdev->netdev;
7829 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7830 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7831 hdd_station_ctx_t *pHddStaCtx;
7832 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7833 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307834 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307835 eHalStatus status;
7836 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307837 uint8_t hb_thresh_val;
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307838 uint8_t qpower;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307839
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307840 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7841 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7842 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307843 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7844 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7845 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307846 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7847 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307848 [PARAM_FORCE_RSN_IE] = {.type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307849 };
7850
7851 ENTER();
7852
7853 if (VOS_FTM_MODE == hdd_get_conparam()) {
7854 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7855 return -EINVAL;
7856 }
7857
7858 ret_val = wlan_hdd_validate_context(pHddCtx);
7859 if (ret_val) {
7860 return ret_val;
7861 }
7862
7863 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7864
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307865 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7866 hddLog(LOGE, FL("Invalid ATTR"));
7867 return -EINVAL;
7868 }
7869
7870 /* check the Wifi Capability */
7871 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7872 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7873 {
7874 hddLog(VOS_TRACE_LEVEL_ERROR,
7875 FL("WIFICONFIG not supported by Firmware"));
7876 return -EINVAL;
7877 }
7878
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307879 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7880 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7881 modifyRoamParamsReq.value =
7882 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7883
7884 if (eHAL_STATUS_SUCCESS !=
7885 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7886 {
7887 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7888 ret_val = -EINVAL;
7889 }
7890 return ret_val;
7891 }
7892
7893 /* Moved this down in order to provide provision to set beacon
7894 * miss penalty count irrespective of connection state.
7895 */
7896 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7897 hddLog(LOGE, FL("Not in Connected state!"));
7898 return -ENOTSUPP;
7899 }
7900
7901 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307902
7903 if (!pReq) {
7904 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7905 "%s: Not able to allocate memory for tSetWifiConfigParams",
7906 __func__);
7907 return eHAL_STATUS_E_MALLOC_FAILED;
7908 }
7909
7910 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7911
7912 pReq->sessionId = pAdapter->sessionId;
7913 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7914
7915 if (tb[PARAM_MODULATED_DTIM]) {
7916 pReq->paramValue = nla_get_u32(
7917 tb[PARAM_MODULATED_DTIM]);
7918 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7919 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307920 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307921 hdd_set_pwrparams(pHddCtx);
7922 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7923 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7924
7925 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7926 iw_full_power_cbfn, pAdapter,
7927 eSME_FULL_PWR_NEEDED_BY_HDD);
7928 }
7929 else
7930 {
7931 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7932 }
7933 }
7934
7935 if (tb[PARAM_STATS_AVG_FACTOR]) {
7936 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7937 pReq->paramValue = nla_get_u16(
7938 tb[PARAM_STATS_AVG_FACTOR]);
7939 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7940 pReq->paramType, pReq->paramValue);
7941 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7942
7943 if (eHAL_STATUS_SUCCESS != status)
7944 {
7945 vos_mem_free(pReq);
7946 pReq = NULL;
7947 ret_val = -EPERM;
7948 return ret_val;
7949 }
7950 }
7951
7952
7953 if (tb[PARAM_GUARD_TIME]) {
7954 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7955 pReq->paramValue = nla_get_u32(
7956 tb[PARAM_GUARD_TIME]);
7957 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7958 pReq->paramType, pReq->paramValue);
7959 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7960
7961 if (eHAL_STATUS_SUCCESS != status)
7962 {
7963 vos_mem_free(pReq);
7964 pReq = NULL;
7965 ret_val = -EPERM;
7966 return ret_val;
7967 }
7968
7969 }
7970
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307971 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7972 hb_thresh_val = nla_get_u8(
7973 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7974
7975 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7976 hb_thresh_val);
7977 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7978 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7979 NULL, eANI_BOOLEAN_FALSE);
7980
7981 status = sme_update_hb_threshold(
7982 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7983 WNI_CFG_HEART_BEAT_THRESHOLD,
7984 hb_thresh_val, eCSR_BAND_24);
7985 if (eHAL_STATUS_SUCCESS != status) {
7986 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7987 vos_mem_free(pReq);
7988 pReq = NULL;
7989 return -EPERM;
7990 }
7991 }
7992
7993 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7994 hb_thresh_val = nla_get_u8(
7995 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7996
7997 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
7998 hb_thresh_val);
7999 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
8000 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
8001 NULL, eANI_BOOLEAN_FALSE);
8002
8003 status = sme_update_hb_threshold(
8004 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
8005 WNI_CFG_HEART_BEAT_THRESHOLD,
8006 hb_thresh_val, eCSR_BAND_5G);
8007 if (eHAL_STATUS_SUCCESS != status) {
8008 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
8009 vos_mem_free(pReq);
8010 pReq = NULL;
8011 return -EPERM;
8012 }
8013 }
8014
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05308015 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]) {
8016 qpower = nla_get_u8(
8017 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]);
8018
8019 if(qpower > 1) {
8020 hddLog(LOGE, "Invalid QPOWER value %d", qpower);
8021 vos_mem_free(pReq);
8022 pReq = NULL;
8023 return -EINVAL;
8024 }
8025 /* FW is expacting qpower as 1 for Disable and 2 for enable */
8026 qpower++;
8027 hdd_set_qpower(pHddCtx, qpower);
8028 }
8029
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05308030 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE] &&
8031 pHddCtx->cfg_ini->force_rsne_override) {
8032 uint8_t force_rsne_override;
8033
8034 force_rsne_override =
8035 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE]);
8036 if (force_rsne_override > 1) {
8037 hddLog(LOGE, "Invalid test_mode %d", force_rsne_override);
8038 ret_val = -EINVAL;
8039 }
8040 pHddCtx->force_rsne_override = force_rsne_override;
8041 hddLog(LOG1, "force_rsne_override - %d",
8042 pHddCtx->force_rsne_override);
8043 }
8044
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308045 EXIT();
8046 return ret_val;
8047}
8048
8049/**
8050 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
8051 * vendor command
8052 *
8053 * @wiphy: wiphy device pointer
8054 * @wdev: wireless device pointer
8055 * @data: Vendor command data buffer
8056 * @data_len: Buffer length
8057 *
8058 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
8059 *
8060 * Return: EOK or other error codes.
8061 */
8062static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
8063 struct wireless_dev *wdev,
8064 const void *data,
8065 int data_len)
8066{
8067 int ret;
8068
8069 vos_ssr_protect(__func__);
8070 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
8071 data, data_len);
8072 vos_ssr_unprotect(__func__);
8073
8074 return ret;
8075}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308076
8077/*
8078 * define short names for the global vendor params
8079 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8080 */
8081#define STATS_SET_INVALID \
8082 QCA_ATTR_NUD_STATS_SET_INVALID
8083#define STATS_SET_START \
8084 QCA_ATTR_NUD_STATS_SET_START
8085#define STATS_GW_IPV4 \
8086 QCA_ATTR_NUD_STATS_GW_IPV4
8087#define STATS_SET_MAX \
8088 QCA_ATTR_NUD_STATS_SET_MAX
8089
8090const struct nla_policy
8091qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
8092{
8093 [STATS_SET_START] = {.type = NLA_FLAG },
8094 [STATS_GW_IPV4] = {.type = NLA_U32 },
8095};
8096
8097/**
8098 * hdd_set_nud_stats_cb() - hdd callback api to get status
8099 * @data: pointer to adapter
8100 * @rsp: status
8101 *
8102 * Return: None
8103 */
8104static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
8105{
8106
8107 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8108
8109 if (NULL == adapter)
8110 return;
8111
8112 if (VOS_STATUS_SUCCESS == rsp) {
8113 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8114 "%s success received STATS_SET_START", __func__);
8115 } else {
8116 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8117 "%s STATS_SET_START Failed!!", __func__);
8118 }
8119 return;
8120}
8121
8122/**
8123 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8124 * @wiphy: pointer to wireless wiphy structure.
8125 * @wdev: pointer to wireless_dev structure.
8126 * @data: pointer to apfind configuration data.
8127 * @data_len: the length in byte of apfind data.
8128 *
8129 * This is called when wlan driver needs to send arp stats to
8130 * firmware.
8131 *
8132 * Return: An error code or 0 on success.
8133 */
8134static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8135 struct wireless_dev *wdev,
8136 const void *data, int data_len)
8137{
8138 struct nlattr *tb[STATS_SET_MAX + 1];
8139 struct net_device *dev = wdev->netdev;
8140 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8141 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308142 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308143 setArpStatsParams arp_stats_params;
8144 int err = 0;
8145
8146 ENTER();
8147
8148 err = wlan_hdd_validate_context(hdd_ctx);
8149 if (0 != err)
8150 return err;
8151
8152 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8154 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8155 return -EINVAL;
8156 }
8157
8158 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8159 qca_wlan_vendor_set_nud_stats);
8160 if (err)
8161 {
8162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8163 "%s STATS_SET_START ATTR", __func__);
8164 return err;
8165 }
8166
8167 if (tb[STATS_SET_START])
8168 {
8169 if (!tb[STATS_GW_IPV4]) {
8170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8171 "%s STATS_SET_START CMD", __func__);
8172 return -EINVAL;
8173 }
8174 arp_stats_params.flag = true;
8175 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8176 } else {
8177 arp_stats_params.flag = false;
8178 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308179 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8181 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308182 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8183 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308184
8185 arp_stats_params.pkt_type = 1; // ARP packet type
8186
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308187 if (arp_stats_params.flag) {
8188 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8189 WLANTL_SetARPFWDatapath(pVosContext, true);
8190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8191 "%s Set FW in data path for ARP with tgt IP :%d",
8192 __func__, hdd_ctx->track_arp_ip);
8193 }
8194 else {
8195 WLANTL_SetARPFWDatapath(pVosContext, false);
8196 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8197 "%s Remove FW from data path", __func__);
8198 }
8199
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308200 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8201 arp_stats_params.data_ctx = adapter;
8202
8203 if (eHAL_STATUS_SUCCESS !=
8204 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8206 "%s STATS_SET_START CMD Failed!!", __func__);
8207 return -EINVAL;
8208 }
8209
8210 EXIT();
8211
8212 return err;
8213}
8214
8215/**
8216 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8217 * @wiphy: pointer to wireless wiphy structure.
8218 * @wdev: pointer to wireless_dev structure.
8219 * @data: pointer to apfind configuration data.
8220 * @data_len: the length in byte of apfind data.
8221 *
8222 * This is called when wlan driver needs to send arp stats to
8223 * firmware.
8224 *
8225 * Return: An error code or 0 on success.
8226 */
8227static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8228 struct wireless_dev *wdev,
8229 const void *data, int data_len)
8230{
8231 int ret;
8232
8233 vos_ssr_protect(__func__);
8234 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8235 vos_ssr_unprotect(__func__);
8236
8237 return ret;
8238}
8239#undef STATS_SET_INVALID
8240#undef STATS_SET_START
8241#undef STATS_GW_IPV4
8242#undef STATS_SET_MAX
8243
8244/*
8245 * define short names for the global vendor params
8246 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8247 */
8248#define STATS_GET_INVALID \
8249 QCA_ATTR_NUD_STATS_SET_INVALID
8250#define COUNT_FROM_NETDEV \
8251 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8252#define COUNT_TO_LOWER_MAC \
8253 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8254#define RX_COUNT_BY_LOWER_MAC \
8255 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8256#define COUNT_TX_SUCCESS \
8257 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8258#define RSP_RX_COUNT_BY_LOWER_MAC \
8259 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8260#define RSP_RX_COUNT_BY_UPPER_MAC \
8261 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8262#define RSP_COUNT_TO_NETDEV \
8263 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8264#define RSP_COUNT_OUT_OF_ORDER_DROP \
8265 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8266#define AP_LINK_ACTIVE \
8267 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8268#define AP_LINK_DAD \
8269 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8270#define STATS_GET_MAX \
8271 QCA_ATTR_NUD_STATS_GET_MAX
8272
8273const struct nla_policy
8274qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8275{
8276 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8277 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8278 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8279 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8280 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8281 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8282 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8283 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8284 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8285 [AP_LINK_DAD] = {.type = NLA_FLAG },
8286};
8287
8288static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8289{
8290
8291 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308292 hdd_context_t *hdd_ctx;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308293 struct hdd_nud_stats_context *context;
8294 int status;
8295
8296 ENTER();
8297
8298 if (NULL == adapter)
8299 return;
8300
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308301 if (!rsp) {
8302 hddLog(LOGE, FL("data is null"));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308303 return;
8304 }
8305
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308306 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8307 status = wlan_hdd_validate_context(hdd_ctx);
8308 if (0 != status) {
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308309 return;
8310 }
8311
8312 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8313 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8314 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8315 adapter->dad |= rsp->dad;
8316
8317 spin_lock(&hdd_context_lock);
8318 context = &hdd_ctx->nud_stats_context;
8319 complete(&context->response_event);
8320 spin_unlock(&hdd_context_lock);
8321
8322 return;
8323}
8324static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8325 struct wireless_dev *wdev,
8326 const void *data, int data_len)
8327{
8328 int err = 0;
8329 unsigned long rc;
8330 struct hdd_nud_stats_context *context;
8331 struct net_device *dev = wdev->netdev;
8332 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8333 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8334 getArpStatsParams arp_stats_params;
8335 struct sk_buff *skb;
8336
8337 ENTER();
8338
8339 err = wlan_hdd_validate_context(hdd_ctx);
8340 if (0 != err)
8341 return err;
8342
8343 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8344 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8345 arp_stats_params.data_ctx = adapter;
8346
8347 spin_lock(&hdd_context_lock);
8348 context = &hdd_ctx->nud_stats_context;
8349 INIT_COMPLETION(context->response_event);
8350 spin_unlock(&hdd_context_lock);
8351
8352 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8354 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8355 return -EINVAL;
8356 }
8357
8358 if (eHAL_STATUS_SUCCESS !=
8359 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8360 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8361 "%s STATS_SET_START CMD Failed!!", __func__);
8362 return -EINVAL;
8363 }
8364
8365 rc = wait_for_completion_timeout(&context->response_event,
8366 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8367 if (!rc)
8368 {
8369 hddLog(LOGE,
8370 FL("Target response timed out request "));
8371 return -ETIMEDOUT;
8372 }
8373
8374 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8375 WLAN_NUD_STATS_LEN);
8376 if (!skb)
8377 {
8378 hddLog(VOS_TRACE_LEVEL_ERROR,
8379 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8380 __func__);
8381 return -ENOMEM;
8382 }
8383
8384 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8385 adapter->hdd_stats.hddArpStats.txCount) ||
8386 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8387 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8388 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8389 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8390 nla_put_u16(skb, COUNT_TX_SUCCESS,
8391 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8392 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8393 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8394 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8395 adapter->hdd_stats.hddArpStats.rxCount) ||
8396 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8397 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8398 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8399 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8400 hddLog(LOGE, FL("nla put fail"));
8401 kfree_skb(skb);
8402 return -EINVAL;
8403 }
8404 if (adapter->con_status)
8405 nla_put_flag(skb, AP_LINK_ACTIVE);
8406 if (adapter->dad)
8407 nla_put_flag(skb, AP_LINK_DAD);
8408
8409 cfg80211_vendor_cmd_reply(skb);
8410 return err;
8411}
8412
8413static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8414 struct wireless_dev *wdev,
8415 const void *data, int data_len)
8416{
8417 int ret;
8418
8419 vos_ssr_protect(__func__);
8420 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8421 vos_ssr_unprotect(__func__);
8422
8423 return ret;
8424}
8425
8426#undef QCA_ATTR_NUD_STATS_SET_INVALID
8427#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8428#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8429#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8430#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8431#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8432#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8433#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8434#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8435#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8436#undef QCA_ATTR_NUD_STATS_GET_MAX
8437
8438
8439
Kapil Guptaee33bf12016-12-20 18:27:37 +05308440#ifdef WLAN_FEATURE_APFIND
8441/**
8442 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8443 * @wiphy: pointer to wireless wiphy structure.
8444 * @wdev: pointer to wireless_dev structure.
8445 * @data: pointer to apfind configuration data.
8446 * @data_len: the length in byte of apfind data.
8447 *
8448 * This is called when wlan driver needs to send APFIND configurations to
8449 * firmware.
8450 *
8451 * Return: An error code or 0 on success.
8452 */
8453static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8454 struct wireless_dev *wdev,
8455 const void *data, int data_len)
8456{
8457 struct sme_ap_find_request_req apfind_req;
8458 VOS_STATUS status;
8459 int ret_val;
8460 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8461
8462 ENTER();
8463
8464 ret_val = wlan_hdd_validate_context(hdd_ctx);
8465 if (ret_val)
8466 return ret_val;
8467
8468 if (VOS_FTM_MODE == hdd_get_conparam()) {
8469 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8470 return -EPERM;
8471 }
8472
8473 apfind_req.request_data_len = data_len;
8474 apfind_req.request_data = data;
8475
8476 status = sme_apfind_set_cmd(&apfind_req);
8477 if (VOS_STATUS_SUCCESS != status) {
8478 ret_val = -EIO;
8479 }
8480 return ret_val;
8481}
8482
8483/**
8484 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8485 * @wiphy: pointer to wireless wiphy structure.
8486 * @wdev: pointer to wireless_dev structure.
8487 * @data: pointer to apfind configuration data.
8488 * @data_len: the length in byte of apfind data.
8489 *
8490 * This is called when wlan driver needs to send APFIND configurations to
8491 * firmware.
8492 *
8493 * Return: An error code or 0 on success.
8494 */
8495static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8496 struct wireless_dev *wdev,
8497 const void *data, int data_len)
8498{
8499 int ret;
8500
8501 vos_ssr_protect(__func__);
8502 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8503 vos_ssr_unprotect(__func__);
8504
8505 return ret;
8506}
8507#endif /* WLAN_FEATURE_APFIND */
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308508
8509/**
8510 * __wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8511 * @wiphy: pointer to wireless wiphy structure.
8512 * @wdev: pointer to wireless_dev structure.
8513 * @data: Pointer to the data to be passed via vendor interface
8514 * @data_len:Length of the data to be passed
8515 *
8516 * This is called by userspace to know the supported logger features
8517 *
8518 * Return: Return the Success or Failure code.
8519 */
8520static int
8521__wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8522 struct wireless_dev *wdev,
8523 const void *data, int data_len)
8524{
8525 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8526 int status;
8527 uint32_t features;
8528 struct sk_buff *reply_skb = NULL;
8529
8530 if (VOS_FTM_MODE == hdd_get_conparam()) {
8531 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8532 return -EINVAL;
8533 }
8534
8535 status = wlan_hdd_validate_context(hdd_ctx);
8536 if (0 != status)
8537 return -EINVAL;
8538
8539 features = 0;
8540
8541 if (hdd_is_memdump_supported())
8542 features |= WIFI_LOGGER_MEMORY_DUMP_SUPPORTED;
8543
8544 if (hdd_ctx->cfg_ini->wlanLoggingEnable &&
8545 hdd_ctx->cfg_ini->enableFatalEvent &&
8546 hdd_ctx->is_fatal_event_log_sup) {
8547 features |= WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED;
8548 features |= WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
8549 }
8550
8551 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8552 sizeof(uint32_t) + NLA_HDRLEN + NLMSG_HDRLEN);
8553 if (!reply_skb) {
8554 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
8555 return -ENOMEM;
8556 }
8557
8558 hddLog(LOG1, FL("Supported logger features: 0x%0x"), features);
8559 if (nla_put_u32(reply_skb, QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED,
8560 features)) {
8561 hddLog(LOGE, FL("nla put fail"));
8562 kfree_skb(reply_skb);
8563 return -EINVAL;
8564 }
8565
8566 return cfg80211_vendor_cmd_reply(reply_skb);
8567}
8568
8569/**
8570 * wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8571 * @wiphy: pointer to wireless wiphy structure.
8572 * @wdev: pointer to wireless_dev structure.
8573 * @data: Pointer to the data to be passed via vendor interface
8574 * @data_len:Length of the data to be passed
8575 *
8576 * This is called by userspace to know the supported logger features
8577 *
8578 * Return: Return the Success or Failure code.
8579 */
8580static int
8581wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8582 struct wireless_dev *wdev,
8583 const void *data, int data_len)
8584{
8585 int ret;
8586
8587 vos_ssr_protect(__func__);
8588 ret = __wlan_hdd_cfg80211_get_logger_supp_feature(wiphy, wdev,
8589 data, data_len);
8590 vos_ssr_unprotect(__func__);
8591
8592 return ret;
8593}
8594
Sunil Duttc69bccb2014-05-26 21:30:20 +05308595const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8596{
Mukul Sharma2a271632014-10-13 14:59:01 +05308597 {
8598 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8599 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8600 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8601 WIPHY_VENDOR_CMD_NEED_NETDEV |
8602 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308603 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308604 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308605
8606 {
8607 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8608 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8609 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8610 WIPHY_VENDOR_CMD_NEED_NETDEV |
8611 WIPHY_VENDOR_CMD_NEED_RUNNING,
8612 .doit = wlan_hdd_cfg80211_nan_request
8613 },
8614
Sunil Duttc69bccb2014-05-26 21:30:20 +05308615#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8616 {
8617 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8618 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8619 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8620 WIPHY_VENDOR_CMD_NEED_NETDEV |
8621 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308622 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308623 },
8624
8625 {
8626 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8627 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8628 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8629 WIPHY_VENDOR_CMD_NEED_NETDEV |
8630 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308631 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308632 },
8633
8634 {
8635 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8636 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8637 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8638 WIPHY_VENDOR_CMD_NEED_NETDEV |
8639 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308640 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308641 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308642#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308643#ifdef WLAN_FEATURE_EXTSCAN
8644 {
8645 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8646 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8647 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8648 WIPHY_VENDOR_CMD_NEED_NETDEV |
8649 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308650 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308651 },
8652 {
8653 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8654 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8655 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8656 WIPHY_VENDOR_CMD_NEED_NETDEV |
8657 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308658 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308659 },
8660 {
8661 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8662 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8663 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8664 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308665 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308666 },
8667 {
8668 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8669 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8670 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8671 WIPHY_VENDOR_CMD_NEED_NETDEV |
8672 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308673 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308674 },
8675 {
8676 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8677 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8678 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8679 WIPHY_VENDOR_CMD_NEED_NETDEV |
8680 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308681 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308682 },
8683 {
8684 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8685 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8686 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8687 WIPHY_VENDOR_CMD_NEED_NETDEV |
8688 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308689 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308690 },
8691 {
8692 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8693 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8694 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8695 WIPHY_VENDOR_CMD_NEED_NETDEV |
8696 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308697 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308698 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308699#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308700/*EXT TDLS*/
8701 {
8702 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8703 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8704 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8705 WIPHY_VENDOR_CMD_NEED_NETDEV |
8706 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308707 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308708 },
8709 {
8710 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8711 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8712 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8713 WIPHY_VENDOR_CMD_NEED_NETDEV |
8714 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308715 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308716 },
8717 {
8718 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8719 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8720 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8721 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308722 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308723 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308724 {
8725 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8726 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8727 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8728 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308729 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308730 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308731 {
8732 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8733 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8734 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8735 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308736 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308737 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308738 {
8739 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8740 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8741 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8742 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308743 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308744 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308745 {
8746 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8747 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8748 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8749 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308750 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308751 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308752 {
8753 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308754 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8755 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8756 WIPHY_VENDOR_CMD_NEED_NETDEV |
8757 WIPHY_VENDOR_CMD_NEED_RUNNING,
8758 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8759 },
8760 {
8761 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308762 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8763 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8764 WIPHY_VENDOR_CMD_NEED_NETDEV |
8765 WIPHY_VENDOR_CMD_NEED_RUNNING,
8766 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308767 },
8768 {
8769 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8770 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8771 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8772 WIPHY_VENDOR_CMD_NEED_NETDEV,
8773 .doit = wlan_hdd_cfg80211_wifi_logger_start
8774 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308775 {
8776 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8777 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8778 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8779 WIPHY_VENDOR_CMD_NEED_NETDEV|
8780 WIPHY_VENDOR_CMD_NEED_RUNNING,
8781 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308782 },
8783 {
8784 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8785 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8786 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8787 WIPHY_VENDOR_CMD_NEED_NETDEV |
8788 WIPHY_VENDOR_CMD_NEED_RUNNING,
8789 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308790 },
8791 {
8792 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8793 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8794 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8795 WIPHY_VENDOR_CMD_NEED_NETDEV |
8796 WIPHY_VENDOR_CMD_NEED_RUNNING,
8797 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308798 },
8799#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8800 {
8801 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8802 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8803 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8804 WIPHY_VENDOR_CMD_NEED_NETDEV |
8805 WIPHY_VENDOR_CMD_NEED_RUNNING,
8806 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308807 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308808#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308809 {
8810 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8811 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8812 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8813 WIPHY_VENDOR_CMD_NEED_NETDEV |
8814 WIPHY_VENDOR_CMD_NEED_RUNNING,
8815 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308816 },
8817 {
8818 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8819 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8820 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8821 WIPHY_VENDOR_CMD_NEED_NETDEV |
8822 WIPHY_VENDOR_CMD_NEED_RUNNING,
8823 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308824 },
8825#ifdef WLAN_FEATURE_APFIND
8826 {
8827 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8828 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8829 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8830 WIPHY_VENDOR_CMD_NEED_NETDEV,
8831 .doit = wlan_hdd_cfg80211_apfind_cmd
8832 },
8833#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308834 {
8835 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8836 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8837 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8838 WIPHY_VENDOR_CMD_NEED_NETDEV |
8839 WIPHY_VENDOR_CMD_NEED_RUNNING,
8840 .doit = wlan_hdd_cfg80211_set_nud_stats
8841 },
8842 {
8843 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8844 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8845 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8846 WIPHY_VENDOR_CMD_NEED_NETDEV |
8847 WIPHY_VENDOR_CMD_NEED_RUNNING,
8848 .doit = wlan_hdd_cfg80211_get_nud_stats
8849 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308850 {
8851 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8852 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8853 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8854 WIPHY_VENDOR_CMD_NEED_NETDEV |
8855 WIPHY_VENDOR_CMD_NEED_RUNNING,
8856 .doit = hdd_cfg80211_get_station_cmd
8857 },
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308858 {
8859 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8860 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET,
8861 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
Hanumanth Reddy Pothula07c95582018-05-23 12:41:22 +05308862 WIPHY_VENDOR_CMD_NEED_NETDEV,
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308863 .doit = wlan_hdd_cfg80211_get_logger_supp_feature
8864 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308865};
8866
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008867/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308868static const
8869struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008870{
8871#ifdef FEATURE_WLAN_CH_AVOID
8872 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308873 .vendor_id = QCA_NL80211_VENDOR_ID,
8874 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008875 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308876#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8877#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8878 {
8879 /* Index = 1*/
8880 .vendor_id = QCA_NL80211_VENDOR_ID,
8881 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8882 },
8883 {
8884 /* Index = 2*/
8885 .vendor_id = QCA_NL80211_VENDOR_ID,
8886 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8887 },
8888 {
8889 /* Index = 3*/
8890 .vendor_id = QCA_NL80211_VENDOR_ID,
8891 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8892 },
8893 {
8894 /* Index = 4*/
8895 .vendor_id = QCA_NL80211_VENDOR_ID,
8896 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8897 },
8898 {
8899 /* Index = 5*/
8900 .vendor_id = QCA_NL80211_VENDOR_ID,
8901 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8902 },
8903 {
8904 /* Index = 6*/
8905 .vendor_id = QCA_NL80211_VENDOR_ID,
8906 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8907 },
8908#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308909#ifdef WLAN_FEATURE_EXTSCAN
8910 {
8911 .vendor_id = QCA_NL80211_VENDOR_ID,
8912 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8913 },
8914 {
8915 .vendor_id = QCA_NL80211_VENDOR_ID,
8916 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8917 },
8918 {
8919 .vendor_id = QCA_NL80211_VENDOR_ID,
8920 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8921 },
8922 {
8923 .vendor_id = QCA_NL80211_VENDOR_ID,
8924 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8925 },
8926 {
8927 .vendor_id = QCA_NL80211_VENDOR_ID,
8928 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8929 },
8930 {
8931 .vendor_id = QCA_NL80211_VENDOR_ID,
8932 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8933 },
8934 {
8935 .vendor_id = QCA_NL80211_VENDOR_ID,
8936 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8937 },
8938 {
8939 .vendor_id = QCA_NL80211_VENDOR_ID,
8940 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8941 },
8942 {
8943 .vendor_id = QCA_NL80211_VENDOR_ID,
8944 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8945 },
8946 {
8947 .vendor_id = QCA_NL80211_VENDOR_ID,
8948 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8949 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308950#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308951/*EXT TDLS*/
8952 {
8953 .vendor_id = QCA_NL80211_VENDOR_ID,
8954 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8955 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308956 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8957 .vendor_id = QCA_NL80211_VENDOR_ID,
8958 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8959 },
8960
Srinivas Dasari030bad32015-02-18 23:23:54 +05308961
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308962 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308963 .vendor_id = QCA_NL80211_VENDOR_ID,
8964 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8965 },
8966
Sushant Kaushik084f6592015-09-10 13:11:56 +05308967 {
8968 .vendor_id = QCA_NL80211_VENDOR_ID,
8969 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308970 },
8971 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8972 .vendor_id = QCA_NL80211_VENDOR_ID,
8973 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8974 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308975 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8976 .vendor_id = QCA_NL80211_VENDOR_ID,
8977 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8978 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308979 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8980 .vendor_id = QCA_NL80211_VENDOR_ID,
8981 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8982 },
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05308983 [QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
8984 .vendor_id = QCA_NL80211_VENDOR_ID,
8985 .subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
8986 },
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +05308987 [QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX] = {
8988 .vendor_id = QCA_NL80211_VENDOR_ID,
8989 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8990 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008991};
8992
Jeff Johnson295189b2012-06-20 16:38:30 -07008993/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308994 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308995 * This function is called by hdd_wlan_startup()
8996 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308997 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008998 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308999struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07009000{
9001 struct wiphy *wiphy;
9002 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309003 /*
9004 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07009005 */
9006 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
9007
9008 if (!wiphy)
9009 {
9010 /* Print error and jump into err label and free the memory */
9011 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
9012 return NULL;
9013 }
9014
Sunil Duttc69bccb2014-05-26 21:30:20 +05309015
Jeff Johnson295189b2012-06-20 16:38:30 -07009016 return wiphy;
9017}
9018
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309019#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
9020 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
9021/**
9022 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
9023 * @wiphy: pointer to wiphy
9024 * @config: pointer to config
9025 *
9026 * Return: None
9027 */
9028static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
9029 hdd_config_t *config)
9030{
9031 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
9032 if (config->max_sched_scan_plan_interval)
9033 wiphy->max_sched_scan_plan_interval =
9034 config->max_sched_scan_plan_interval;
9035 if (config->max_sched_scan_plan_iterations)
9036 wiphy->max_sched_scan_plan_iterations =
9037 config->max_sched_scan_plan_iterations;
9038}
9039#else
9040static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
9041 hdd_config_t *config)
9042{
9043}
9044#endif
9045
Jeff Johnson295189b2012-06-20 16:38:30 -07009046/*
9047 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309048 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07009049 * private ioctl to change the band value
9050 */
9051int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
9052{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309053 int i, j;
9054 eNVChannelEnabledType channelEnabledState;
9055
Jeff Johnsone7245742012-09-05 17:12:55 -07009056 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309057
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309058 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009059 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309060
9061 if (NULL == wiphy->bands[i])
9062 {
9063 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
9064 __func__, i);
9065 continue;
9066 }
9067
9068 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9069 {
9070 struct ieee80211_supported_band *band = wiphy->bands[i];
9071
9072 channelEnabledState = vos_nv_getChannelEnabledState(
9073 band->channels[j].hw_value);
9074
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309075 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309076 {
Abhishek Singh678227a2014-11-04 10:52:38 +05309077 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309078 continue;
9079 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309080 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309081 {
9082 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9083 continue;
9084 }
9085
9086 if (NV_CHANNEL_DISABLE == channelEnabledState ||
9087 NV_CHANNEL_INVALID == channelEnabledState)
9088 {
9089 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9090 }
9091 else if (NV_CHANNEL_DFS == channelEnabledState)
9092 {
9093 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9094 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
9095 }
9096 else
9097 {
9098 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
9099 |IEEE80211_CHAN_RADAR);
9100 }
9101 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009102 }
9103 return 0;
9104}
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309105
9106/**
9107 * hdd_add_channel_switch_support()- Adds Channel Switch flag if supported
9108 * @wiphy: Pointer to the wiphy.
9109 *
9110 * This Function adds Channel Switch support flag, if channel switch is
9111 * supported by kernel.
9112 * Return: void.
9113 */
9114#ifdef CHANNEL_SWITCH_SUPPORTED
9115static inline
9116void hdd_add_channel_switch_support(struct wiphy *wiphy)
9117{
9118 wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
9119 wiphy->max_num_csa_counters = WLAN_HDD_MAX_NUM_CSA_COUNTERS;
9120}
9121#else
9122static inline
9123void hdd_add_channel_switch_support(struct wiphy *wiphy)
9124{
9125}
9126#endif
9127
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +05309128#if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \
9129 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
9130void wlan_hdd_cfg80211_scan_randomization_init(struct wiphy *wiphy)
9131{
9132 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
9133 hdd_config_t *config = hdd_ctx->cfg_ini;
9134
9135 if (config->enableMacSpoofing != MAC_ADDR_SPOOFING_FW_HOST_ENABLE)
9136 return;
9137
9138 wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
9139}
9140#endif
9141
Jeff Johnson295189b2012-06-20 16:38:30 -07009142/*
9143 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309144 * This function is called by hdd_wlan_startup()
9145 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07009146 * This function is used to initialize and register wiphy structure.
9147 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309148int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009149 struct wiphy *wiphy,
9150 hdd_config_t *pCfg
9151 )
9152{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309153 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309154 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9155
Jeff Johnsone7245742012-09-05 17:12:55 -07009156 ENTER();
9157
Jeff Johnson295189b2012-06-20 16:38:30 -07009158 /* Now bind the underlying wlan device with wiphy */
9159 set_wiphy_dev(wiphy, dev);
9160
9161 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009162
Kiet Lam6c583332013-10-14 05:37:09 +05309163#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009164 /* the flag for the other case would be initialzed in
9165 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05309166#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9167 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
9168#else
Amar Singhal0a402232013-10-11 20:57:16 -07009169 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05309170#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05309171#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009172
Amar Singhalfddc28c2013-09-05 13:03:40 -07009173 /* This will disable updating of NL channels from passive to
9174 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309175#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9176 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
9177#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07009178 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309179#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07009180
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309181#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
9182 wiphy->wowlan = &wowlan_support_cfg80211_init;
9183#else
Nachiket Kukade1e1b90e2018-05-10 15:26:13 +05309184 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
9185 WIPHY_WOWLAN_MAGIC_PKT;
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309186 wiphy->wowlan.n_patterns = WOWL_MAX_PTRNS_ALLOWED;
9187 wiphy->wowlan.pattern_min_len = 1;
9188 wiphy->wowlan.pattern_max_len = WOWL_PTRN_MAX_SIZE;
9189#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009190
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009191#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009192 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
9193 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
9194 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07009195 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309196#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05309197 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309198#else
9199 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
9200#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009201#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009202
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009203#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009204 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08009205#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009206 || pCfg->isFastRoamIniFeatureEnabled
9207#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009208#ifdef FEATURE_WLAN_ESE
9209 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009210#endif
9211 )
9212 {
9213 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
9214 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08009215#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009216#ifdef FEATURE_WLAN_TDLS
9217 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
9218 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
9219#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309220#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05309221 if (pCfg->configPNOScanSupport)
9222 {
9223 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
9224 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
9225 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
9226 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
9227 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309228#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009229
Abhishek Singh10d85972015-04-17 10:27:23 +05309230#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9231 wiphy->features |= NL80211_FEATURE_HT_IBSS;
9232#endif
9233
Amar Singhalfddc28c2013-09-05 13:03:40 -07009234#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009235 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
9236 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07009237 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009238 driver need to determine what to do with both
9239 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07009240
9241 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07009242#else
9243 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009244#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009245
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309246 wiphy->max_scan_ssids = MAX_SCAN_SSID;
9247
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05309248 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07009249
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309250 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
9251
Jeff Johnson295189b2012-06-20 16:38:30 -07009252 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05309253 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
9254 | BIT(NL80211_IFTYPE_ADHOC)
9255 | BIT(NL80211_IFTYPE_P2P_CLIENT)
9256 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309257 | BIT(NL80211_IFTYPE_AP)
9258 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07009259
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309260 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009261 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309262#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9263 if( pCfg->enableMCC )
9264 {
9265 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309266 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009267
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309268 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309269 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009270
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309271 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309272 wiphy->iface_combinations = wlan_hdd_iface_combination;
9273 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009274#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309275 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009276
Jeff Johnson295189b2012-06-20 16:38:30 -07009277 /* Before registering we need to update the ht capabilitied based
9278 * on ini values*/
9279 if( !pCfg->ShortGI20MhzEnable )
9280 {
9281 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
9282 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07009283 }
9284
9285 if( !pCfg->ShortGI40MhzEnable )
9286 {
9287 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9288 }
9289
9290 if( !pCfg->nChannelBondingMode5GHz )
9291 {
9292 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9293 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309294 /*
9295 * In case of static linked driver at the time of driver unload,
9296 * module exit doesn't happens. Module cleanup helps in cleaning
9297 * of static memory.
9298 * If driver load happens statically, at the time of driver unload,
9299 * wiphy flags don't get reset because of static memory.
9300 * It's better not to store channel in static memory.
9301 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309302 wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9303 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309304 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309305 if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309306 {
9307 hddLog(VOS_TRACE_LEVEL_ERROR,
9308 FL("Not enough memory to allocate channels"));
9309 return -ENOMEM;
9310 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309311 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309312 &hdd_channels_2_4_GHZ[0],
9313 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009314
Agrawal Ashish97dec502015-11-26 20:20:58 +05309315 if (true == hdd_is_5g_supported(pHddCtx))
9316 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309317 wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9318 wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309319 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309320 if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309321 {
9322 hddLog(VOS_TRACE_LEVEL_ERROR,
9323 FL("Not enough memory to allocate channels"));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309324 vos_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
9325 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
Agrawal Ashish97dec502015-11-26 20:20:58 +05309326 return -ENOMEM;
9327 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309328 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309329 &hdd_channels_5_GHZ[0],
9330 sizeof(hdd_channels_5_GHZ));
9331 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309332
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309333 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309334 {
9335
9336 if (NULL == wiphy->bands[i])
9337 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309338 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309339 __func__, i);
9340 continue;
9341 }
9342
9343 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9344 {
9345 struct ieee80211_supported_band *band = wiphy->bands[i];
9346
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309347 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309348 {
9349 // Enable social channels for P2P
9350 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9351 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9352 else
9353 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9354 continue;
9355 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309356 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309357 {
9358 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9359 continue;
9360 }
9361 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009362 }
9363 /*Initialise the supported cipher suite details*/
9364 wiphy->cipher_suites = hdd_cipher_suites;
9365 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9366
9367 /*signal strength in mBm (100*dBm) */
9368 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9369
9370#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309371 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009372#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009373
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309374 hdd_add_channel_switch_support(wiphy);
Sunil Duttc69bccb2014-05-26 21:30:20 +05309375 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9376 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009377 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9378 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9379
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309380 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
9381
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309382 EXIT();
9383 return 0;
9384}
9385
9386/* In this function we are registering wiphy. */
9387int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9388{
9389 ENTER();
9390 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009391 if (0 > wiphy_register(wiphy))
9392 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309393 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009394 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9395 return -EIO;
9396 }
9397
9398 EXIT();
9399 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309400}
Jeff Johnson295189b2012-06-20 16:38:30 -07009401
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309402/* In this function we are updating channel list when,
9403 regulatory domain is FCC and country code is US.
9404 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9405 As per FCC smart phone is not a indoor device.
9406 GO should not opeate on indoor channels */
9407void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9408{
9409 int j;
9410 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9411 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9412 //Default counrtycode from NV at the time of wiphy initialization.
9413 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9414 &defaultCountryCode[0]))
9415 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009416 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309417 }
9418 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9419 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309420 if (NULL == wiphy->bands[HDD_NL80211_BAND_5GHZ])
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309421 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309422 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[HDD_NL80211_BAND_5GHZ] is NULL",__func__ );
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309423 return;
9424 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309425 for (j = 0; j < wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels; j++)
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309426 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309427 struct ieee80211_supported_band *band = wiphy->bands[HDD_NL80211_BAND_5GHZ];
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309428 // Mark UNII -1 band channel as passive
9429 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9430 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9431 }
9432 }
9433}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309434/* This function registers for all frame which supplicant is interested in */
9435void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009436{
Jeff Johnson295189b2012-06-20 16:38:30 -07009437 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9438 /* Register for all P2P action, public action etc frames */
9439 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009440 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309441 /* Register frame indication call back */
9442 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009443 /* Right now we are registering these frame when driver is getting
9444 initialized. Once we will move to 2.6.37 kernel, in which we have
9445 frame register ops, we will move this code as a part of that */
9446 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309447 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009448 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9449
9450 /* GAS Initial Response */
9451 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9452 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309453
Jeff Johnson295189b2012-06-20 16:38:30 -07009454 /* GAS Comeback Request */
9455 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9456 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9457
9458 /* GAS Comeback Response */
9459 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9460 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9461
9462 /* P2P Public Action */
9463 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309464 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009465 P2P_PUBLIC_ACTION_FRAME_SIZE );
9466
9467 /* P2P Action */
9468 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9469 (v_U8_t*)P2P_ACTION_FRAME,
9470 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009471
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309472 /* WNM BSS Transition Request frame */
9473 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9474 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9475 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009476
9477 /* WNM-Notification */
9478 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9479 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9480 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009481}
9482
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309483void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009484{
Jeff Johnson295189b2012-06-20 16:38:30 -07009485 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9486 /* Register for all P2P action, public action etc frames */
9487 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9488
Jeff Johnsone7245742012-09-05 17:12:55 -07009489 ENTER();
9490
Jeff Johnson295189b2012-06-20 16:38:30 -07009491 /* Right now we are registering these frame when driver is getting
9492 initialized. Once we will move to 2.6.37 kernel, in which we have
9493 frame register ops, we will move this code as a part of that */
9494 /* GAS Initial Request */
9495
9496 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9497 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9498
9499 /* GAS Initial Response */
9500 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9501 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309502
Jeff Johnson295189b2012-06-20 16:38:30 -07009503 /* GAS Comeback Request */
9504 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9505 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9506
9507 /* GAS Comeback Response */
9508 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9509 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9510
9511 /* P2P Public Action */
9512 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309513 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009514 P2P_PUBLIC_ACTION_FRAME_SIZE );
9515
9516 /* P2P Action */
9517 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9518 (v_U8_t*)P2P_ACTION_FRAME,
9519 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009520 /* WNM-Notification */
9521 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9522 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9523 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009524}
9525
9526#ifdef FEATURE_WLAN_WAPI
9527void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309528 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009529{
9530 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9531 tCsrRoamSetKey setKey;
9532 v_BOOL_t isConnected = TRUE;
9533 int status = 0;
9534 v_U32_t roamId= 0xFF;
9535 tANI_U8 *pKeyPtr = NULL;
9536 int n = 0;
9537
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309538 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9539 __func__, hdd_device_modetoString(pAdapter->device_mode),
9540 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009541
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309542 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009543 setKey.keyId = key_index; // Store Key ID
9544 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9545 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9546 setKey.paeRole = 0 ; // the PAE role
9547 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9548 {
9549 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9550 }
9551 else
9552 {
9553 isConnected = hdd_connIsConnected(pHddStaCtx);
9554 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9555 }
9556 setKey.keyLength = key_Len;
9557 pKeyPtr = setKey.Key;
9558 memcpy( pKeyPtr, key, key_Len);
9559
Arif Hussain6d2a3322013-11-17 19:50:10 -08009560 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009561 __func__, key_Len);
9562 for (n = 0 ; n < key_Len; n++)
9563 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9564 __func__,n,setKey.Key[n]);
9565
9566 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9567 if ( isConnected )
9568 {
9569 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9570 pAdapter->sessionId, &setKey, &roamId );
9571 }
9572 if ( status != 0 )
9573 {
9574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9575 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9576 __LINE__, status );
9577 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9578 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309579 /* Need to clear any trace of key value in the memory.
9580 * Thus zero out the memory even though it is local
9581 * variable.
9582 */
9583 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009584}
9585#endif /* FEATURE_WLAN_WAPI*/
9586
9587#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309588int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009589 beacon_data_t **ppBeacon,
9590 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009591#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309592int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009593 beacon_data_t **ppBeacon,
9594 struct cfg80211_beacon_data *params,
9595 int dtim_period)
9596#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309597{
Jeff Johnson295189b2012-06-20 16:38:30 -07009598 int size;
9599 beacon_data_t *beacon = NULL;
9600 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309601 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9602 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009603
Jeff Johnsone7245742012-09-05 17:12:55 -07009604 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009605 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309606 {
9607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9608 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009609 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309610 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009611
9612 old = pAdapter->sessionCtx.ap.beacon;
9613
9614 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309615 {
9616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9617 FL("session(%d) old and new heads points to NULL"),
9618 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009619 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309620 }
9621
9622 if (params->tail && !params->tail_len)
9623 {
9624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9625 FL("tail_len is zero but tail is not NULL"));
9626 return -EINVAL;
9627 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009628
Jeff Johnson295189b2012-06-20 16:38:30 -07009629#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9630 /* Kernel 3.0 is not updating dtim_period for set beacon */
9631 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309632 {
9633 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9634 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009635 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309636 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009637#endif
9638
Kapil Gupta137ef892016-12-13 19:38:00 +05309639 if (params->head)
9640 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009641 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309642 head = params->head;
9643 } else
9644 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009645 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309646 head = old->head;
9647 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009648
Kapil Gupta137ef892016-12-13 19:38:00 +05309649 if (params->tail || !old)
9650 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009651 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309652 tail = params->tail;
9653 } else
9654 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009655 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309656 tail = old->tail;
9657 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009658
Kapil Gupta137ef892016-12-13 19:38:00 +05309659 if (params->proberesp_ies || !old)
9660 {
9661 proberesp_ies_len = params->proberesp_ies_len;
9662 proberesp_ies = params->proberesp_ies;
9663 } else
9664 {
9665 proberesp_ies_len = old->proberesp_ies_len;
9666 proberesp_ies = old->proberesp_ies;
9667 }
9668
9669 if (params->assocresp_ies || !old)
9670 {
9671 assocresp_ies_len = params->assocresp_ies_len;
9672 assocresp_ies = params->assocresp_ies;
9673 } else
9674 {
9675 assocresp_ies_len = old->assocresp_ies_len;
9676 assocresp_ies = old->assocresp_ies;
9677 }
9678
9679 size = sizeof(beacon_data_t) + head_len + tail_len +
9680 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009681
9682 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009683 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309684 {
9685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9686 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009687 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309688 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009689
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009690#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309691 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009692 beacon->dtim_period = params->dtim_period;
9693 else
9694 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009695#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309696 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009697 beacon->dtim_period = dtim_period;
9698 else
9699 beacon->dtim_period = old->dtim_period;
9700#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309701
Jeff Johnson295189b2012-06-20 16:38:30 -07009702 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9703 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309704 beacon->proberesp_ies = beacon->tail + tail_len;
9705 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9706
Jeff Johnson295189b2012-06-20 16:38:30 -07009707 beacon->head_len = head_len;
9708 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309709 beacon->proberesp_ies_len = proberesp_ies_len;
9710 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009711
c_manjee527ecac2017-01-25 12:25:27 +05309712 if (head && head_len)
9713 memcpy(beacon->head, head, head_len);
9714 if (tail && tail_len)
9715 memcpy(beacon->tail, tail, tail_len);
9716 if (proberesp_ies && proberesp_ies_len)
9717 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9718 if (assocresp_ies && assocresp_ies_len)
9719 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009720
9721 *ppBeacon = beacon;
9722
9723 kfree(old);
9724
9725 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009726}
Jeff Johnson295189b2012-06-20 16:38:30 -07009727
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309728v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9729#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9730 const v_U8_t *pIes,
9731#else
9732 v_U8_t *pIes,
9733#endif
9734 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009735{
9736 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309737 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009738 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309739
Jeff Johnson295189b2012-06-20 16:38:30 -07009740 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309741 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009742 elem_id = ptr[0];
9743 elem_len = ptr[1];
9744 left -= 2;
9745 if(elem_len > left)
9746 {
9747 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009748 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009749 eid,elem_len,left);
9750 return NULL;
9751 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309752 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009753 {
9754 return ptr;
9755 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309756
Jeff Johnson295189b2012-06-20 16:38:30 -07009757 left -= elem_len;
9758 ptr += (elem_len + 2);
9759 }
9760 return NULL;
9761}
9762
Jeff Johnson295189b2012-06-20 16:38:30 -07009763/* Check if rate is 11g rate or not */
9764static int wlan_hdd_rate_is_11g(u8 rate)
9765{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009766 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009767 u8 i;
9768 for (i = 0; i < 8; i++)
9769 {
9770 if(rate == gRateArray[i])
9771 return TRUE;
9772 }
9773 return FALSE;
9774}
9775
9776/* Check for 11g rate and set proper 11g only mode */
9777static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9778 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9779{
9780 u8 i, num_rates = pIe[0];
9781
9782 pIe += 1;
9783 for ( i = 0; i < num_rates; i++)
9784 {
9785 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9786 {
9787 /* If rate set have 11g rate than change the mode to 11G */
9788 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9789 if (pIe[i] & BASIC_RATE_MASK)
9790 {
9791 /* If we have 11g rate as basic rate, it means mode
9792 is 11g only mode.
9793 */
9794 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9795 *pCheckRatesfor11g = FALSE;
9796 }
9797 }
9798 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9799 {
9800 *require_ht = TRUE;
9801 }
9802 }
9803 return;
9804}
9805
9806static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9807{
9808 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9809 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9810 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9811 u8 checkRatesfor11g = TRUE;
9812 u8 require_ht = FALSE;
9813 u8 *pIe=NULL;
9814
9815 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9816
9817 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9818 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9819 if (pIe != NULL)
9820 {
9821 pIe += 1;
9822 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9823 &pConfig->SapHw_mode);
9824 }
9825
9826 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9827 WLAN_EID_EXT_SUPP_RATES);
9828 if (pIe != NULL)
9829 {
9830
9831 pIe += 1;
9832 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9833 &pConfig->SapHw_mode);
9834 }
9835
9836 if( pConfig->channel > 14 )
9837 {
9838 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9839 }
9840
9841 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9842 WLAN_EID_HT_CAPABILITY);
9843
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309844 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009845 {
9846 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9847 if(require_ht)
9848 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9849 }
9850}
9851
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309852static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9853 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9854{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009855 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309856 v_U8_t *pIe = NULL;
9857 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9858
9859 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9860 pBeacon->tail, pBeacon->tail_len);
9861
9862 if (pIe)
9863 {
9864 ielen = pIe[1] + 2;
9865 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9866 {
9867 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9868 }
9869 else
9870 {
9871 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9872 return -EINVAL;
9873 }
9874 *total_ielen += ielen;
9875 }
9876 return 0;
9877}
9878
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009879static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9880 v_U8_t *genie, v_U8_t *total_ielen)
9881{
9882 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9883 int left = pBeacon->tail_len;
9884 v_U8_t *ptr = pBeacon->tail;
9885 v_U8_t elem_id, elem_len;
9886 v_U16_t ielen = 0;
9887
9888 if ( NULL == ptr || 0 == left )
9889 return;
9890
9891 while (left >= 2)
9892 {
9893 elem_id = ptr[0];
9894 elem_len = ptr[1];
9895 left -= 2;
9896 if (elem_len > left)
9897 {
9898 hddLog( VOS_TRACE_LEVEL_ERROR,
9899 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9900 elem_id, elem_len, left);
9901 return;
9902 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309903 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009904 {
9905 /* skipping the VSIE's which we don't want to include or
9906 * it will be included by existing code
9907 */
9908 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9909#ifdef WLAN_FEATURE_WFD
9910 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9911#endif
9912 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9913 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9914 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9915 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9916 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9917 {
9918 ielen = ptr[1] + 2;
9919 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9920 {
9921 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9922 *total_ielen += ielen;
9923 }
9924 else
9925 {
9926 hddLog( VOS_TRACE_LEVEL_ERROR,
9927 "IE Length is too big "
9928 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9929 elem_id, elem_len, *total_ielen);
9930 }
9931 }
9932 }
9933
9934 left -= elem_len;
9935 ptr += (elem_len + 2);
9936 }
9937 return;
9938}
9939
Kapil Gupta137ef892016-12-13 19:38:00 +05309940int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009941{
9942 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309943 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009944 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009945 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309946 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009947
9948 genie = vos_mem_malloc(MAX_GENIE_LEN);
9949
9950 if(genie == NULL) {
9951
9952 return -ENOMEM;
9953 }
9954
Kapil Gupta137ef892016-12-13 19:38:00 +05309955 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309956 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9957 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009958 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309959 hddLog(LOGE,
9960 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309961 ret = -EINVAL;
9962 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009963 }
9964
9965#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309966 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9967 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9968 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309969 hddLog(LOGE,
9970 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309971 ret = -EINVAL;
9972 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009973 }
9974#endif
9975
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309976 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9977 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009978 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309979 hddLog(LOGE,
9980 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309981 ret = -EINVAL;
9982 goto done;
9983 }
9984
9985 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9986 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009987 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009988 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009989
9990 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9991 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9992 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9993 {
9994 hddLog(LOGE,
9995 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009996 ret = -EINVAL;
9997 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009998 }
9999
10000 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10001 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10002 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10003 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10004 ==eHAL_STATUS_FAILURE)
10005 {
10006 hddLog(LOGE,
10007 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010008 ret = -EINVAL;
10009 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010010 }
10011
10012 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +053010013 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010014 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010015 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -070010016 u8 probe_rsp_ie_len[3] = {0};
10017 u8 counter = 0;
10018 /* Check Probe Resp Length if it is greater then 255 then Store
10019 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
10020 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
10021 Store More then 255 bytes into One Variable.
10022 */
10023 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
10024 {
10025 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
10026 {
10027 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
10028 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
10029 }
10030 else
10031 {
10032 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
10033 rem_probe_resp_ie_len = 0;
10034 }
10035 }
10036
10037 rem_probe_resp_ie_len = 0;
10038
10039 if (probe_rsp_ie_len[0] > 0)
10040 {
10041 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10042 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +053010043 (tANI_U8*)&pBeacon->
10044 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010045 probe_rsp_ie_len[0], NULL,
10046 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10047 {
10048 hddLog(LOGE,
10049 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010050 ret = -EINVAL;
10051 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010052 }
10053 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10054 }
10055
10056 if (probe_rsp_ie_len[1] > 0)
10057 {
10058 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10059 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +053010060 (tANI_U8*)&pBeacon->
10061 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010062 probe_rsp_ie_len[1], NULL,
10063 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10064 {
10065 hddLog(LOGE,
10066 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010067 ret = -EINVAL;
10068 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010069 }
10070 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10071 }
10072
10073 if (probe_rsp_ie_len[2] > 0)
10074 {
10075 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10076 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +053010077 (tANI_U8*)&pBeacon->
10078 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010079 probe_rsp_ie_len[2], NULL,
10080 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10081 {
10082 hddLog(LOGE,
10083 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010084 ret = -EINVAL;
10085 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010086 }
10087 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10088 }
10089
10090 if (probe_rsp_ie_len[1] == 0 )
10091 {
10092 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10093 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10094 eANI_BOOLEAN_FALSE) )
10095 {
10096 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010097 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010098 }
10099 }
10100
10101 if (probe_rsp_ie_len[2] == 0 )
10102 {
10103 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10104 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10105 eANI_BOOLEAN_FALSE) )
10106 {
10107 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010108 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010109 }
10110 }
10111
10112 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10113 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10114 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10115 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10116 == eHAL_STATUS_FAILURE)
10117 {
10118 hddLog(LOGE,
10119 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010120 ret = -EINVAL;
10121 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010122 }
10123 }
10124 else
10125 {
10126 // Reset WNI_CFG_PROBE_RSP Flags
10127 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
10128
10129 hddLog(VOS_TRACE_LEVEL_INFO,
10130 "%s: No Probe Response IE received in set beacon",
10131 __func__);
10132 }
10133
10134 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +053010135 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010136 {
10137 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +053010138 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
10139 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -070010140 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10141 {
10142 hddLog(LOGE,
10143 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010144 ret = -EINVAL;
10145 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010146 }
10147
10148 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10149 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
10150 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10151 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10152 == eHAL_STATUS_FAILURE)
10153 {
10154 hddLog(LOGE,
10155 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010156 ret = -EINVAL;
10157 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010158 }
10159 }
10160 else
10161 {
10162 hddLog(VOS_TRACE_LEVEL_INFO,
10163 "%s: No Assoc Response IE received in set beacon",
10164 __func__);
10165
10166 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10167 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10168 eANI_BOOLEAN_FALSE) )
10169 {
10170 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010171 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010172 }
10173 }
10174
Jeff Johnsone7245742012-09-05 17:12:55 -070010175done:
Jeff Johnson295189b2012-06-20 16:38:30 -070010176 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010177 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010178}
Jeff Johnson295189b2012-06-20 16:38:30 -070010179
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010180/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010181 * FUNCTION: wlan_hdd_validate_operation_channel
10182 * called by wlan_hdd_cfg80211_start_bss() and
10183 * wlan_hdd_cfg80211_set_channel()
10184 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010185 * channel list.
10186 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -070010187VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010188{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010189
Jeff Johnson295189b2012-06-20 16:38:30 -070010190 v_U32_t num_ch = 0;
10191 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10192 u32 indx = 0;
10193 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010194 v_U8_t fValidChannel = FALSE, count = 0;
10195 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010196
Jeff Johnson295189b2012-06-20 16:38:30 -070010197 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10198
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010199 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010200 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010201 /* Validate the channel */
10202 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010203 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010204 if ( channel == rfChannels[count].channelNum )
10205 {
10206 fValidChannel = TRUE;
10207 break;
10208 }
10209 }
10210 if (fValidChannel != TRUE)
10211 {
10212 hddLog(VOS_TRACE_LEVEL_ERROR,
10213 "%s: Invalid Channel [%d]", __func__, channel);
10214 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010215 }
10216 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010217 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010218 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010219 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10220 valid_ch, &num_ch))
10221 {
10222 hddLog(VOS_TRACE_LEVEL_ERROR,
10223 "%s: failed to get valid channel list", __func__);
10224 return VOS_STATUS_E_FAILURE;
10225 }
10226 for (indx = 0; indx < num_ch; indx++)
10227 {
10228 if (channel == valid_ch[indx])
10229 {
10230 break;
10231 }
10232 }
10233
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010234 if (indx >= num_ch)
10235 {
10236 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10237 {
10238 eCsrBand band;
10239 unsigned int freq;
10240
10241 sme_GetFreqBand(hHal, &band);
10242
10243 if (eCSR_BAND_5G == band)
10244 {
10245#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10246 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10247 {
10248 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010249 HDD_NL80211_BAND_2GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010250 }
10251 else
10252 {
10253 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010254 HDD_NL80211_BAND_5GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010255 }
10256#else
10257 freq = ieee80211_channel_to_frequency(channel);
10258#endif
10259 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
10260 return VOS_STATUS_SUCCESS;
10261 }
10262 }
10263
10264 hddLog(VOS_TRACE_LEVEL_ERROR,
10265 "%s: Invalid Channel [%d]", __func__, channel);
10266 return VOS_STATUS_E_FAILURE;
10267 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010268 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010269
Jeff Johnson295189b2012-06-20 16:38:30 -070010270 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010271
Jeff Johnson295189b2012-06-20 16:38:30 -070010272}
10273
Viral Modi3a32cc52013-02-08 11:14:52 -080010274/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010275 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -080010276 * This function is used to set the channel number
10277 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010278static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -080010279 struct ieee80211_channel *chan,
10280 enum nl80211_channel_type channel_type
10281 )
10282{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010283 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -080010284 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -070010285 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -080010286 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010287 hdd_context_t *pHddCtx;
10288 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010289
10290 ENTER();
10291
10292 if( NULL == dev )
10293 {
10294 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010295 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010296 return -ENODEV;
10297 }
10298 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010299
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010300 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10301 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10302 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010303 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010304 "%s: device_mode = %s (%d) freq = %d", __func__,
10305 hdd_device_modetoString(pAdapter->device_mode),
10306 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010307
10308 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10309 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010310 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010311 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010312 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010313 }
10314
10315 /*
10316 * Do freq to chan conversion
10317 * TODO: for 11a
10318 */
10319
10320 channel = ieee80211_frequency_to_channel(freq);
10321
10322 /* Check freq range */
10323 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10324 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10325 {
10326 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010327 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010328 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10329 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10330 return -EINVAL;
10331 }
10332
10333 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10334
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010335 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10336 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010337 {
10338 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10339 {
10340 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010341 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010342 return -EINVAL;
10343 }
10344 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10345 "%s: set channel to [%d] for device mode =%d",
10346 __func__, channel,pAdapter->device_mode);
10347 }
10348 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010349 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010350 )
10351 {
10352 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10353 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10354 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10355
10356 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10357 {
10358 /* Link is up then return cant set channel*/
10359 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010360 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010361 return -EINVAL;
10362 }
10363
10364 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10365 pHddStaCtx->conn_info.operationChannel = channel;
10366 pRoamProfile->ChannelInfo.ChannelList =
10367 &pHddStaCtx->conn_info.operationChannel;
10368 }
10369 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010370 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010371 )
10372 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010373 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10374 {
10375 if(VOS_STATUS_SUCCESS !=
10376 wlan_hdd_validate_operation_channel(pAdapter,channel))
10377 {
10378 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010379 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010380 return -EINVAL;
10381 }
10382 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10383 }
10384 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010385 {
10386 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10387
10388 /* If auto channel selection is configured as enable/ 1 then ignore
10389 channel set by supplicant
10390 */
10391 if ( cfg_param->apAutoChannelSelection )
10392 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010393 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10394 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010395 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010396 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10397 __func__, hdd_device_modetoString(pAdapter->device_mode),
10398 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010399 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010400 else
10401 {
10402 if(VOS_STATUS_SUCCESS !=
10403 wlan_hdd_validate_operation_channel(pAdapter,channel))
10404 {
10405 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010406 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010407 return -EINVAL;
10408 }
10409 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10410 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010411 }
10412 }
10413 else
10414 {
10415 hddLog(VOS_TRACE_LEVEL_FATAL,
10416 "%s: Invalid device mode failed to set valid channel", __func__);
10417 return -EINVAL;
10418 }
10419 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010420 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010421}
10422
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010423static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10424 struct net_device *dev,
10425 struct ieee80211_channel *chan,
10426 enum nl80211_channel_type channel_type
10427 )
10428{
10429 int ret;
10430
10431 vos_ssr_protect(__func__);
10432 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10433 vos_ssr_unprotect(__func__);
10434
10435 return ret;
10436}
10437
Anurag Chouhan83026002016-12-13 22:46:21 +053010438#ifdef DHCP_SERVER_OFFLOAD
10439void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10440 VOS_STATUS status)
10441{
10442 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10443
10444 ENTER();
10445
10446 if (NULL == adapter)
10447 {
10448 hddLog(VOS_TRACE_LEVEL_ERROR,
10449 "%s: adapter is NULL",__func__);
10450 return;
10451 }
10452
10453 adapter->dhcp_status.dhcp_offload_status = status;
10454 vos_event_set(&adapter->dhcp_status.vos_event);
10455 return;
10456}
10457
10458/**
10459 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10460 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010461 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010462 *
10463 * Return: None
10464 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010465VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10466 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010467{
10468 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10469 sir_dhcp_srv_offload_info dhcp_srv_info;
10470 tANI_U8 num_entries = 0;
10471 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10472 tANI_U8 num;
10473 tANI_U32 temp;
10474 VOS_STATUS ret;
10475
10476 ENTER();
10477
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010478 if (!re_init) {
10479 ret = wlan_hdd_validate_context(hdd_ctx);
10480 if (0 != ret)
10481 return VOS_STATUS_E_INVAL;
10482 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010483
10484 /* Prepare the request to send to SME */
10485 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10486 if (NULL == dhcp_srv_info) {
10487 hddLog(VOS_TRACE_LEVEL_ERROR,
10488 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10489 return VOS_STATUS_E_NOMEM;
10490 }
10491
10492 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10493
10494 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10495 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10496 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10497 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10498 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10499 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10500
10501 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10502 srv_ip,
10503 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010504 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010505 if (num_entries != IPADDR_NUM_ENTRIES) {
10506 hddLog(VOS_TRACE_LEVEL_ERROR,
10507 "%s: incorrect IP address (%s) assigned for DHCP server!",
10508 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10509 vos_mem_free(dhcp_srv_info);
10510 return VOS_STATUS_E_FAILURE;
10511 }
10512
10513 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10514 hddLog(VOS_TRACE_LEVEL_ERROR,
10515 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10516 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10517 vos_mem_free(dhcp_srv_info);
10518 return VOS_STATUS_E_FAILURE;
10519 }
10520
10521 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10522 hddLog(VOS_TRACE_LEVEL_ERROR,
10523 "%s: invalid IP address (%s)! The last field must be less than 100!",
10524 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10525 vos_mem_free(dhcp_srv_info);
10526 return VOS_STATUS_E_FAILURE;
10527 }
10528
10529 for (num = 0; num < num_entries; num++) {
10530 temp = srv_ip[num];
10531 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10532 }
10533
10534 if (eHAL_STATUS_SUCCESS !=
10535 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10536 hddLog(VOS_TRACE_LEVEL_ERROR,
10537 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10538 vos_mem_free(dhcp_srv_info);
10539 return VOS_STATUS_E_FAILURE;
10540 }
10541
10542 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10543 "%s: enable DHCP Server offload successfully!", __func__);
10544
10545 vos_mem_free(dhcp_srv_info);
10546 return 0;
10547}
10548#endif /* DHCP_SERVER_OFFLOAD */
10549
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010550/*
10551 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10552 * @wiphy_chan: wiphy channel number
10553 * @rfChannel: channel hw value
10554 * @disable: Disable/enable the flags
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010555 * @hdd_ctx: The HDD context handler
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010556 *
10557 * Modify wiphy flags and cds state if channel is indoor.
10558 *
10559 * Return: void
10560 */
10561void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010562 v_U32_t rfChannel, bool disable, hdd_context_t *hdd_ctx)
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010563{
10564 v_U32_t channelLoop;
10565 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10566
10567 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10568
10569 if (rfChannels[channelLoop].channelNum == rfChannel) {
10570 channelEnum = (eRfChannels)channelLoop;
10571 break;
10572 }
10573 }
10574
10575 if (INVALID_RF_CHANNEL == channelEnum)
10576 return;
10577
10578 if (disable) {
10579 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10580 wiphy_chan->flags |=
10581 IEEE80211_CHAN_DISABLED;
10582 regChannels[channelEnum].enabled =
10583 NV_CHANNEL_DISABLE;
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010584 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as DISABLE",
10585 channelEnum);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010586 }
10587 } else {
10588 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10589 wiphy_chan->flags &=
10590 ~IEEE80211_CHAN_DISABLED;
10591 /*
10592 * Indoor channels are marked as DFS
10593 * during regulatory processing
10594 */
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010595 if ((wiphy_chan->flags & (IEEE80211_CHAN_RADAR |
10596 IEEE80211_CHAN_PASSIVE_SCAN)) ||
10597 ((hdd_ctx->cfg_ini->indoor_channel_support == false)
10598 && (wiphy_chan->flags &
10599 IEEE80211_CHAN_INDOOR_ONLY))) {
10600 regChannels[channelEnum].enabled = NV_CHANNEL_DFS;
10601 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as DFS",
10602 channelEnum);
10603 } else {
10604 regChannels[channelEnum].enabled =
10605 NV_CHANNEL_ENABLE;
10606 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as ENABLE",
10607 channelEnum);
10608 }
10609 }
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010610
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010611 }
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010612}
10613
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010614void hdd_update_indoor_channel(hdd_context_t *hdd_ctx, bool disable)
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010615{
10616 int band_num;
10617 int chan_num;
10618 v_U32_t rfChannel;
10619 struct ieee80211_channel *wiphy_chan;
10620 struct wiphy *wiphy;
10621
10622 ENTER();
10623 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10624
10625 wiphy = hdd_ctx->wiphy;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010626 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010627
10628 if (wiphy->bands[band_num] == NULL)
10629 continue;
10630
10631 for (chan_num = 0;
10632 chan_num < wiphy->bands[band_num]->n_channels;
10633 chan_num++) {
10634
10635 wiphy_chan =
10636 &(wiphy->bands[band_num]->channels[chan_num]);
10637 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10638
10639 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010640 disable, hdd_ctx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010641 }
10642 }
10643 EXIT();
10644}
10645
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010646int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10647{
Dundi Raviteja49de66b2018-07-27 12:22:57 +053010648 eHalStatus status;
10649 int result = 0;
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010650 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10651 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10652 long ret;
10653 eConnectionState prev_conn_state;
10654 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
10655
10656 ENTER();
10657
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010658 /* Indicate sme of disconnect so that in progress connection or preauth
10659 * can be aborted
10660 */
10661 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10662 pAdapter->sessionId);
10663 pHddCtx->isAmpAllowed = VOS_TRUE;
10664
10665 /* Need to apply spin lock before decreasing active sessions
10666 * as there can be chance for double decrement if context switch
10667 * Calls hdd_DisConnectHandler.
10668 */
10669
10670 prev_conn_state = pHddStaCtx->conn_info.connState;
10671
10672 spin_lock_bh(&pAdapter->lock_for_active_session);
10673 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10674 {
10675 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10676 }
10677 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10678 spin_unlock_bh(&pAdapter->lock_for_active_session);
10679 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
10680
10681 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10682 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10683
10684 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10685
10686 /*
10687 * stop tx queues before deleting STA/BSS context from the firmware.
10688 * tx has to be disabled because the firmware can get busy dropping
10689 * the tx frames after BSS/STA has been deleted and will not send
10690 * back a response resulting in WDI timeout
10691 */
10692 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10693 netif_tx_disable(pAdapter->dev);
10694 netif_carrier_off(pAdapter->dev);
10695
10696 wlan_hdd_check_and_stop_mon(pAdapter, true);
10697
10698 /*issue disconnect*/
10699 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10700 pAdapter->sessionId, reason);
10701 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
10702 prev_conn_state != eConnectionState_Connecting)
10703 {
10704 hddLog(LOG1,
10705 FL("status = %d, already disconnected"), status);
10706 result = 0;
10707 /*
10708 * Wait here instead of returning directly. This will block the
10709 * next connect command and allow processing of the disconnect
10710 * in SME else we might hit some race conditions leading to SME
10711 * and HDD out of sync. As disconnect is already in progress,
10712 * wait here for 1 sec instead of 5 sec.
10713 */
10714 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
10715 goto wait_for_disconnect;
10716 }
10717 /*
10718 * Wait here instead of returning directly, this will block the next
10719 * connect command and allow processing of the scan for ssid and
10720 * the previous connect command in CSR. Else we might hit some
10721 * race conditions leading to SME and HDD out of sync.
10722 */
10723 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10724 {
10725 hddLog(LOG1,
10726 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
10727 }
10728 else if ( 0 != status )
10729 {
10730 hddLog(LOGE,
10731 FL("csrRoamDisconnect failure, returned %d"),
10732 (int)status);
10733 result = -EINVAL;
10734 goto disconnected;
10735 }
10736wait_for_disconnect:
10737 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
10738 msecs_to_jiffies(wait_time));
10739 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
10740 {
10741 hddLog(LOGE,
10742 "%s: Failed to disconnect, timed out", __func__);
10743 result = -ETIMEDOUT;
10744 }
10745disconnected:
10746 hddLog(LOG1,
10747 FL("Set HDD connState to eConnectionState_NotConnected"));
10748 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10749#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
10750 /* Sending disconnect event to userspace for kernel version < 3.11
10751 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
10752 */
10753 hddLog(LOG1, FL("Send disconnected event to userspace"));
10754
10755 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
10756 WLAN_REASON_UNSPECIFIED);
10757#endif
10758
10759 EXIT();
10760 return result;
10761}
10762
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010763void hdd_check_and_disconnect_sta_on_invalid_channel(hdd_context_t *hdd_ctx)
10764{
10765
10766 hdd_adapter_t *sta_adapter;
10767 tANI_U8 sta_chan;
10768
10769 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
10770
10771 if (!sta_chan) {
10772 hddLog(LOG1, FL("STA not connected"));
10773 return;
10774 }
10775
10776 hddLog(LOG1, FL("STA connected on chan %hu"), sta_chan);
10777
10778 if (sme_IsChannelValid(hdd_ctx->hHal, sta_chan)) {
10779 hddLog(LOG1, FL("STA connected on chan %hu and it is valid"),
10780 sta_chan);
10781 return;
10782 }
10783
10784 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
10785
10786 if (!sta_adapter) {
10787 hddLog(LOG1, FL("STA adapter doesn't exist"));
10788 return;
10789 }
10790
10791 hddLog(LOG1, FL("chan %hu not valid, issue disconnect"), sta_chan);
10792 /* Issue Disconnect request */
10793 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10794}
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010795
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010796int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx)
10797{
10798 struct hdd_cache_channels *cache_chann;
10799 struct wiphy *wiphy;
10800 int freq, status, rfChannel;
10801 int i, band_num, channel_num;
10802 struct ieee80211_channel *wiphy_channel;
10803
10804 ENTER();
10805
10806 if (!hdd_ctx) {
10807 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10808 return -EINVAL;
10809 }
10810
10811 wiphy = hdd_ctx->wiphy;
10812
10813 mutex_lock(&hdd_ctx->cache_channel_lock);
10814
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010815 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010816
10817 if (!cache_chann || !cache_chann->num_channels) {
10818 hddLog(VOS_TRACE_LEVEL_INFO,
10819 "%s channel list is NULL or num channels are zero",
10820 __func__);
10821 mutex_unlock(&hdd_ctx->cache_channel_lock);
10822 return -EINVAL;
10823 }
10824
10825 for (i = 0; i < cache_chann->num_channels; i++) {
10826 status = hdd_wlan_get_freq(
10827 cache_chann->channel_info[i].channel_num,
10828 &freq);
10829
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010830 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
10831 band_num++) {
Dundi Raviteja1d019fd2018-09-23 18:18:22 +053010832 if (!wiphy->bands[band_num])
10833 continue;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010834 for (channel_num = 0; channel_num <
10835 wiphy->bands[band_num]->n_channels;
10836 channel_num++) {
10837 wiphy_channel = &(wiphy->bands[band_num]->
10838 channels[channel_num]);
10839 if (wiphy_channel->center_freq == freq) {
10840 rfChannel = wiphy_channel->hw_value;
10841 /*
10842 *Restore the orginal states
10843 *of the channels
10844 */
10845 vos_nv_set_channel_state(
10846 rfChannel,
10847 cache_chann->
10848 channel_info[i].reg_status);
10849 wiphy_channel->flags =
10850 cache_chann->
10851 channel_info[i].wiphy_status;
Ashish Kumar Dhanotiya1cf97dd2019-03-11 16:59:25 +053010852 hddLog(VOS_TRACE_LEVEL_DEBUG,
10853 "Restore channel %d reg_stat %d wiphy_stat 0x%x",
10854 cache_chann->
10855 channel_info[i].channel_num,
10856 cache_chann->
10857 channel_info[i].reg_status,
10858 wiphy_channel->flags);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010859 break;
10860 }
10861 }
10862 if (channel_num < wiphy->bands[band_num]->n_channels)
10863 break;
10864 }
10865 }
10866
10867 mutex_unlock(&hdd_ctx->cache_channel_lock);
10868
10869 status = sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10870 if (status)
10871 hddLog(VOS_TRACE_LEVEL_ERROR, "Can't Restore channel list");
10872 EXIT();
10873
10874 return 0;
10875}
10876
Ashish Kumar Dhanotiya1cf97dd2019-03-11 16:59:25 +053010877int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx)
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010878{
10879 struct hdd_cache_channels *cache_chann;
10880 struct wiphy *wiphy;
10881 int freq, status, rfChannel;
10882 int i, band_num, band_ch_num;
10883 struct ieee80211_channel *wiphy_channel;
10884
10885 if (!hdd_ctx) {
10886 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10887 return -EINVAL;
10888 }
10889
10890 wiphy = hdd_ctx->wiphy;
10891
10892 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010893 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010894
10895 if (!cache_chann || !cache_chann->num_channels) {
10896 hddLog(VOS_TRACE_LEVEL_INFO,
10897 "%s channel list is NULL or num channels are zero",
10898 __func__);
10899 mutex_unlock(&hdd_ctx->cache_channel_lock);
10900 return -EINVAL;
10901 }
10902
10903 for (i = 0; i < cache_chann->num_channels; i++) {
10904 status = hdd_wlan_get_freq(
10905 cache_chann->channel_info[i].channel_num,
10906 &freq);
10907
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010908 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010909 band_num++) {
Dundi Raviteja1d019fd2018-09-23 18:18:22 +053010910 if (!wiphy->bands[band_num])
10911 continue;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010912 for (band_ch_num = 0; band_ch_num <
10913 wiphy->bands[band_num]->n_channels;
10914 band_ch_num++) {
10915 wiphy_channel = &(wiphy->bands[band_num]->
10916 channels[band_ch_num]);
10917 if (wiphy_channel->center_freq == freq) {
10918 rfChannel = wiphy_channel->hw_value;
10919 /*
10920 * Cache the current states of
10921 * the channels
10922 */
10923 cache_chann->
10924 channel_info[i].reg_status =
10925 vos_nv_getChannelEnabledState(
10926 rfChannel);
10927
10928 cache_chann->
10929 channel_info[i].wiphy_status =
10930 wiphy_channel->flags;
10931 hddLog(VOS_TRACE_LEVEL_INFO,
10932 "Disable channel %d reg_stat %d wiphy_stat 0x%x",
10933 cache_chann->
10934 channel_info[i].channel_num,
10935 cache_chann->
10936 channel_info[i].reg_status,
10937 wiphy_channel->flags);
10938
10939 vos_nv_set_channel_state(
10940 rfChannel,
10941 NV_CHANNEL_DISABLE);
10942 wiphy_channel->flags |=
10943 IEEE80211_CHAN_DISABLED;
10944 break;
10945 }
10946 }
10947 if (band_ch_num < wiphy->bands[band_num]->n_channels)
10948 break;
10949 }
10950 }
10951
10952 mutex_unlock(&hdd_ctx->cache_channel_lock);
10953 sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10954 return 0;
10955}
10956
Jeff Johnson295189b2012-06-20 16:38:30 -070010957#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10958static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10959 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010960#else
10961static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10962 struct cfg80211_beacon_data *params,
10963 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010964 enum nl80211_hidden_ssid hidden_ssid,
10965 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010966#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010967{
10968 tsap_Config_t *pConfig;
10969 beacon_data_t *pBeacon = NULL;
10970 struct ieee80211_mgmt *pMgmt_frame;
10971 v_U8_t *pIe=NULL;
10972 v_U16_t capab_info;
10973 eCsrAuthType RSNAuthType;
10974 eCsrEncryptionType RSNEncryptType;
10975 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010976 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010977 tpWLAN_SAPEventCB pSapEventCallback;
10978 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070010979 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010980 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010981 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010982 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070010983 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080010984 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Vignesh Viswanathan36575f82018-06-14 16:52:21 +053010985 hdd_adapter_t *sta_adapter;
Peng Xu2446a892014-09-05 17:21:18 +053010986 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070010987 v_BOOL_t MFPCapable = VOS_FALSE;
10988 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010989 v_BOOL_t sapEnable11AC =
10990 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053010991 u_int16_t prev_rsn_length = 0;
10992
Jeff Johnson295189b2012-06-20 16:38:30 -070010993 ENTER();
10994
Nitesh Shah9b066282017-06-06 18:05:52 +053010995 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Vignesh Viswanathan36575f82018-06-14 16:52:21 +053010996
10997 /*
10998 * For STA+SAP concurrency support from GUI, first STA connection gets
10999 * triggered and while it is in progress, SAP start also comes up.
11000 * Once STA association is successful, STA connect event is sent to
11001 * kernel which gets queued in kernel workqueue and supplicant won't
11002 * process M1 received from AP and send M2 until this NL80211_CONNECT
11003 * event is received. Workqueue is not scheduled as RTNL lock is already
11004 * taken by hostapd thread which has issued start_bss command to driver.
11005 * Driver cannot complete start_bss as the pending command at the head
11006 * of the SME command pending list is hw_mode_update for STA session
11007 * which cannot be processed as SME is in WAITforKey state for STA
11008 * interface. The start_bss command for SAP interface is queued behind
11009 * the hw_mode_update command and so it cannot be processed until
11010 * hw_mode_update command is processed. This is causing a deadlock so
11011 * disconnect the STA interface first if connection or key exchange is
11012 * in progress and then start SAP interface.
11013 */
11014 sta_adapter = hdd_get_sta_connection_in_progress(pHddCtx);
11015 if (sta_adapter) {
11016 hddLog(LOG1, FL("Disconnecting STA with session id: %d"),
11017 sta_adapter->sessionId);
11018 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
11019 }
11020
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011021 iniConfig = pHddCtx->cfg_ini;
11022
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011023 /* Mark the indoor channel (passive) to disable */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011024 if (iniConfig->disable_indoor_channel &&
11025 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011026 hdd_update_indoor_channel(pHddCtx, true);
11027
11028 if (!VOS_IS_STATUS_SUCCESS(
11029 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
11030 hdd_update_indoor_channel(pHddCtx, false);
11031 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
11032 FL("Can't start BSS: update channel list failed"));
Bala Venkatesh5c06a252018-07-12 16:08:04 +053011033 ret = eHAL_STATUS_FAILURE;
11034 goto tdls_enable;
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011035 }
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053011036
11037 /* check if STA is on indoor channel */
11038 if (hdd_is_sta_sap_scc_allowed_on_dfs_chan(pHddCtx))
11039 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011040 }
11041
Jeff Johnson295189b2012-06-20 16:38:30 -070011042 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
11043
11044 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
11045
11046 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
11047
11048 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
11049
11050 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
11051
11052 //channel is already set in the set_channel Call back
11053 //pConfig->channel = pCommitConfig->channel;
11054
11055 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011056 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070011057 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
11058
11059 pConfig->dtim_period = pBeacon->dtim_period;
11060
Arif Hussain6d2a3322013-11-17 19:50:10 -080011061 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070011062 pConfig->dtim_period);
11063
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080011064 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070011065 {
11066 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011067 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053011068 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
11069 {
11070 tANI_BOOLEAN restartNeeded;
11071 pConfig->ieee80211d = 1;
11072 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
11073 sme_setRegInfo(hHal, pConfig->countryCode);
11074 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
11075 }
11076 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070011077 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070011078 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070011079 pConfig->ieee80211d = 1;
11080 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
11081 sme_setRegInfo(hHal, pConfig->countryCode);
11082 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070011083 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011084 else
11085 {
11086 pConfig->ieee80211d = 0;
11087 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011088 /*
11089 * If auto channel is configured i.e. channel is 0,
11090 * so skip channel validation.
11091 */
11092 if( AUTO_CHANNEL_SELECT != pConfig->channel )
11093 {
11094 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
11095 {
11096 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011097 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011098 ret = -EINVAL;
11099 goto error;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011100 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011101 pConfig->user_config_channel = pConfig->channel;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011102 }
11103 else
11104 {
11105 if(1 != pHddCtx->is_dynamic_channel_range_set)
11106 {
11107 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
11108 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
11109 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
11110 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011111 pHddCtx->is_dynamic_channel_range_set = 0;
11112 pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011113 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011114 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011115 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011116 {
11117 pConfig->ieee80211d = 0;
11118 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011119
11120#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11121 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11122 pConfig->authType = eSAP_OPEN_SYSTEM;
11123 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11124 pConfig->authType = eSAP_SHARED_KEY;
11125 else
11126 pConfig->authType = eSAP_AUTO_SWITCH;
11127#else
11128 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11129 pConfig->authType = eSAP_OPEN_SYSTEM;
11130 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11131 pConfig->authType = eSAP_SHARED_KEY;
11132 else
11133 pConfig->authType = eSAP_AUTO_SWITCH;
11134#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011135
11136 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011137
11138 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070011139 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053011140#ifdef SAP_AUTH_OFFLOAD
11141 /* In case of sap offload, hostapd.conf is configuted with open mode and
11142 * security is configured from ini file. Due to open mode in hostapd.conf
11143 * privacy bit is set to false which will result in not sending,
11144 * data packets as encrypted.
11145 * If enable_sap_auth_offload is enabled in ini and
11146 * sap_auth_offload_sec_type is type of WPA2-PSK,
11147 * driver will set privacy bit to 1.
11148 */
11149 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
11150 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
11151 pConfig->privacy = VOS_TRUE;
11152#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011153
11154 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
11155
11156 /*Set wps station to configured*/
11157 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
11158
11159 if(pIe)
11160 {
11161 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
11162 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011163 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011164 ret = -EINVAL;
11165 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011166 }
11167 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
11168 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070011169 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070011170 /* Check 15 bit of WPS IE as it contain information for wps state
11171 * WPS state
11172 */
11173 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
11174 {
11175 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
11176 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
11177 {
11178 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
11179 }
11180 }
11181 }
11182 else
11183 {
11184 pConfig->wps_state = SAP_WPS_DISABLED;
11185 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011186 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070011187
c_hpothufe599e92014-06-16 11:38:55 +053011188 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11189 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11190 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
11191 eCSR_ENCRYPT_TYPE_NONE;
11192
Jeff Johnson295189b2012-06-20 16:38:30 -070011193 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053011194 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011195 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011196 WLAN_EID_RSN);
11197 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011198 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011199 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011200 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11201 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11202 pConfig->RSNWPAReqIELength);
11203 else
11204 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11205 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011206 /* The actual processing may eventually be more extensive than
11207 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070011208 * by the app.
11209 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011210 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011211 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11212 &RSNEncryptType,
11213 &mcRSNEncryptType,
11214 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011215 &MFPCapable,
11216 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011217 pConfig->RSNWPAReqIE[1]+2,
11218 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011219
11220 if( VOS_STATUS_SUCCESS == status )
11221 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011222 /* Now copy over all the security attributes you have
11223 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011224 * */
11225 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11226 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11227 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11228 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011229 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011230 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011231 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11232 }
11233 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011234
Jeff Johnson295189b2012-06-20 16:38:30 -070011235 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11236 pBeacon->tail, pBeacon->tail_len);
11237
11238 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
11239 {
Kapil Gupta137ef892016-12-13 19:38:00 +053011240 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011241 {
11242 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053011243 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070011244 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011245 if (pConfig->RSNWPAReqIELength <=
11246 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
11247 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
11248 pIe[1] + 2);
11249 else
11250 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11251 pConfig->RSNWPAReqIELength);
11252
Jeff Johnson295189b2012-06-20 16:38:30 -070011253 }
11254 else
11255 {
11256 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011257 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11258 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11259 pConfig->RSNWPAReqIELength);
11260 else
11261 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11262 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011263 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011264 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11265 &RSNEncryptType,
11266 &mcRSNEncryptType,
11267 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011268 &MFPCapable,
11269 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011270 pConfig->RSNWPAReqIE[1]+2,
11271 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011272
11273 if( VOS_STATUS_SUCCESS == status )
11274 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011275 /* Now copy over all the security attributes you have
11276 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011277 * */
11278 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11279 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11280 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11281 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011282 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011283 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011284 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11285 }
11286 }
11287 }
11288
Kapil Gupta137ef892016-12-13 19:38:00 +053011289 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070011290 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011291 ret = -EINVAL;
11292 goto error;
Jeff Johnson4416a782013-03-25 14:17:50 -070011293 }
11294
Jeff Johnson295189b2012-06-20 16:38:30 -070011295 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
11296
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011297#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011298 if (params->ssid != NULL)
11299 {
11300 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
11301 pConfig->SSIDinfo.ssid.length = params->ssid_len;
11302 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11303 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11304 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011305#else
11306 if (ssid != NULL)
11307 {
11308 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
11309 pConfig->SSIDinfo.ssid.length = ssid_len;
11310 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11311 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11312 }
11313#endif
11314
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011315 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070011316 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011317
Jeff Johnson295189b2012-06-20 16:38:30 -070011318 /* default value */
11319 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
11320 pConfig->num_accept_mac = 0;
11321 pConfig->num_deny_mac = 0;
11322
11323 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11324 pBeacon->tail, pBeacon->tail_len);
11325
11326 /* pIe for black list is following form:
11327 type : 1 byte
11328 length : 1 byte
11329 OUI : 4 bytes
11330 acl type : 1 byte
11331 no of mac addr in black list: 1 byte
11332 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011333 */
11334 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011335 {
11336 pConfig->SapMacaddr_acl = pIe[6];
11337 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011338 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011339 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011340 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
11341 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011342 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11343 for (i = 0; i < pConfig->num_deny_mac; i++)
11344 {
11345 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11346 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011347 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011348 }
11349 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11350 pBeacon->tail, pBeacon->tail_len);
11351
11352 /* pIe for white list is following form:
11353 type : 1 byte
11354 length : 1 byte
11355 OUI : 4 bytes
11356 acl type : 1 byte
11357 no of mac addr in white list: 1 byte
11358 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011359 */
11360 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011361 {
11362 pConfig->SapMacaddr_acl = pIe[6];
11363 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011364 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011365 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011366 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
11367 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011368 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11369 for (i = 0; i < pConfig->num_accept_mac; i++)
11370 {
11371 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11372 acl_entry++;
11373 }
11374 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011375
Jeff Johnson295189b2012-06-20 16:38:30 -070011376 wlan_hdd_set_sapHwmode(pHostapdAdapter);
11377
Jeff Johnsone7245742012-09-05 17:12:55 -070011378#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011379 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011380 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
11381 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053011382 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
11383 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011384 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
11385 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011386 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
11387 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070011388 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011389 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070011390 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011391 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011392
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011393 /* If ACS disable and selected channel <= 14
11394 * OR
11395 * ACS enabled and ACS operating band is choosen as 2.4
11396 * AND
11397 * VHT in 2.4G Disabled
11398 * THEN
11399 * Fallback to 11N mode
11400 */
11401 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
11402 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053011403 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011404 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011405 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011406 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
11407 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011408 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
11409 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011410 }
11411#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011412
Jeff Johnson295189b2012-06-20 16:38:30 -070011413 // ht_capab is not what the name conveys,this is used for protection bitmap
11414 pConfig->ht_capab =
11415 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
11416
Kapil Gupta137ef892016-12-13 19:38:00 +053011417 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070011418 {
11419 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011420 ret = -EINVAL;
11421 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011422 }
11423
11424 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011425 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070011426 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
11427 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011428 pConfig->obssProtEnabled =
11429 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070011430
Chet Lanctot8cecea22014-02-11 19:09:36 -080011431#ifdef WLAN_FEATURE_11W
11432 pConfig->mfpCapable = MFPCapable;
11433 pConfig->mfpRequired = MFPRequired;
11434 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
11435 pConfig->mfpCapable, pConfig->mfpRequired);
11436#endif
11437
Arif Hussain6d2a3322013-11-17 19:50:10 -080011438 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070011439 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011440 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
11441 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
11442 (int)pConfig->channel);
11443 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
11444 pConfig->SapHw_mode, pConfig->privacy,
11445 pConfig->authType);
11446 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
11447 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
11448 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
11449 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070011450
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011451 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070011452 {
11453 //Bss already started. just return.
11454 //TODO Probably it should update some beacon params.
11455 hddLog( LOGE, "Bss Already started...Ignore the request");
11456 EXIT();
11457 return 0;
11458 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011459
Agarwal Ashish51325b52014-06-16 16:50:49 +053011460 if (vos_max_concurrent_connections_reached()) {
11461 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011462 ret = -EINVAL;
11463 goto error;
Agarwal Ashish51325b52014-06-16 16:50:49 +053011464 }
11465
Jeff Johnson295189b2012-06-20 16:38:30 -070011466 pConfig->persona = pHostapdAdapter->device_mode;
11467
Peng Xu2446a892014-09-05 17:21:18 +053011468 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
11469 if ( NULL != psmeConfig)
11470 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011471 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053011472 sme_GetConfigParam(hHal, psmeConfig);
11473 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011474#ifdef WLAN_FEATURE_AP_HT40_24G
11475 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11476 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
11477 && pHddCtx->cfg_ini->apHT40_24GEnabled)
11478 {
11479 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
11480 sme_UpdateConfig (hHal, psmeConfig);
11481 }
11482#endif
Peng Xu2446a892014-09-05 17:21:18 +053011483 vos_mem_free(psmeConfig);
11484 }
Peng Xuafc34e32014-09-25 13:23:55 +053011485 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053011486
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011487 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -070011488 pSapEventCallback = hdd_hostapd_SAPEventCB;
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011489
11490 vos_event_reset(&pHostapdState->vosEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -070011491 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
11492 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
11493 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011494 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011495 ret = -EINVAL;
11496 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011497 }
11498
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011499 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070011500 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
11501
11502 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011503
Jeff Johnson295189b2012-06-20 16:38:30 -070011504 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011505 {
11506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011507 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070011508 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011509 VOS_ASSERT(0);
11510 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011511
Jeff Johnson295189b2012-06-20 16:38:30 -070011512 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053011513 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
11514 VOS_STATUS_SUCCESS)
11515 {
11516 hddLog(LOGE,FL("Fail to get Softap sessionID"));
11517 VOS_ASSERT(0);
11518 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053011519 /* Initialize WMM configuation */
11520 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011521 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011522
Anurag Chouhan83026002016-12-13 22:46:21 +053011523#ifdef DHCP_SERVER_OFFLOAD
11524 /* set dhcp server offload */
11525 if (iniConfig->enable_dhcp_srv_offload &&
11526 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011527 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053011528 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053011529 if (!VOS_IS_STATUS_SUCCESS(status))
11530 {
11531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11532 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011533 vos_event_reset(&pHostapdState->vosEvent);
11534 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11535 status = vos_wait_single_event(&pHostapdState->vosEvent,
11536 10000);
11537 if (!VOS_IS_STATUS_SUCCESS(status)) {
11538 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011539 ret = -EINVAL;
11540 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011541 }
11542 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011543 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011544 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
11545 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
11546 {
11547 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11548 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
11549 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011550 vos_event_reset(&pHostapdState->vosEvent);
11551 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11552 status = vos_wait_single_event(&pHostapdState->vosEvent,
11553 10000);
11554 if (!VOS_IS_STATUS_SUCCESS(status)) {
11555 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011556 ret = -EINVAL;
11557 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011558 }
11559 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011560 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011561#ifdef MDNS_OFFLOAD
11562 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011563 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011564 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
11565 if (VOS_IS_STATUS_SUCCESS(status))
11566 {
11567 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11568 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011569 vos_event_reset(&pHostapdState->vosEvent);
11570 if (VOS_STATUS_SUCCESS ==
11571 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11572 status = vos_wait_single_event(&pHostapdState->vosEvent,
11573 10000);
11574 if (!VOS_IS_STATUS_SUCCESS(status)) {
11575 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011576 ret = -EINVAL;
11577 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011578 }
11579 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011580 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011581 status = vos_wait_single_event(&pHostapdAdapter->
11582 mdns_status.vos_event, 2000);
11583 if (!VOS_IS_STATUS_SUCCESS(status) ||
11584 pHostapdAdapter->mdns_status.mdns_enable_status ||
11585 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
11586 pHostapdAdapter->mdns_status.mdns_resp_status)
11587 {
11588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11589 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
11590 pHostapdAdapter->mdns_status.mdns_enable_status,
11591 pHostapdAdapter->mdns_status.mdns_fqdn_status,
11592 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011593 vos_event_reset(&pHostapdState->vosEvent);
11594 if (VOS_STATUS_SUCCESS ==
11595 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11596 status = vos_wait_single_event(&pHostapdState->vosEvent,
11597 10000);
11598 if (!VOS_IS_STATUS_SUCCESS(status)) {
11599 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011600 ret = -EINVAL;
11601 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011602 }
11603 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011604 }
11605 }
11606#endif /* MDNS_OFFLOAD */
11607 } else {
11608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11609 ("DHCP Disabled ini %d, FW %d"),
11610 iniConfig->enable_dhcp_srv_offload,
11611 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053011612 }
11613#endif /* DHCP_SERVER_OFFLOAD */
11614
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011615#ifdef WLAN_FEATURE_P2P_DEBUG
11616 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
11617 {
11618 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
11619 {
11620 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11621 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011622 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011623 }
11624 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
11625 {
11626 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11627 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011628 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011629 }
11630 }
11631#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053011632 /* Check and restart SAP if it is on Unsafe channel */
11633 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011634
Jeff Johnson295189b2012-06-20 16:38:30 -070011635 pHostapdState->bCommit = TRUE;
11636 EXIT();
11637
11638 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011639error:
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011640 /* Revert the indoor to passive marking if START BSS fails */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011641 if (iniConfig->disable_indoor_channel &&
11642 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011643 hdd_update_indoor_channel(pHddCtx, false);
11644 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
11645 }
11646
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011647 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
Bala Venkatesh5c06a252018-07-12 16:08:04 +053011648
11649tdls_enable:
11650 if (ret != eHAL_STATUS_SUCCESS)
11651 wlan_hdd_tdls_reenable(pHddCtx);
11652
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011653 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011654}
11655
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011656#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011657static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011658 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011659 struct beacon_parameters *params)
11660{
11661 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011662 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011663 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011664
11665 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011666
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011667 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11668 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11669 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011670 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11671 hdd_device_modetoString(pAdapter->device_mode),
11672 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011673
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011674 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11675 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011676 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011677 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011678 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011679 }
11680
Agarwal Ashish51325b52014-06-16 16:50:49 +053011681 if (vos_max_concurrent_connections_reached()) {
11682 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11683 return -EINVAL;
11684 }
11685
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011686 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011687 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011688 )
11689 {
11690 beacon_data_t *old,*new;
11691
11692 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011693
Jeff Johnson295189b2012-06-20 16:38:30 -070011694 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011695 {
11696 hddLog(VOS_TRACE_LEVEL_WARN,
11697 FL("already beacon info added to session(%d)"),
11698 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011699 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011700 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011701
11702 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11703
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011704 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011705 {
11706 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011707 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011708 return -EINVAL;
11709 }
11710
11711 pAdapter->sessionCtx.ap.beacon = new;
11712
11713 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11714 }
11715
11716 EXIT();
11717 return status;
11718}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011719
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011720static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11721 struct net_device *dev,
11722 struct beacon_parameters *params)
11723{
11724 int ret;
11725
11726 vos_ssr_protect(__func__);
11727 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11728 vos_ssr_unprotect(__func__);
11729
11730 return ret;
11731}
11732
11733static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011734 struct net_device *dev,
11735 struct beacon_parameters *params)
11736{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011737 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011738 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11739 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011740 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011741
11742 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011743
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011744 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11745 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11746 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11747 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11748 __func__, hdd_device_modetoString(pAdapter->device_mode),
11749 pAdapter->device_mode);
11750
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011751 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11752 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011753 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011754 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011755 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011756 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011757
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011758 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011759 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011760 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011761 {
11762 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011763
Jeff Johnson295189b2012-06-20 16:38:30 -070011764 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011765
Jeff Johnson295189b2012-06-20 16:38:30 -070011766 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011767 {
11768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11769 FL("session(%d) old and new heads points to NULL"),
11770 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011771 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011772 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011773
11774 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11775
11776 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011777 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011778 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011779 return -EINVAL;
11780 }
11781
11782 pAdapter->sessionCtx.ap.beacon = new;
11783
11784 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11785 }
11786
11787 EXIT();
11788 return status;
11789}
11790
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011791static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11792 struct net_device *dev,
11793 struct beacon_parameters *params)
11794{
11795 int ret;
11796
11797 vos_ssr_protect(__func__);
11798 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11799 vos_ssr_unprotect(__func__);
11800
11801 return ret;
11802}
11803
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011804#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11805
11806#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011807static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011808 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011809#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011810static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011811 struct net_device *dev)
11812#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011813{
11814 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Vignesh Viswanathan5caacc22018-06-14 17:14:20 +053011815 hdd_adapter_t *staAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011816 hdd_context_t *pHddCtx = NULL;
11817 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011818 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011819 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011820
11821 ENTER();
11822
11823 if (NULL == pAdapter)
11824 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011826 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011827 return -ENODEV;
11828 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011829
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011830 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11831 TRACE_CODE_HDD_CFG80211_STOP_AP,
11832 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011833 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11834 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011835 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011836 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011837 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011838 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011839
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011840 pScanInfo = &pHddCtx->scan_info;
11841
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011842 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11843 __func__, hdd_device_modetoString(pAdapter->device_mode),
11844 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011845
Vignesh Viswanathan5caacc22018-06-14 17:14:20 +053011846 /*
11847 * if a sta connection is in progress in another adapter, disconnect
11848 * the sta and complete the sap operation. sta will reconnect
11849 * after sap stop is done.
11850 */
11851 staAdapter = hdd_get_sta_connection_in_progress(pHddCtx);
11852 if (staAdapter) {
11853 hddLog(LOG1, FL("disconnecting sta with session id: %d"),
11854 staAdapter->sessionId);
11855 wlan_hdd_disconnect(staAdapter, eCSR_DISCONNECT_REASON_DEAUTH);
11856 }
11857
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011858 ret = wlan_hdd_scan_abort(pAdapter);
11859
Girish Gowli4bf7a632014-06-12 13:42:11 +053011860 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011861 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011862 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11863 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011864
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011865 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011866 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11868 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011869
Jeff Johnsone7245742012-09-05 17:12:55 -070011870 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011871 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011872 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011873 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011874 }
11875
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011876 /* Delete all associated STAs before stopping AP/P2P GO */
11877 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011878 hdd_hostapd_stop(dev);
11879
Jeff Johnson295189b2012-06-20 16:38:30 -070011880 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011881 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011882 )
11883 {
11884 beacon_data_t *old;
11885
11886 old = pAdapter->sessionCtx.ap.beacon;
11887
11888 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011889 {
11890 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11891 FL("session(%d) beacon data points to NULL"),
11892 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011893 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011894 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011895
Jeff Johnson295189b2012-06-20 16:38:30 -070011896 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011897
11898 mutex_lock(&pHddCtx->sap_lock);
11899 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11900 {
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011901 hdd_hostapd_state_t *pHostapdState =
11902 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11903
Abhishek Singh10e17cf2018-03-12 14:34:22 +053011904 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
11905 hdd_wait_for_ecsa_complete(pHddCtx);
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011906 vos_event_reset(&pHostapdState->vosEvent);
11907
Jeff Johnson4416a782013-03-25 14:17:50 -070011908 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011909 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011910 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11911
11912 if (!VOS_IS_STATUS_SUCCESS(status))
11913 {
11914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011915 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011916 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011917 }
11918 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011919 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011920 /* BSS stopped, clear the active sessions for this device mode */
11921 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011922 }
11923 mutex_unlock(&pHddCtx->sap_lock);
11924
11925 if(status != VOS_STATUS_SUCCESS)
11926 {
11927 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011928 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011929 return -EINVAL;
11930 }
11931
Jeff Johnson4416a782013-03-25 14:17:50 -070011932 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011933 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11934 ==eHAL_STATUS_FAILURE)
11935 {
11936 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011937 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011938 }
11939
Jeff Johnson4416a782013-03-25 14:17:50 -070011940 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011941 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11942 eANI_BOOLEAN_FALSE) )
11943 {
11944 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011945 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011946 }
11947
11948 // Reset WNI_CFG_PROBE_RSP Flags
11949 wlan_hdd_reset_prob_rspies(pAdapter);
11950
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011951 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11952
Jeff Johnson295189b2012-06-20 16:38:30 -070011953 pAdapter->sessionCtx.ap.beacon = NULL;
11954 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011955#ifdef WLAN_FEATURE_P2P_DEBUG
11956 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11957 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11958 {
11959 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11960 "GO got removed");
11961 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11962 }
11963#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011964 }
11965 EXIT();
11966 return status;
11967}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011968
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011969#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11970static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
11971 struct net_device *dev)
11972{
11973 int ret;
11974
11975 vos_ssr_protect(__func__);
11976 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
11977 vos_ssr_unprotect(__func__);
11978
11979 return ret;
11980}
11981#else
11982static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
11983 struct net_device *dev)
11984{
11985 int ret;
11986
11987 vos_ssr_protect(__func__);
11988 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
11989 vos_ssr_unprotect(__func__);
11990
11991 return ret;
11992}
11993#endif
11994
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011995#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
11996
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011997static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011998 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011999 struct cfg80211_ap_settings *params)
12000{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012001 hdd_adapter_t *pAdapter;
12002 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012003 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012004
12005 ENTER();
12006
Girish Gowlib143d7a2015-02-18 19:39:55 +053012007 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012008 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053012010 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012011 return -ENODEV;
12012 }
12013
12014 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12015 if (NULL == pAdapter)
12016 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012017 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012018 "%s: HDD adapter is Null", __func__);
12019 return -ENODEV;
12020 }
12021
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012022 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12023 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
12024 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012025 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
12026 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012027 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012028 "%s: HDD adapter magic is invalid", __func__);
12029 return -ENODEV;
12030 }
12031
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053012032 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
12033
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012034 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012035 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012036 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012037 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012038 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012039 }
12040
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012041 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
12042 __func__, hdd_device_modetoString(pAdapter->device_mode),
12043 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012044
12045 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012046 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012047 )
12048 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012049 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012050
12051 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012052
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012053 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012054 {
12055 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12056 FL("already beacon info added to session(%d)"),
12057 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012058 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012059 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012060
Girish Gowlib143d7a2015-02-18 19:39:55 +053012061#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
12062 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12063 &new,
12064 &params->beacon);
12065#else
12066 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12067 &new,
12068 &params->beacon,
12069 params->dtim_period);
12070#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012071
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012072 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012073 {
12074 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012075 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012076 return -EINVAL;
12077 }
12078 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080012079#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070012080 wlan_hdd_cfg80211_set_channel(wiphy, dev,
12081#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
12082 params->channel, params->channel_type);
12083#else
12084 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
12085#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080012086#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012087 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012088 params->ssid_len, params->hidden_ssid,
12089 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012090 }
12091
12092 EXIT();
12093 return status;
12094}
12095
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012096static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
12097 struct net_device *dev,
12098 struct cfg80211_ap_settings *params)
12099{
12100 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012101
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012102 vos_ssr_protect(__func__);
12103 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
12104 vos_ssr_unprotect(__func__);
12105
12106 return ret;
12107}
12108
12109static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012110 struct net_device *dev,
12111 struct cfg80211_beacon_data *params)
12112{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012113 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012114 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012115 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012116
12117 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012118
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012119 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12120 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
12121 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080012122 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012123 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012124
12125 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12126 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012127 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012128 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012129 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012130 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012131
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012132 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012133 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012134 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012135 {
12136 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012137
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012138 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012139
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012140 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012141 {
12142 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12143 FL("session(%d) beacon data points to NULL"),
12144 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012145 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012146 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012147
12148 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
12149
12150 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012151 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012152 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012153 return -EINVAL;
12154 }
12155
12156 pAdapter->sessionCtx.ap.beacon = new;
12157
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012158 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
12159 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012160 }
12161
12162 EXIT();
12163 return status;
12164}
12165
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012166static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
12167 struct net_device *dev,
12168 struct cfg80211_beacon_data *params)
12169{
12170 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012171
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012172 vos_ssr_protect(__func__);
12173 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
12174 vos_ssr_unprotect(__func__);
12175
12176 return ret;
12177}
12178
12179#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070012180
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012181static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012182 struct net_device *dev,
12183 struct bss_parameters *params)
12184{
12185 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012186 hdd_context_t *pHddCtx;
12187 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012188
12189 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012190
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012191 if (NULL == pAdapter)
12192 {
12193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12194 "%s: HDD adapter is Null", __func__);
12195 return -ENODEV;
12196 }
12197 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012198 ret = wlan_hdd_validate_context(pHddCtx);
12199 if (0 != ret)
12200 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012201 return ret;
12202 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012203 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12204 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
12205 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012206 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12207 __func__, hdd_device_modetoString(pAdapter->device_mode),
12208 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012209
12210 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012211 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012212 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012213 {
12214 /* ap_isolate == -1 means that in change bss, upper layer doesn't
12215 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012216 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070012217 {
12218 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012219 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012220 }
12221
12222 EXIT();
12223 return 0;
12224}
12225
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012226static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
12227 struct net_device *dev,
12228 struct bss_parameters *params)
12229{
12230 int ret;
12231
12232 vos_ssr_protect(__func__);
12233 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
12234 vos_ssr_unprotect(__func__);
12235
12236 return ret;
12237}
Kiet Lam10841362013-11-01 11:36:50 +053012238/* FUNCTION: wlan_hdd_change_country_code_cd
12239* to wait for contry code completion
12240*/
12241void* wlan_hdd_change_country_code_cb(void *pAdapter)
12242{
12243 hdd_adapter_t *call_back_pAdapter = pAdapter;
12244 complete(&call_back_pAdapter->change_country_code);
12245 return NULL;
12246}
12247
Jeff Johnson295189b2012-06-20 16:38:30 -070012248/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012249 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070012250 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
12251 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012252int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012253 struct net_device *ndev,
12254 enum nl80211_iftype type,
12255 u32 *flags,
12256 struct vif_params *params
12257 )
12258{
12259 struct wireless_dev *wdev;
12260 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012261 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012262 tCsrRoamProfile *pRoamProfile = NULL;
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012263 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012264 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012265 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012266 eMib_dot11DesiredBssType connectedBssType;
12267 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012268 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012269
12270 ENTER();
12271
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012272 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012273 {
12274 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12275 "%s: Adapter context is null", __func__);
12276 return VOS_STATUS_E_FAILURE;
12277 }
12278
12279 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12280 if (!pHddCtx)
12281 {
12282 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12283 "%s: HDD context is null", __func__);
12284 return VOS_STATUS_E_FAILURE;
12285 }
12286
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012287 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12288 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
12289 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012290 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012291 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012292 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012293 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012294 }
12295
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012296 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12297 __func__, hdd_device_modetoString(pAdapter->device_mode),
12298 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012299
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012300 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
12301 hddLog(VOS_TRACE_LEVEL_FATAL,
12302 "%s: STA + MON is in progress, cannot change interface",
12303 __func__);
12304 }
12305
Agarwal Ashish51325b52014-06-16 16:50:49 +053012306 if (vos_max_concurrent_connections_reached()) {
12307 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12308 return -EINVAL;
12309 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012310 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012311 wdev = ndev->ieee80211_ptr;
12312
12313#ifdef WLAN_BTAMP_FEATURE
12314 if((NL80211_IFTYPE_P2P_CLIENT == type)||
12315 (NL80211_IFTYPE_ADHOC == type)||
12316 (NL80211_IFTYPE_AP == type)||
12317 (NL80211_IFTYPE_P2P_GO == type))
12318 {
12319 pHddCtx->isAmpAllowed = VOS_FALSE;
12320 // stop AMP traffic
12321 status = WLANBAP_StopAmp();
12322 if(VOS_STATUS_SUCCESS != status )
12323 {
12324 pHddCtx->isAmpAllowed = VOS_TRUE;
12325 hddLog(VOS_TRACE_LEVEL_FATAL,
12326 "%s: Failed to stop AMP", __func__);
12327 return -EINVAL;
12328 }
12329 }
12330#endif //WLAN_BTAMP_FEATURE
12331 /* Reset the current device mode bit mask*/
12332 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
12333
Bala Venkatesh5c06a252018-07-12 16:08:04 +053012334 if (((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
12335 (type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO)) ||
12336 type == NL80211_IFTYPE_AP)
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053012337 {
12338 /* Notify Mode change in case of concurrency.
12339 * Below function invokes TDLS teardown Functionality Since TDLS is
12340 * not Supported in case of concurrency i.e Once P2P session
12341 * is detected disable offchannel and teardown TDLS links
12342 */
12343 hddLog(LOG1,
12344 FL("Device mode = %d Interface type = %d"),
12345 pAdapter->device_mode, type);
12346 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
12347 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053012348
Jeff Johnson295189b2012-06-20 16:38:30 -070012349 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012350 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070012351 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012352 )
12353 {
12354 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012355 if (!pWextState)
12356 {
12357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12358 "%s: pWextState is null", __func__);
12359 return VOS_STATUS_E_FAILURE;
12360 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012361 pRoamProfile = &pWextState->roamProfile;
12362 LastBSSType = pRoamProfile->BSSType;
12363
12364 switch (type)
12365 {
12366 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012367 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012368 hddLog(VOS_TRACE_LEVEL_INFO,
12369 "%s: setting interface Type to INFRASTRUCTURE", __func__);
12370 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012371#ifdef WLAN_FEATURE_11AC
12372 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
12373 {
12374 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
12375 }
12376#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012377 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070012378 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012379 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012380 //Check for sub-string p2p to confirm its a p2p interface
12381 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012382 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053012383#ifdef FEATURE_WLAN_TDLS
12384 mutex_lock(&pHddCtx->tdls_lock);
12385 wlan_hdd_tdls_exit(pAdapter, TRUE);
12386 mutex_unlock(&pHddCtx->tdls_lock);
12387#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012388 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12389 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12390 }
12391 else
12392 {
12393 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012394 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012395 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012396 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053012397
Jeff Johnson295189b2012-06-20 16:38:30 -070012398 case NL80211_IFTYPE_ADHOC:
12399 hddLog(VOS_TRACE_LEVEL_INFO,
12400 "%s: setting interface Type to ADHOC", __func__);
12401 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
12402 pRoamProfile->phyMode =
12403 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070012404 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012405 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053012406 hdd_set_ibss_ops( pAdapter );
12407 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053012408
12409 status = hdd_sta_id_hash_attach(pAdapter);
12410 if (VOS_STATUS_SUCCESS != status) {
12411 hddLog(VOS_TRACE_LEVEL_ERROR,
12412 FL("Failed to initialize hash for IBSS"));
12413 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012414 break;
12415
12416 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012417 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012418 {
12419 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12420 "%s: setting interface Type to %s", __func__,
12421 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
12422
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012423 //Cancel any remain on channel for GO mode
12424 if (NL80211_IFTYPE_P2P_GO == type)
12425 {
12426 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
12427 }
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012428 if (NL80211_IFTYPE_AP == type)
12429 {
12430 /*
12431 * As Loading WLAN Driver one interface being created
12432 * for p2p device address. This will take one HW STA and
12433 * the max number of clients that can connect to softAP
12434 * will be reduced by one. so while changing the interface
12435 * type to NL80211_IFTYPE_AP (SoftAP) remove p2p0 interface
12436 * as it is not required in SoftAP mode.
12437 */
12438
12439 // Get P2P Adapter
12440 pP2pAdapter = hdd_get_adapter(pHddCtx,
12441 WLAN_HDD_P2P_DEVICE);
12442 if (pP2pAdapter)
12443 {
Min Liuf3481952018-12-10 16:01:14 +080012444 wlan_hdd_release_intf_addr(pHddCtx,
12445 pP2pAdapter->macAddressCurrent.bytes);
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012446 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12447 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
12448 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12449 }
12450 }
12451
Swaroop Goltia2e32212014-04-09 23:37:33 +053012452 //Disable IMPS & BMPS for SAP/GO
12453 if(VOS_STATUS_E_FAILURE ==
12454 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
12455 {
12456 //Fail to Exit BMPS
12457 VOS_ASSERT(0);
12458 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053012459
12460 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
12461
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012462#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070012463
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012464 /* A Mutex Lock is introduced while changing the mode to
12465 * protect the concurrent access for the Adapters by TDLS
12466 * module.
12467 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012468 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012469#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012470 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053012471 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012472 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070012473 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12474 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012475#ifdef FEATURE_WLAN_TDLS
12476 mutex_unlock(&pHddCtx->tdls_lock);
12477#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012478 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
12479 (pConfig->apRandomBssidEnabled))
12480 {
12481 /* To meet Android requirements create a randomized
12482 MAC address of the form 02:1A:11:Fx:xx:xx */
12483 get_random_bytes(&ndev->dev_addr[3], 3);
12484 ndev->dev_addr[0] = 0x02;
12485 ndev->dev_addr[1] = 0x1A;
12486 ndev->dev_addr[2] = 0x11;
12487 ndev->dev_addr[3] |= 0xF0;
12488 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
12489 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080012490 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
12491 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012492 }
12493
Jeff Johnson295189b2012-06-20 16:38:30 -070012494 hdd_set_ap_ops( pAdapter->dev );
12495
Kiet Lam10841362013-11-01 11:36:50 +053012496 /* This is for only SAP mode where users can
12497 * control country through ini.
12498 * P2P GO follows station country code
12499 * acquired during the STA scanning. */
12500 if((NL80211_IFTYPE_AP == type) &&
12501 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
12502 {
12503 int status = 0;
12504 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
12505 "%s: setting country code from INI ", __func__);
12506 init_completion(&pAdapter->change_country_code);
12507 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
12508 (void *)(tSmeChangeCountryCallback)
12509 wlan_hdd_change_country_code_cb,
12510 pConfig->apCntryCode, pAdapter,
12511 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012512 eSIR_FALSE,
12513 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053012514 if (eHAL_STATUS_SUCCESS == status)
12515 {
12516 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012517 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053012518 &pAdapter->change_country_code,
12519 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012520 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053012521 {
12522 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012523 FL("SME Timed out while setting country code %ld"),
12524 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080012525
12526 if (pHddCtx->isLogpInProgress)
12527 {
12528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12529 "%s: LOGP in Progress. Ignore!!!", __func__);
12530 return -EAGAIN;
12531 }
Kiet Lam10841362013-11-01 11:36:50 +053012532 }
12533 }
12534 else
12535 {
12536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012537 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053012538 return -EINVAL;
12539 }
12540 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053012541 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070012542 if(status != VOS_STATUS_SUCCESS)
12543 {
12544 hddLog(VOS_TRACE_LEVEL_FATAL,
12545 "%s: Error initializing the ap mode", __func__);
12546 return -EINVAL;
12547 }
12548 hdd_set_conparam(1);
12549
Nirav Shah7e3c8132015-06-22 23:51:42 +053012550 status = hdd_sta_id_hash_attach(pAdapter);
12551 if (VOS_STATUS_SUCCESS != status)
12552 {
12553 hddLog(VOS_TRACE_LEVEL_ERROR,
12554 FL("Failed to initialize hash for AP"));
12555 return -EINVAL;
12556 }
12557
Jeff Johnson295189b2012-06-20 16:38:30 -070012558 /*interface type changed update in wiphy structure*/
12559 if(wdev)
12560 {
12561 wdev->iftype = type;
12562 pHddCtx->change_iface = type;
12563 }
12564 else
12565 {
12566 hddLog(VOS_TRACE_LEVEL_ERROR,
12567 "%s: ERROR !!!! Wireless dev is NULL", __func__);
12568 return -EINVAL;
12569 }
12570 goto done;
12571 }
12572
12573 default:
12574 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12575 __func__);
12576 return -EOPNOTSUPP;
12577 }
12578 }
12579 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012580 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070012581 )
12582 {
12583 switch(type)
12584 {
12585 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012586 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012587 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053012588
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012589 if (pAdapter->device_mode == WLAN_HDD_SOFTAP
12590 && !hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE)) {
12591 /*
12592 * The p2p interface was deleted while SoftAP mode was init,
12593 * create that interface now that the SoftAP is going down.
12594 */
12595 pP2pAdapter = hdd_open_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE,
12596 "p2p%d", wlan_hdd_get_intf_addr(pHddCtx),
12597 VOS_TRUE);
12598 }
12599
Deepthi Gowri500fc472014-08-11 19:53:10 +053012600 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012601
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012602#ifdef FEATURE_WLAN_TDLS
12603
12604 /* A Mutex Lock is introduced while changing the mode to
12605 * protect the concurrent access for the Adapters by TDLS
12606 * module.
12607 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012608 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012609#endif
c_hpothu002231a2015-02-05 14:58:51 +053012610 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012611 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012612 //Check for sub-string p2p to confirm its a p2p interface
12613 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012614 {
12615 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12616 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12617 }
12618 else
12619 {
12620 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012621 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012622 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053012623
12624 /* set con_mode to STA only when no SAP concurrency mode */
12625 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
12626 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012627 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012628 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
12629 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012630#ifdef FEATURE_WLAN_TDLS
12631 mutex_unlock(&pHddCtx->tdls_lock);
12632#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053012633 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070012634 if( VOS_STATUS_SUCCESS != status )
12635 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070012636 /* In case of JB, for P2P-GO, only change interface will be called,
12637 * This is the right place to enable back bmps_imps()
12638 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012639 if (pHddCtx->hdd_wlan_suspended)
12640 {
12641 hdd_set_pwrparams(pHddCtx);
12642 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012643 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012644 goto done;
12645 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012646 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012647 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012648 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12649 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012650 goto done;
12651 default:
12652 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12653 __func__);
12654 return -EOPNOTSUPP;
12655
12656 }
12657
12658 }
12659 else
12660 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012661 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
12662 __func__, hdd_device_modetoString(pAdapter->device_mode),
12663 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012664 return -EOPNOTSUPP;
12665 }
12666
12667
12668 if(pRoamProfile)
12669 {
12670 if ( LastBSSType != pRoamProfile->BSSType )
12671 {
12672 /*interface type changed update in wiphy structure*/
12673 wdev->iftype = type;
12674
12675 /*the BSS mode changed, We need to issue disconnect
12676 if connected or in IBSS disconnect state*/
12677 if ( hdd_connGetConnectedBssType(
12678 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
12679 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
12680 {
12681 /*need to issue a disconnect to CSR.*/
12682 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12683 if( eHAL_STATUS_SUCCESS ==
12684 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12685 pAdapter->sessionId,
12686 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12687 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012688 ret = wait_for_completion_interruptible_timeout(
12689 &pAdapter->disconnect_comp_var,
12690 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12691 if (ret <= 0)
12692 {
12693 hddLog(VOS_TRACE_LEVEL_ERROR,
12694 FL("wait on disconnect_comp_var failed %ld"), ret);
12695 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012696 }
12697 }
12698 }
12699 }
12700
12701done:
12702 /*set bitmask based on updated value*/
12703 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012704
12705 /* Only STA mode support TM now
12706 * all other mode, TM feature should be disabled */
12707 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12708 (~VOS_STA & pHddCtx->concurrency_mode) )
12709 {
12710 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12711 }
12712
Jeff Johnson295189b2012-06-20 16:38:30 -070012713#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012714 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012715 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012716 {
12717 //we are ok to do AMP
12718 pHddCtx->isAmpAllowed = VOS_TRUE;
12719 }
12720#endif //WLAN_BTAMP_FEATURE
12721 EXIT();
12722 return 0;
12723}
12724
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012725/*
12726 * FUNCTION: wlan_hdd_cfg80211_change_iface
12727 * wrapper function to protect the actual implementation from SSR.
12728 */
12729int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12730 struct net_device *ndev,
12731 enum nl80211_iftype type,
12732 u32 *flags,
12733 struct vif_params *params
12734 )
12735{
12736 int ret;
12737
12738 vos_ssr_protect(__func__);
12739 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12740 vos_ssr_unprotect(__func__);
12741
12742 return ret;
12743}
12744
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012745#ifdef FEATURE_WLAN_TDLS
12746static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012747 struct net_device *dev,
12748#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12749 const u8 *mac,
12750#else
12751 u8 *mac,
12752#endif
12753 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012754{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012755 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012756 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012757 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012758 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012759 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012760 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012761
12762 ENTER();
12763
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012764 if (!dev) {
12765 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12766 return -EINVAL;
12767 }
12768
12769 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12770 if (!pAdapter) {
12771 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12772 return -EINVAL;
12773 }
12774
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012775 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012776 {
12777 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12778 "Invalid arguments");
12779 return -EINVAL;
12780 }
Hoonki Lee27511902013-03-14 18:19:06 -070012781
12782 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12783 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12784 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012785 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012786 "%s: TDLS mode is disabled OR not enabled in FW."
12787 MAC_ADDRESS_STR " Request declined.",
12788 __func__, MAC_ADDR_ARRAY(mac));
12789 return -ENOTSUPP;
12790 }
12791
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012792 if (pHddCtx->isLogpInProgress)
12793 {
12794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12795 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012796 wlan_hdd_tdls_set_link_status(pAdapter,
12797 mac,
12798 eTDLS_LINK_IDLE,
12799 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012800 return -EBUSY;
12801 }
12802
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012803 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012804 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012805
12806 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012808 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12809 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012810 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012811 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012812 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012813
12814 /* in add station, we accept existing valid staId if there is */
12815 if ((0 == update) &&
12816 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12817 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012818 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012820 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012821 " link_status %d. staId %d. add station ignored.",
12822 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012823 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012824 return 0;
12825 }
12826 /* in change station, we accept only when staId is valid */
12827 if ((1 == update) &&
12828 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12829 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12830 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012831 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012833 "%s: " MAC_ADDRESS_STR
12834 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012835 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12836 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12837 mutex_unlock(&pHddCtx->tdls_lock);
12838 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012839 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012840 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012841
12842 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012843 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012844 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12846 "%s: " MAC_ADDRESS_STR
12847 " TDLS setup is ongoing. Request declined.",
12848 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012849 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012850 }
12851
12852 /* first to check if we reached to maximum supported TDLS peer.
12853 TODO: for now, return -EPERM looks working fine,
12854 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012855 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12856 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012857 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12859 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012860 " TDLS Max peer already connected. Request declined."
12861 " Num of peers (%d), Max allowed (%d).",
12862 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12863 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012864 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012865 }
12866 else
12867 {
12868 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012869 mutex_lock(&pHddCtx->tdls_lock);
12870 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012871 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012872 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012873 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012874 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12875 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12876 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012877 return -EPERM;
12878 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012879 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012880 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012881 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012882 wlan_hdd_tdls_set_link_status(pAdapter,
12883 mac,
12884 eTDLS_LINK_CONNECTING,
12885 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012886
Jeff Johnsond75fe012013-04-06 10:53:06 -070012887 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012888 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012889 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012890 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012891 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012892 if(StaParams->htcap_present)
12893 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012895 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012897 "ht_capa->extended_capabilities: %0x",
12898 StaParams->HTCap.extendedHtCapInfo);
12899 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012901 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012903 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012904 if(StaParams->vhtcap_present)
12905 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012907 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12908 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12909 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12910 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012911 {
12912 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012914 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012915 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012916 "[%d]: %x ", i, StaParams->supported_rates[i]);
12917 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012918 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012919 else if ((1 == update) && (NULL == StaParams))
12920 {
12921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12922 "%s : update is true, but staParams is NULL. Error!", __func__);
12923 return -EPERM;
12924 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012925
12926 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12927
12928 if (!update)
12929 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012930 /*Before adding sta make sure that device exited from BMPS*/
12931 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12932 {
12933 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12934 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12935 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12936 if (status != VOS_STATUS_SUCCESS) {
12937 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12938 }
12939 }
12940
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012941 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012942 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012943 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012944 hddLog(VOS_TRACE_LEVEL_ERROR,
12945 FL("Failed to add TDLS peer STA. Enable Bmps"));
12946 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012947 return -EPERM;
12948 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012949 }
12950 else
12951 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012952 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012953 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012954 if (ret != eHAL_STATUS_SUCCESS) {
12955 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12956 return -EPERM;
12957 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012958 }
12959
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012960 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012961 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12962
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012963 mutex_lock(&pHddCtx->tdls_lock);
12964 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12965
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012966 if ((pTdlsPeer != NULL) &&
12967 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012968 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012969 hddLog(VOS_TRACE_LEVEL_ERROR,
12970 FL("peer link status %u"), pTdlsPeer->link_status);
12971 mutex_unlock(&pHddCtx->tdls_lock);
12972 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012973 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012974 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012975
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012976 if (ret <= 0)
12977 {
12978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12979 "%s: timeout waiting for tdls add station indication %ld",
12980 __func__, ret);
12981 goto error;
12982 }
12983
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012984 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12985 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012986 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012987 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012988 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012989 }
12990
12991 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012992
12993error:
Atul Mittal115287b2014-07-08 13:26:33 +053012994 wlan_hdd_tdls_set_link_status(pAdapter,
12995 mac,
12996 eTDLS_LINK_IDLE,
12997 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012998 return -EPERM;
12999
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013000}
13001#endif
13002
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013003VOS_STATUS wlan_hdd_send_sta_authorized_event(
13004 hdd_adapter_t *adapter,
13005 hdd_context_t *hdd_ctx,
13006 const v_MACADDR_t *mac_addr)
13007{
13008 struct sk_buff *vendor_event;
13009 uint32_t sta_flags = 0;
13010 VOS_STATUS status;
13011
13012 ENTER();
13013
13014 if (!hdd_ctx) {
13015 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null"));
13016 return -EINVAL;
13017 }
13018
13019 vendor_event =
13020 cfg80211_vendor_event_alloc(
Ashish Kumar Dhanotiyac99fbef2018-04-11 12:23:32 +053013021 hdd_ctx->wiphy,
13022#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
13023 &adapter->wdev,
13024#endif
13025 sizeof(sta_flags) +
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013026 VOS_MAC_ADDR_SIZE + NLMSG_HDRLEN,
13027 QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX,
13028 GFP_KERNEL);
13029 if (!vendor_event) {
13030 hddLog(VOS_TRACE_LEVEL_ERROR,
13031 FL("cfg80211_vendor_event_alloc failed"));
13032 return -EINVAL;
13033 }
13034
13035 sta_flags |= BIT(NL80211_STA_FLAG_AUTHORIZED);
13036
13037 status = nla_put_u32(vendor_event,
13038 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS,
13039 sta_flags);
13040 if (status) {
13041 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA flag put fails"));
13042 kfree_skb(vendor_event);
13043 return VOS_STATUS_E_FAILURE;
13044 }
13045 status = nla_put(vendor_event,
13046 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_MAC,
13047 VOS_MAC_ADDR_SIZE, mac_addr->bytes);
13048 if (status) {
13049 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA MAC put fails"));
13050 kfree_skb(vendor_event);
13051 return VOS_STATUS_E_FAILURE;
13052 }
13053
13054 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
13055
13056 EXIT();
13057 return 0;
13058}
13059
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013060static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013061 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013062#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13063 const u8 *mac,
13064#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013065 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013066#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013067 struct station_parameters *params)
13068{
13069 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013070 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013071 hdd_context_t *pHddCtx;
13072 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013073 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013074 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013075#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013076 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013077 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013078 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013079 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013080#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013081
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013082 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013083
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013084 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013085 if ((NULL == pAdapter))
13086 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013087 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013088 "invalid adapter ");
13089 return -EINVAL;
13090 }
13091
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013092 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13093 TRACE_CODE_HDD_CHANGE_STATION,
13094 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053013095 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013096
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013097 ret = wlan_hdd_validate_context(pHddCtx);
13098 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053013099 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013100 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013101 }
13102
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013103 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13104
13105 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013106 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13108 "invalid HDD station context");
13109 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013110 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013111 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
13112
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013113 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
13114 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070013115 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013116 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070013117 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013118 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070013119 WLANTL_STA_AUTHENTICATED);
13120
Gopichand Nakkala29149562013-05-10 21:43:41 +053013121 if (status != VOS_STATUS_SUCCESS)
13122 {
13123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13124 "%s: Not able to change TL state to AUTHENTICATED", __func__);
13125 return -EINVAL;
13126 }
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013127 status = wlan_hdd_send_sta_authorized_event(pAdapter, pHddCtx,
13128 &STAMacAddress);
13129 if (status != VOS_STATUS_SUCCESS)
13130 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013131 }
13132 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070013133 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
13134 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013135#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013136 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13137 StaParams.capability = params->capability;
13138 StaParams.uapsd_queues = params->uapsd_queues;
13139 StaParams.max_sp = params->max_sp;
13140
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013141 /* Convert (first channel , number of channels) tuple to
13142 * the total list of channels. This goes with the assumption
13143 * that if the first channel is < 14, then the next channels
13144 * are an incremental of 1 else an incremental of 4 till the number
13145 * of channels.
13146 */
13147 if (0 != params->supported_channels_len) {
13148 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013149 for ( i = 0 ; i < params->supported_channels_len
13150 && j < SIR_MAC_MAX_SUPP_CHANNELS; i+=2)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013151 {
13152 int wifi_chan_index;
13153 StaParams.supported_channels[j] = params->supported_channels[i];
13154 wifi_chan_index =
13155 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
13156 no_of_channels = params->supported_channels[i+1];
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013157 for(k=1; k <= no_of_channels
13158 && j < SIR_MAC_MAX_SUPP_CHANNELS - 1; k++)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013159 {
13160 StaParams.supported_channels[j+1] =
13161 StaParams.supported_channels[j] + wifi_chan_index;
13162 j+=1;
13163 }
13164 }
13165 StaParams.supported_channels_len = j;
13166 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053013167 if (params->supported_oper_classes_len >
13168 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
13169 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13170 "received oper classes:%d, resetting it to max supported %d",
13171 params->supported_oper_classes_len,
13172 SIR_MAC_MAX_SUPP_OPER_CLASSES);
13173 params->supported_oper_classes_len =
13174 SIR_MAC_MAX_SUPP_OPER_CLASSES;
13175 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013176 vos_mem_copy(StaParams.supported_oper_classes,
13177 params->supported_oper_classes,
13178 params->supported_oper_classes_len);
13179 StaParams.supported_oper_classes_len =
13180 params->supported_oper_classes_len;
13181
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013182 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
13183 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13184 "received extn capabilities:%d, resetting it to max supported",
13185 params->ext_capab_len);
13186 params->ext_capab_len = sizeof(StaParams.extn_capability);
13187 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013188 if (0 != params->ext_capab_len)
13189 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013190 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013191
13192 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013193 {
13194 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013195 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013196 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013197
13198 StaParams.supported_rates_len = params->supported_rates_len;
13199
13200 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
13201 * The supported_rates array , for all the structures propogating till Add Sta
13202 * to the firmware has to be modified , if the supplicant (ieee80211) is
13203 * modified to send more rates.
13204 */
13205
13206 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
13207 */
13208 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
13209 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
13210
13211 if (0 != StaParams.supported_rates_len) {
13212 int i = 0;
13213 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
13214 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013215 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013216 "Supported Rates with Length %d", StaParams.supported_rates_len);
13217 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013219 "[%d]: %0x", i, StaParams.supported_rates[i]);
13220 }
13221
13222 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013223 {
13224 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013225 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013226 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013227
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013228 if (0 != params->ext_capab_len ) {
13229 /*Define A Macro : TODO Sunil*/
13230 if ((1<<4) & StaParams.extn_capability[3]) {
13231 isBufSta = 1;
13232 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013233 /* TDLS Channel Switching Support */
13234 if ((1<<6) & StaParams.extn_capability[3]) {
13235 isOffChannelSupported = 1;
13236 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013237 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013238
13239 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053013240 (params->ht_capa || params->vht_capa ||
13241 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013242 /* TDLS Peer is WME/QoS capable */
13243 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013244
13245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13246 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
13247 __func__, isQosWmmSta, StaParams.htcap_present);
13248
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013249 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
13250 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013251 isOffChannelSupported,
13252 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013253
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013254 if (VOS_STATUS_SUCCESS != status) {
13255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13256 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
13257 return -EINVAL;
13258 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013259 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
13260
13261 if (VOS_STATUS_SUCCESS != status) {
13262 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13263 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
13264 return -EINVAL;
13265 }
13266 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013267#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053013268 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013269 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013270 return status;
13271}
13272
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013273#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13274static int wlan_hdd_change_station(struct wiphy *wiphy,
13275 struct net_device *dev,
13276 const u8 *mac,
13277 struct station_parameters *params)
13278#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013279static int wlan_hdd_change_station(struct wiphy *wiphy,
13280 struct net_device *dev,
13281 u8 *mac,
13282 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013283#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013284{
13285 int ret;
13286
13287 vos_ssr_protect(__func__);
13288 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
13289 vos_ssr_unprotect(__func__);
13290
13291 return ret;
13292}
13293
Jeff Johnson295189b2012-06-20 16:38:30 -070013294/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013295 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013296 * This function is used to initialize the key information
13297 */
13298#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013299static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013300 struct net_device *ndev,
13301 u8 key_index, bool pairwise,
13302 const u8 *mac_addr,
13303 struct key_params *params
13304 )
13305#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013306static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013307 struct net_device *ndev,
13308 u8 key_index, const u8 *mac_addr,
13309 struct key_params *params
13310 )
13311#endif
13312{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013313 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013314 tCsrRoamSetKey setKey;
13315 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013316 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013317 v_U32_t roamId= 0xFF;
13318 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013319 hdd_hostapd_state_t *pHostapdState;
13320 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013321 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013322 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013323 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013324 v_MACADDR_t *peerMacAddr;
13325 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013326 uint8_t staid = HDD_MAX_STA_COUNT;
13327 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013328
13329 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013330
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013331 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13332 TRACE_CODE_HDD_CFG80211_ADD_KEY,
13333 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013334 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13335 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013336 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013337 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013338 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013339 }
13340
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013341 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13342 __func__, hdd_device_modetoString(pAdapter->device_mode),
13343 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013344
13345 if (CSR_MAX_NUM_KEY <= key_index)
13346 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013347 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013348 key_index);
13349
13350 return -EINVAL;
13351 }
13352
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013353 if (CSR_MAX_KEY_LEN < params->key_len)
13354 {
13355 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
13356 params->key_len);
13357
13358 return -EINVAL;
13359 }
13360
Jingxiang Gec438aea2017-10-26 16:44:00 +080013361 if (CSR_MAX_RSC_LEN < params->seq_len)
13362 {
13363 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
13364 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053013365
13366 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080013367 }
13368
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013369 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080013370 "%s: called with key index = %d & key length %d & seq length %d",
13371 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013372
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013373 peerMacAddr = (v_MACADDR_t *)mac_addr;
13374
Jeff Johnson295189b2012-06-20 16:38:30 -070013375 /*extract key idx, key len and key*/
13376 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13377 setKey.keyId = key_index;
13378 setKey.keyLength = params->key_len;
13379 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080013380 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013381
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013382 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013383 {
13384 case WLAN_CIPHER_SUITE_WEP40:
13385 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13386 break;
13387
13388 case WLAN_CIPHER_SUITE_WEP104:
13389 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
13390 break;
13391
13392 case WLAN_CIPHER_SUITE_TKIP:
13393 {
13394 u8 *pKey = &setKey.Key[0];
13395 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
13396
13397 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
13398
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013399 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070013400
13401 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013402 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013403 |--------------|----------|----------|
13404 <---16bytes---><--8bytes--><--8bytes-->
13405
13406 */
13407 /*Sme expects the 32 bytes key to be in the below order
13408
13409 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013410 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013411 |--------------|----------|----------|
13412 <---16bytes---><--8bytes--><--8bytes-->
13413 */
13414 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013415 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070013416
13417 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013418 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013419
13420 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013421 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013422
13423
13424 break;
13425 }
13426
13427 case WLAN_CIPHER_SUITE_CCMP:
13428 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
13429 break;
13430
13431#ifdef FEATURE_WLAN_WAPI
13432 case WLAN_CIPHER_SUITE_SMS4:
13433 {
13434 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13435 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
13436 params->key, params->key_len);
13437 return 0;
13438 }
13439#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013440
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013441#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013442 case WLAN_CIPHER_SUITE_KRK:
13443 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
13444 break;
13445#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013446
13447#ifdef WLAN_FEATURE_11W
13448 case WLAN_CIPHER_SUITE_AES_CMAC:
13449 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070013450 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070013451#endif
13452
Jeff Johnson295189b2012-06-20 16:38:30 -070013453 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013454 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070013455 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013456 status = -EOPNOTSUPP;
13457 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013458 }
13459
13460 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
13461 __func__, setKey.encType);
13462
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013463 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070013464#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13465 (!pairwise)
13466#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013467 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013468#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013469 )
13470 {
13471 /* set group key*/
13472 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13473 "%s- %d: setting Broadcast key",
13474 __func__, __LINE__);
13475 setKey.keyDirection = eSIR_RX_ONLY;
13476 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13477 }
13478 else
13479 {
13480 /* set pairwise key*/
13481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13482 "%s- %d: setting pairwise key",
13483 __func__, __LINE__);
13484 setKey.keyDirection = eSIR_TX_RX;
13485 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013486 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013487 }
13488 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
13489 {
13490 setKey.keyDirection = eSIR_TX_RX;
13491 /*Set the group key*/
13492 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13493 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070013494
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013495 if ( 0 != status )
13496 {
13497 hddLog(VOS_TRACE_LEVEL_ERROR,
13498 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013499 status = -EINVAL;
13500 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013501 }
13502 /*Save the keys here and call sme_RoamSetKey for setting
13503 the PTK after peer joins the IBSS network*/
13504 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
13505 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013506 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013507 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053013508 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
13509 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
13510 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013511 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013512 if( pHostapdState->bssState == BSS_START )
13513 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013514 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13515 vos_status = wlan_hdd_check_ula_done(pAdapter);
13516
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013517 if (peerMacAddr && (pairwise_set_key == true))
13518 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013519
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013520 if ( vos_status != VOS_STATUS_SUCCESS )
13521 {
13522 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13523 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13524 __LINE__, vos_status );
13525
13526 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13527
13528 status = -EINVAL;
13529 goto end;
13530 }
13531
Jeff Johnson295189b2012-06-20 16:38:30 -070013532 status = WLANSAP_SetKeySta( pVosContext, &setKey);
13533
13534 if ( status != eHAL_STATUS_SUCCESS )
13535 {
13536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13537 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13538 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013539 status = -EINVAL;
13540 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013541 }
13542 }
13543
13544 /* Saving WEP keys */
13545 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
13546 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
13547 {
13548 //Save the wep key in ap context. Issue setkey after the BSS is started.
13549 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13550 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
13551 }
13552 else
13553 {
13554 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013555 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013556 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
13557 }
13558 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013559 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
13560 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013561 {
13562 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13563 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13564
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013565#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13566 if (!pairwise)
13567#else
13568 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
13569#endif
13570 {
13571 /* set group key*/
13572 if (pHddStaCtx->roam_info.deferKeyComplete)
13573 {
13574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13575 "%s- %d: Perform Set key Complete",
13576 __func__, __LINE__);
13577 hdd_PerformRoamSetKeyComplete(pAdapter);
13578 }
13579 }
13580
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013581 if (pairwise_set_key == true)
13582 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013583
Jeff Johnson295189b2012-06-20 16:38:30 -070013584 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
13585
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080013586 pWextState->roamProfile.Keys.defaultIndex = key_index;
13587
13588
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013589 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013590 params->key, params->key_len);
13591
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013592
Jeff Johnson295189b2012-06-20 16:38:30 -070013593 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13594
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013595 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013596 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013597 __func__, setKey.peerMac[0], setKey.peerMac[1],
13598 setKey.peerMac[2], setKey.peerMac[3],
13599 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013600 setKey.keyDirection);
13601
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013602 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053013603
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013604 if ( vos_status != VOS_STATUS_SUCCESS )
13605 {
13606 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013607 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13608 __LINE__, vos_status );
13609
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013610 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013611
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013612 status = -EINVAL;
13613 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013614
13615 }
13616
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013617#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013618 /* The supplicant may attempt to set the PTK once pre-authentication
13619 is done. Save the key in the UMAC and include it in the ADD BSS
13620 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013621 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013622 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013623 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013624 hddLog(VOS_TRACE_LEVEL_INFO_MED,
13625 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013626 status = 0;
13627 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013628 }
13629 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
13630 {
13631 hddLog(VOS_TRACE_LEVEL_ERROR,
13632 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013633 status = -EINVAL;
13634 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013635 }
13636#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070013637
13638 /* issue set key request to SME*/
13639 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13640 pAdapter->sessionId, &setKey, &roamId );
13641
13642 if ( 0 != status )
13643 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013644 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013645 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
13646 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013647 status = -EINVAL;
13648 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013649 }
13650
13651
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013652 /* in case of IBSS as there was no information available about WEP keys during
13653 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070013654 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013655 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
13656 !( ( IW_AUTH_KEY_MGMT_802_1X
13657 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070013658 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
13659 )
13660 &&
13661 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
13662 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
13663 )
13664 )
13665 {
13666 setKey.keyDirection = eSIR_RX_ONLY;
13667 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13668
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013669 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013670 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013671 __func__, setKey.peerMac[0], setKey.peerMac[1],
13672 setKey.peerMac[2], setKey.peerMac[3],
13673 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013674 setKey.keyDirection);
13675
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013676 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013677 pAdapter->sessionId, &setKey, &roamId );
13678
13679 if ( 0 != status )
13680 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013681 hddLog(VOS_TRACE_LEVEL_ERROR,
13682 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013683 __func__, status);
13684 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013685 status = -EINVAL;
13686 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013687 }
13688 }
13689 }
13690
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013691 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013692 for (i = 0; i < params->seq_len; i++) {
13693 rsc_counter |= (params->seq[i] << i*8);
13694 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013695 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
13696 }
13697
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013698end:
13699 /* Need to clear any trace of key value in the memory.
13700 * Thus zero out the memory even though it is local
13701 * variable.
13702 */
13703 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013704 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013705 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013706}
13707
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013708#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13709static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13710 struct net_device *ndev,
13711 u8 key_index, bool pairwise,
13712 const u8 *mac_addr,
13713 struct key_params *params
13714 )
13715#else
13716static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13717 struct net_device *ndev,
13718 u8 key_index, const u8 *mac_addr,
13719 struct key_params *params
13720 )
13721#endif
13722{
13723 int ret;
13724 vos_ssr_protect(__func__);
13725#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13726 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
13727 mac_addr, params);
13728#else
13729 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
13730 params);
13731#endif
13732 vos_ssr_unprotect(__func__);
13733
13734 return ret;
13735}
13736
Jeff Johnson295189b2012-06-20 16:38:30 -070013737/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013738 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013739 * This function is used to get the key information
13740 */
13741#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013742static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013743 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013744 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013745 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013746 const u8 *mac_addr, void *cookie,
13747 void (*callback)(void *cookie, struct key_params*)
13748 )
13749#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013750static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013751 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013752 struct net_device *ndev,
13753 u8 key_index, const u8 *mac_addr, void *cookie,
13754 void (*callback)(void *cookie, struct key_params*)
13755 )
13756#endif
13757{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013758 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013759 hdd_wext_state_t *pWextState = NULL;
13760 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013761 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013762 hdd_context_t *pHddCtx;
13763 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013764
13765 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013766
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013767 if (NULL == pAdapter)
13768 {
13769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13770 "%s: HDD adapter is Null", __func__);
13771 return -ENODEV;
13772 }
13773
13774 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13775 ret = wlan_hdd_validate_context(pHddCtx);
13776 if (0 != ret)
13777 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013778 return ret;
13779 }
13780
13781 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13782 pRoamProfile = &(pWextState->roamProfile);
13783
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013784 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13785 __func__, hdd_device_modetoString(pAdapter->device_mode),
13786 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013787
Jeff Johnson295189b2012-06-20 16:38:30 -070013788 memset(&params, 0, sizeof(params));
13789
13790 if (CSR_MAX_NUM_KEY <= key_index)
13791 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013792 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013793 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013794 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013795
13796 switch(pRoamProfile->EncryptionType.encryptionType[0])
13797 {
13798 case eCSR_ENCRYPT_TYPE_NONE:
13799 params.cipher = IW_AUTH_CIPHER_NONE;
13800 break;
13801
13802 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13803 case eCSR_ENCRYPT_TYPE_WEP40:
13804 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13805 break;
13806
13807 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13808 case eCSR_ENCRYPT_TYPE_WEP104:
13809 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13810 break;
13811
13812 case eCSR_ENCRYPT_TYPE_TKIP:
13813 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13814 break;
13815
13816 case eCSR_ENCRYPT_TYPE_AES:
13817 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13818 break;
13819
13820 default:
13821 params.cipher = IW_AUTH_CIPHER_NONE;
13822 break;
13823 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013824
c_hpothuaaf19692014-05-17 17:01:48 +053013825 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13826 TRACE_CODE_HDD_CFG80211_GET_KEY,
13827 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013828
Jeff Johnson295189b2012-06-20 16:38:30 -070013829 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13830 params.seq_len = 0;
13831 params.seq = NULL;
13832 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13833 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013834 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013835 return 0;
13836}
13837
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013838#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13839static int wlan_hdd_cfg80211_get_key(
13840 struct wiphy *wiphy,
13841 struct net_device *ndev,
13842 u8 key_index, bool pairwise,
13843 const u8 *mac_addr, void *cookie,
13844 void (*callback)(void *cookie, struct key_params*)
13845 )
13846#else
13847static int wlan_hdd_cfg80211_get_key(
13848 struct wiphy *wiphy,
13849 struct net_device *ndev,
13850 u8 key_index, const u8 *mac_addr, void *cookie,
13851 void (*callback)(void *cookie, struct key_params*)
13852 )
13853#endif
13854{
13855 int ret;
13856
13857 vos_ssr_protect(__func__);
13858#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13859 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13860 mac_addr, cookie, callback);
13861#else
13862 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13863 callback);
13864#endif
13865 vos_ssr_unprotect(__func__);
13866
13867 return ret;
13868}
13869
Jeff Johnson295189b2012-06-20 16:38:30 -070013870/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013871 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013872 * This function is used to delete the key information
13873 */
13874#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013875static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013876 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013877 u8 key_index,
13878 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013879 const u8 *mac_addr
13880 )
13881#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013882static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013883 struct net_device *ndev,
13884 u8 key_index,
13885 const u8 *mac_addr
13886 )
13887#endif
13888{
13889 int status = 0;
13890
13891 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013892 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013893 //it is observed that this is invalidating peer
13894 //key index whenever re-key is done. This is affecting data link.
13895 //It should be ok to ignore del_key.
13896#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013897 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13898 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013899 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13900 tCsrRoamSetKey setKey;
13901 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013902
Jeff Johnson295189b2012-06-20 16:38:30 -070013903 ENTER();
13904
13905 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13906 __func__,pAdapter->device_mode);
13907
13908 if (CSR_MAX_NUM_KEY <= key_index)
13909 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013910 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013911 key_index);
13912
13913 return -EINVAL;
13914 }
13915
13916 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13917 setKey.keyId = key_index;
13918
13919 if (mac_addr)
13920 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13921 else
13922 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13923
13924 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13925
13926 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013927 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013928 )
13929 {
13930
13931 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013932 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13933 if( pHostapdState->bssState == BSS_START)
13934 {
13935 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013936
Jeff Johnson295189b2012-06-20 16:38:30 -070013937 if ( status != eHAL_STATUS_SUCCESS )
13938 {
13939 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13940 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13941 __LINE__, status );
13942 }
13943 }
13944 }
13945 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013946 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013947 )
13948 {
13949 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13950
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013951 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13952
13953 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013954 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013955 __func__, setKey.peerMac[0], setKey.peerMac[1],
13956 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013957 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013958 if(pAdapter->sessionCtx.station.conn_info.connState ==
13959 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013960 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013961 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013962 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013963
Jeff Johnson295189b2012-06-20 16:38:30 -070013964 if ( 0 != status )
13965 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013966 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013967 "%s: sme_RoamSetKey failure, returned %d",
13968 __func__, status);
13969 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13970 return -EINVAL;
13971 }
13972 }
13973 }
13974#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013975 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013976 return status;
13977}
13978
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013979#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13980static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13981 struct net_device *ndev,
13982 u8 key_index,
13983 bool pairwise,
13984 const u8 *mac_addr
13985 )
13986#else
13987static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13988 struct net_device *ndev,
13989 u8 key_index,
13990 const u8 *mac_addr
13991 )
13992#endif
13993{
13994 int ret;
13995
13996 vos_ssr_protect(__func__);
13997#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13998 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
13999 mac_addr);
14000#else
14001 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
14002#endif
14003 vos_ssr_unprotect(__func__);
14004
14005 return ret;
14006}
14007
Jeff Johnson295189b2012-06-20 16:38:30 -070014008/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014009 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070014010 * This function is used to set the default tx key index
14011 */
14012#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014013static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014014 struct net_device *ndev,
14015 u8 key_index,
14016 bool unicast, bool multicast)
14017#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014018static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014019 struct net_device *ndev,
14020 u8 key_index)
14021#endif
14022{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014023 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014024 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053014025 hdd_wext_state_t *pWextState;
14026 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014027 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014028
14029 ENTER();
14030
Gopichand Nakkala29149562013-05-10 21:43:41 +053014031 if ((NULL == pAdapter))
14032 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053014034 "invalid adapter");
14035 return -EINVAL;
14036 }
14037
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014038 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14039 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
14040 pAdapter->sessionId, key_index));
14041
Gopichand Nakkala29149562013-05-10 21:43:41 +053014042 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14043 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14044
14045 if ((NULL == pWextState) || (NULL == pHddStaCtx))
14046 {
14047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14048 "invalid Wext state or HDD context");
14049 return -EINVAL;
14050 }
14051
Arif Hussain6d2a3322013-11-17 19:50:10 -080014052 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014053 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014054
Jeff Johnson295189b2012-06-20 16:38:30 -070014055 if (CSR_MAX_NUM_KEY <= key_index)
14056 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014057 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014058 key_index);
14059
14060 return -EINVAL;
14061 }
14062
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014063 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14064 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014065 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014066 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014067 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014068 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014069
Jeff Johnson295189b2012-06-20 16:38:30 -070014070 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070014071 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014072 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014073 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053014074 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080014075 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080014076#ifdef FEATURE_WLAN_WAPI
14077 (eCSR_ENCRYPT_TYPE_WPI !=
14078 pHddStaCtx->conn_info.ucEncryptionType) &&
14079#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014080 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080014081 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070014082 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014083 {
14084 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070014085 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014086
Jeff Johnson295189b2012-06-20 16:38:30 -070014087 tCsrRoamSetKey setKey;
14088 v_U32_t roamId= 0xFF;
14089 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014090
14091 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014092 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014093
Jeff Johnson295189b2012-06-20 16:38:30 -070014094 Keys->defaultIndex = (u8)key_index;
14095 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
14096 setKey.keyId = key_index;
14097 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014098
14099 vos_mem_copy(&setKey.Key[0],
14100 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014101 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014102
Gopichand Nakkala29149562013-05-10 21:43:41 +053014103 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014104
14105 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070014106 &pHddStaCtx->conn_info.bssId[0],
14107 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014108
Gopichand Nakkala29149562013-05-10 21:43:41 +053014109 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
14110 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
14111 eCSR_ENCRYPT_TYPE_WEP104)
14112 {
14113 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
14114 even though ap is configured for WEP-40 encryption. In this canse the key length
14115 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
14116 type(104) and switching encryption type to 40*/
14117 pWextState->roamProfile.EncryptionType.encryptionType[0] =
14118 eCSR_ENCRYPT_TYPE_WEP40;
14119 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
14120 eCSR_ENCRYPT_TYPE_WEP40;
14121 }
14122
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014123 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014124 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014125
Jeff Johnson295189b2012-06-20 16:38:30 -070014126 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014127 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014128 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014129
Jeff Johnson295189b2012-06-20 16:38:30 -070014130 if ( 0 != status )
14131 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014132 hddLog(VOS_TRACE_LEVEL_ERROR,
14133 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014134 status);
14135 return -EINVAL;
14136 }
14137 }
14138 }
14139
14140 /* In SoftAp mode setting key direction for default mode */
14141 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
14142 {
14143 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
14144 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
14145 (eCSR_ENCRYPT_TYPE_AES !=
14146 pWextState->roamProfile.EncryptionType.encryptionType[0])
14147 )
14148 {
14149 /* Saving key direction for default key index to TX default */
14150 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
14151 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
14152 }
14153 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014154 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014155 return status;
14156}
14157
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014158#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14159static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14160 struct net_device *ndev,
14161 u8 key_index,
14162 bool unicast, bool multicast)
14163#else
14164static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14165 struct net_device *ndev,
14166 u8 key_index)
14167#endif
14168{
14169 int ret;
14170 vos_ssr_protect(__func__);
14171#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14172 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
14173 multicast);
14174#else
14175 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
14176#endif
14177 vos_ssr_unprotect(__func__);
14178
14179 return ret;
14180}
14181
Jeff Johnson295189b2012-06-20 16:38:30 -070014182/*
14183 * FUNCTION: wlan_hdd_cfg80211_inform_bss
14184 * This function is used to inform the BSS details to nl80211 interface.
14185 */
14186static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
14187 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
14188{
14189 struct net_device *dev = pAdapter->dev;
14190 struct wireless_dev *wdev = dev->ieee80211_ptr;
14191 struct wiphy *wiphy = wdev->wiphy;
14192 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
14193 int chan_no;
14194 int ie_length;
14195 const char *ie;
14196 unsigned int freq;
14197 struct ieee80211_channel *chan;
14198 int rssi = 0;
14199 struct cfg80211_bss *bss = NULL;
14200
Jeff Johnson295189b2012-06-20 16:38:30 -070014201 if( NULL == pBssDesc )
14202 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014203 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014204 return bss;
14205 }
14206
14207 chan_no = pBssDesc->channelId;
14208 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
14209 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
14210
14211 if( NULL == ie )
14212 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014213 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014214 return bss;
14215 }
14216
14217#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
14218 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
14219 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014220 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014221 }
14222 else
14223 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014224 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014225 }
14226#else
14227 freq = ieee80211_channel_to_frequency(chan_no);
14228#endif
14229
14230 chan = __ieee80211_get_channel(wiphy, freq);
14231
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053014232 if (!chan) {
14233 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
14234 return NULL;
14235 }
14236
Abhishek Singhaee43942014-06-16 18:55:47 +053014237 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070014238
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014239 return cfg80211_inform_bss(wiphy, chan,
14240#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14241 CFG80211_BSS_FTYPE_UNKNOWN,
14242#endif
14243 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014244 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070014245 pBssDesc->capabilityInfo,
14246 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053014247 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070014248}
14249
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014250/*
14251 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
14252 * interface that BSS might have been lost.
14253 * @pAdapter: adaptor
14254 * @bssid: bssid which might have been lost
14255 *
14256 * Return: bss which is unlinked from kernel cache
14257 */
14258struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
14259 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
14260{
14261 struct net_device *dev = pAdapter->dev;
14262 struct wireless_dev *wdev = dev->ieee80211_ptr;
14263 struct wiphy *wiphy = wdev->wiphy;
14264 struct cfg80211_bss *bss = NULL;
14265
Abhishek Singh5a597e62016-12-05 15:16:30 +053014266 bss = hdd_get_bss_entry(wiphy,
14267 NULL, bssid,
14268 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014269 if (bss == NULL) {
14270 hddLog(LOGE, FL("BSS not present"));
14271 } else {
14272 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
14273 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
14274 cfg80211_unlink_bss(wiphy, bss);
14275 }
14276 return bss;
14277}
Jeff Johnson295189b2012-06-20 16:38:30 -070014278
14279
14280/*
14281 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
14282 * This function is used to inform the BSS details to nl80211 interface.
14283 */
14284struct cfg80211_bss*
14285wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
14286 tSirBssDescription *bss_desc
14287 )
14288{
14289 /*
14290 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
14291 already exists in bss data base of cfg80211 for that particular BSS ID.
14292 Using cfg80211_inform_bss_frame to update the bss entry instead of
14293 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
14294 now there is no possibility to get the mgmt(probe response) frame from PE,
14295 converting bss_desc to ieee80211_mgmt(probe response) and passing to
14296 cfg80211_inform_bss_frame.
14297 */
14298 struct net_device *dev = pAdapter->dev;
14299 struct wireless_dev *wdev = dev->ieee80211_ptr;
14300 struct wiphy *wiphy = wdev->wiphy;
14301 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014302#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14303 qcom_ie_age *qie_age = NULL;
14304 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
14305#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014306 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014307#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014308 const char *ie =
14309 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
14310 unsigned int freq;
14311 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014312 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014313 struct cfg80211_bss *bss_status = NULL;
Hanumanth Reddy Pothulae04e06c2018-05-31 14:41:36 +053014314 size_t frame_len = ie_length + offsetof(struct ieee80211_mgmt,
14315 u.probe_resp.variable);
Jeff Johnson295189b2012-06-20 16:38:30 -070014316 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070014317 hdd_context_t *pHddCtx;
14318 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070014319#ifdef WLAN_OPEN_SOURCE
14320 struct timespec ts;
14321#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014322
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014323
Wilson Yangf80a0542013-10-07 13:02:37 -070014324 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14325 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070014326 if (0 != status)
14327 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014328 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014329 }
14330
Hanumanth Reddy Pothula33548e22018-05-31 13:28:51 +053014331 mgmt = kzalloc(frame_len, GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070014332 if (!mgmt)
14333 {
14334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14335 "%s: memory allocation failed ", __func__);
14336 return NULL;
14337 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014338
Jeff Johnson295189b2012-06-20 16:38:30 -070014339 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014340
14341#ifdef WLAN_OPEN_SOURCE
14342 /* Android does not want the timestamp from the frame.
14343 Instead it wants a monotonic increasing value */
14344 get_monotonic_boottime(&ts);
14345 mgmt->u.probe_resp.timestamp =
14346 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
14347#else
14348 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014349 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
14350 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070014351
14352#endif
14353
Jeff Johnson295189b2012-06-20 16:38:30 -070014354 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
14355 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014356
14357#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14358 /* GPS Requirement: need age ie per entry. Using vendor specific. */
14359 /* Assuming this is the last IE, copy at the end */
14360 ie_length -=sizeof(qcom_ie_age);
14361 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
14362 qie_age->element_id = QCOM_VENDOR_IE_ID;
14363 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
14364 qie_age->oui_1 = QCOM_OUI1;
14365 qie_age->oui_2 = QCOM_OUI2;
14366 qie_age->oui_3 = QCOM_OUI3;
14367 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053014368 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
14369 * bss related timestamp is in units of ms. Due to this when scan results
14370 * are sent to lowi the scan age is high.To address this, send age in units
14371 * of 1/10 ms.
14372 */
14373 qie_age->age = (vos_timer_get_system_time() -
14374 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014375#endif
14376
Jeff Johnson295189b2012-06-20 16:38:30 -070014377 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053014378 if (bss_desc->fProbeRsp)
14379 {
14380 mgmt->frame_control |=
14381 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
14382 }
14383 else
14384 {
14385 mgmt->frame_control |=
14386 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
14387 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014388
14389#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014390 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014391 (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014392 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014393 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014394 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014395 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014396 (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014397
14398 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014399 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014400 }
14401 else
14402 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014403 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
14404 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070014405 kfree(mgmt);
14406 return NULL;
14407 }
14408#else
14409 freq = ieee80211_channel_to_frequency(chan_no);
14410#endif
14411 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014412 /*when the band is changed on the fly using the GUI, three things are done
14413 * 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)
14414 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
14415 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
14416 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
14417 * and discards the channels correponding to previous band and calls back with zero bss results.
14418 * 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
14419 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
14420 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
14421 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
14422 * So drop the bss and continue to next bss.
14423 */
14424 if(chan == NULL)
14425 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053014426 hddLog(VOS_TRACE_LEVEL_ERROR,
14427 FL("chan pointer is NULL, chan_no: %d freq: %d"),
14428 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070014429 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014430 return NULL;
14431 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053014432 /*To keep the rssi icon of the connected AP in the scan window
14433 *and the rssi icon of the wireless networks in sync
14434 * */
14435 if (( eConnectionState_Associated ==
14436 pAdapter->sessionCtx.station.conn_info.connState ) &&
14437 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
14438 pAdapter->sessionCtx.station.conn_info.bssId,
14439 WNI_CFG_BSSID_LEN)) &&
14440 (pHddCtx->hdd_wlan_suspended == FALSE))
14441 {
14442 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
14443 rssi = (pAdapter->rssi * 100);
14444 }
14445 else
14446 {
14447 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
14448 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014449
Nirav Shah20ac06f2013-12-12 18:14:06 +053014450 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053014451 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
14452 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053014453
Jeff Johnson295189b2012-06-20 16:38:30 -070014454 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
14455 frame_len, rssi, GFP_KERNEL);
14456 kfree(mgmt);
14457 return bss_status;
14458}
14459
14460/*
14461 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
14462 * This function is used to update the BSS data base of CFG8011
14463 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014464struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014465 tCsrRoamInfo *pRoamInfo
14466 )
14467{
14468 tCsrRoamConnectedProfile roamProfile;
14469 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14470 struct cfg80211_bss *bss = NULL;
14471
14472 ENTER();
14473
14474 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
14475 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
14476
14477 if (NULL != roamProfile.pBssDesc)
14478 {
Girish Gowlif4b68022014-08-28 23:18:57 +053014479 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14480 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070014481
14482 if (NULL == bss)
14483 {
14484 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
14485 __func__);
14486 }
14487
14488 sme_RoamFreeConnectProfile(hHal, &roamProfile);
14489 }
14490 else
14491 {
14492 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
14493 __func__);
14494 }
14495 return bss;
14496}
14497
14498/*
14499 * FUNCTION: wlan_hdd_cfg80211_update_bss
14500 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014501static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
14502 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070014503 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014504{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014505 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014506 tCsrScanResultInfo *pScanResult;
14507 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014508 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014509 tScanResultHandle pResult;
14510 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014511 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014512 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070014513 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014514
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014515 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14516 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
14517 NO_SESSION, pAdapter->sessionId));
14518
Wilson Yangf80a0542013-10-07 13:02:37 -070014519 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014520 ret = wlan_hdd_validate_context(pHddCtx);
14521 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070014522 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014523 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070014524 }
14525
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014526 if (pAdapter->request != NULL)
14527 {
14528 if ((pAdapter->request->n_ssids == 1)
14529 && (pAdapter->request->ssids != NULL)
14530 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
14531 is_p2p_scan = true;
14532 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014533 /*
14534 * start getting scan results and populate cgf80211 BSS database
14535 */
14536 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
14537
14538 /* no scan results */
14539 if (NULL == pResult)
14540 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014541 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
14542 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014543 wlan_hdd_get_frame_logs(pAdapter,
14544 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070014545 return status;
14546 }
14547
14548 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
14549
14550 while (pScanResult)
14551 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014552 /*
14553 * cfg80211_inform_bss() is not updating ie field of bss entry, if
14554 * entry already exists in bss data base of cfg80211 for that
14555 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
14556 * bss entry instead of cfg80211_inform_bss, But this call expects
14557 * mgmt packet as input. As of now there is no possibility to get
14558 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070014559 * ieee80211_mgmt(probe response) and passing to c
14560 * fg80211_inform_bss_frame.
14561 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014562 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
14563 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
14564 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014565 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14566 continue; //Skip the non p2p bss entries
14567 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014568 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14569 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014570
Jeff Johnson295189b2012-06-20 16:38:30 -070014571
14572 if (NULL == bss_status)
14573 {
14574 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014575 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014576 }
14577 else
14578 {
Yue Maf49ba872013-08-19 12:04:25 -070014579 cfg80211_put_bss(
14580#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
14581 wiphy,
14582#endif
14583 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070014584 }
14585
14586 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14587 }
14588
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014589 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014590 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014591 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014592}
14593
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014594void
14595hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
14596{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014597 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080014598 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014599} /****** end hddPrintMacAddr() ******/
14600
14601void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014602hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014603{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014604 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014605 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014606 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
14607 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
14608 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014609} /****** end hddPrintPmkId() ******/
14610
14611//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
14612//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
14613
14614//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
14615//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
14616
14617#define dump_bssid(bssid) \
14618 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014619 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
14620 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014621 }
14622
14623#define dump_pmkid(pMac, pmkid) \
14624 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014625 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
14626 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014627 }
14628
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070014629#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014630/*
14631 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
14632 * This function is used to notify the supplicant of a new PMKSA candidate.
14633 */
14634int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014635 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014636 int index, bool preauth )
14637{
Jeff Johnsone7245742012-09-05 17:12:55 -070014638#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014639 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014640 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014641
14642 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070014643 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014644
14645 if( NULL == pRoamInfo )
14646 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014647 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014648 return -EINVAL;
14649 }
14650
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014651 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
14652 {
14653 dump_bssid(pRoamInfo->bssid);
14654 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014655 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014656 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014657#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014658 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014659}
14660#endif //FEATURE_WLAN_LFR
14661
Yue Maef608272013-04-08 23:09:17 -070014662#ifdef FEATURE_WLAN_LFR_METRICS
14663/*
14664 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
14665 * 802.11r/LFR metrics reporting function to report preauth initiation
14666 *
14667 */
14668#define MAX_LFR_METRICS_EVENT_LENGTH 100
14669VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
14670 tCsrRoamInfo *pRoamInfo)
14671{
14672 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14673 union iwreq_data wrqu;
14674
14675 ENTER();
14676
14677 if (NULL == pAdapter)
14678 {
14679 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14680 return VOS_STATUS_E_FAILURE;
14681 }
14682
14683 /* create the event */
14684 memset(&wrqu, 0, sizeof(wrqu));
14685 memset(metrics_notification, 0, sizeof(metrics_notification));
14686
14687 wrqu.data.pointer = metrics_notification;
14688 wrqu.data.length = scnprintf(metrics_notification,
14689 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
14690 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14691
14692 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14693
14694 EXIT();
14695
14696 return VOS_STATUS_SUCCESS;
14697}
14698
14699/*
14700 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
14701 * 802.11r/LFR metrics reporting function to report preauth completion
14702 * or failure
14703 */
14704VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
14705 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
14706{
14707 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14708 union iwreq_data wrqu;
14709
14710 ENTER();
14711
14712 if (NULL == pAdapter)
14713 {
14714 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14715 return VOS_STATUS_E_FAILURE;
14716 }
14717
14718 /* create the event */
14719 memset(&wrqu, 0, sizeof(wrqu));
14720 memset(metrics_notification, 0, sizeof(metrics_notification));
14721
14722 scnprintf(metrics_notification, sizeof(metrics_notification),
14723 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
14724 MAC_ADDR_ARRAY(pRoamInfo->bssid));
14725
14726 if (1 == preauth_status)
14727 strncat(metrics_notification, " TRUE", 5);
14728 else
14729 strncat(metrics_notification, " FALSE", 6);
14730
14731 wrqu.data.pointer = metrics_notification;
14732 wrqu.data.length = strlen(metrics_notification);
14733
14734 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14735
14736 EXIT();
14737
14738 return VOS_STATUS_SUCCESS;
14739}
14740
14741/*
14742 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
14743 * 802.11r/LFR metrics reporting function to report handover initiation
14744 *
14745 */
14746VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
14747 tCsrRoamInfo *pRoamInfo)
14748{
14749 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14750 union iwreq_data wrqu;
14751
14752 ENTER();
14753
14754 if (NULL == pAdapter)
14755 {
14756 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14757 return VOS_STATUS_E_FAILURE;
14758 }
14759
14760 /* create the event */
14761 memset(&wrqu, 0, sizeof(wrqu));
14762 memset(metrics_notification, 0, sizeof(metrics_notification));
14763
14764 wrqu.data.pointer = metrics_notification;
14765 wrqu.data.length = scnprintf(metrics_notification,
14766 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14767 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14768
14769 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14770
14771 EXIT();
14772
14773 return VOS_STATUS_SUCCESS;
14774}
14775#endif
14776
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014777
14778/**
14779 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14780 * @scan_req: scan request to be checked
14781 *
14782 * Return: true or false
14783 */
14784#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14785static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14786 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014787 *scan_req, hdd_context_t
14788 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014789{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014790 if (!scan_req || !scan_req->wiphy ||
14791 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014792 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14793 return false;
14794 }
14795 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14796 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14797 return false;
14798 }
14799 return true;
14800}
14801#else
14802static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14803 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014804 *scan_req, hdd_context_t
14805 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014806{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014807 if (!scan_req || !scan_req->wiphy ||
14808 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014809 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14810 return false;
14811 }
14812 return true;
14813}
14814#endif
14815
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014816#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
14817/**
14818 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14819 * @adapter: Pointer to the adapter
14820 * @req : Scan request
14821 * @aborted : true scan aborted false scan success
14822 *
14823 * This function notifies scan done to cfg80211
14824 *
14825 * Return: none
14826 */
14827static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14828 struct cfg80211_scan_request *req,
14829 bool aborted)
14830{
14831 struct cfg80211_scan_info info = {
14832 .aborted = aborted
14833 };
14834
14835 if (adapter->dev->flags & IFF_UP)
14836 cfg80211_scan_done(req, &info);
14837 else
14838 hddLog(LOGW,
14839 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14840}
14841#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14842/**
14843 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14844 * @adapter: Pointer to the adapter
14845 * @req : Scan request
14846 * @aborted : true scan aborted false scan success
14847 *
14848 * This function notifies scan done to cfg80211
14849 *
14850 * Return: none
14851 */
14852static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14853 struct cfg80211_scan_request *req,
14854 bool aborted)
14855{
14856 if (adapter->dev->flags & IFF_UP)
14857 cfg80211_scan_done(req, aborted);
14858 else
14859 hddLog(LOGW,
14860 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14861}
14862#else
14863/**
14864 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14865 * @adapter: Pointer to the adapter
14866 * @req : Scan request
14867 * @aborted : true scan aborted false scan success
14868 *
14869 * This function notifies scan done to cfg80211
14870 *
14871 * Return: none
14872 */
14873static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14874 struct cfg80211_scan_request *req,
14875 bool aborted)
14876{
14877 cfg80211_scan_done(req, aborted);
14878}
14879#endif
14880
Mukul Sharmab392b642017-08-17 17:45:29 +053014881#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014882/*
14883 * FUNCTION: hdd_cfg80211_scan_done_callback
14884 * scanning callback function, called after finishing scan
14885 *
14886 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014887static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014888 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14889{
14890 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014891 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014892 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014893 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014894 struct cfg80211_scan_request *req = NULL;
14895 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014896 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014897 long waitRet = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014898 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014899
14900 ENTER();
14901
c_manjee1b4ab9a2016-10-26 11:36:55 +053014902 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14903 !pAdapter->dev) {
14904 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14905 return 0;
14906 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014907 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014908 if (NULL == pHddCtx) {
14909 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014910 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014911 }
14912
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014913#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014914 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014915 {
14916 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014917 }
14918#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014919 pScanInfo = &pHddCtx->scan_info;
14920
Jeff Johnson295189b2012-06-20 16:38:30 -070014921 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014922 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014923 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014924 __func__, halHandle, pContext, (int) scanId, (int) status);
14925
Kiet Lamac06e2c2013-10-23 16:25:07 +053014926 pScanInfo->mScanPendingCounter = 0;
14927
Jeff Johnson295189b2012-06-20 16:38:30 -070014928 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014929 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014930 &pScanInfo->scan_req_completion_event,
14931 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014932 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014933 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014934 hddLog(VOS_TRACE_LEVEL_ERROR,
14935 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014936 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014937 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014938 }
14939
Yue Maef608272013-04-08 23:09:17 -070014940 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014941 {
14942 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014943 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014944 }
14945
14946 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014947 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014948 {
14949 hddLog(VOS_TRACE_LEVEL_INFO,
14950 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014951 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014952 (int) scanId);
14953 }
14954
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014955#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014956 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014957#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014958 {
14959 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14960 pAdapter);
14961 if (0 > ret)
14962 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014963 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014964
Jeff Johnson295189b2012-06-20 16:38:30 -070014965 /* If any client wait scan result through WEXT
14966 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014967 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014968 {
14969 /* The other scan request waiting for current scan finish
14970 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014971 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014972 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014973 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014974 }
14975 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014976 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014977 {
14978 struct net_device *dev = pAdapter->dev;
14979 union iwreq_data wrqu;
14980 int we_event;
14981 char *msg;
14982
14983 memset(&wrqu, '\0', sizeof(wrqu));
14984 we_event = SIOCGIWSCAN;
14985 msg = NULL;
14986 wireless_send_event(dev, we_event, &wrqu, msg);
14987 }
14988 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014989 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014990
14991 /* Get the Scan Req */
14992 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014993 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014994
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014995 /* Scan is no longer pending */
14996 pScanInfo->mScanPending = VOS_FALSE;
14997
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014998 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070014999 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053015000#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
15001 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053015002 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053015003#endif
15004
15005 if (pAdapter->dev) {
15006 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
15007 pAdapter->dev->name);
15008 }
mukul sharmae7041822015-12-03 15:09:21 +053015009 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070015010 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070015011 }
15012
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015013 /* last_scan_timestamp is used to decide if new scan
15014 * is needed or not on station interface. If last station
15015 * scan time and new station scan time is less then
15016 * last_scan_timestamp ; driver will return cached scan.
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015017 * Also only last_scan_timestamp is updated here last_scan_channellist
15018 * is updated on receiving scan request itself to make sure kernel
15019 * allocated scan request(scan_req) object is not dereferenced here,
15020 * because interface down, where kernel frees scan_req, may happen any
15021 * time while driver is processing scan_done_callback. So it's better
15022 * not to access scan_req in this routine.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015023 */
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015024 if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
15025 if (status == eCSR_SCAN_SUCCESS)
15026 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
15027 else {
15028 vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
15029 sizeof(pHddCtx->scan_info.last_scan_channelList));
15030 pHddCtx->scan_info.last_scan_numChannels = 0;
15031 pScanInfo->last_scan_timestamp = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015032 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015033 }
15034
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070015035 /*
15036 * cfg80211_scan_done informing NL80211 about completion
15037 * of scanning
15038 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015039 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
15040 {
15041 aborted = true;
15042 }
mukul sharmae7041822015-12-03 15:09:21 +053015043
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015044#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015045 if (NET_DEV_IS_IFF_UP(pAdapter) &&
15046 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015047#endif
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015048 hdd_cfg80211_scan_done(pAdapter, req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053015049
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080015050 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070015051
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015052allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015053 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
15054 ) && (pHddCtx->spoofMacAddr.isEnabled
15055 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053015056 /* Generate new random mac addr for next scan */
15057 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053015058
15059 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
15060 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053015061 }
15062
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015063 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015064 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015065
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015066 /* Acquire wakelock to handle the case where APP's tries to suspend
15067 * immediatly after the driver gets connect request(i.e after scan)
15068 * from supplicant, this result in app's is suspending and not able
15069 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015070 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015071
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015072#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015073 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015074#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015075#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015076 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015077#endif
15078
Jeff Johnson295189b2012-06-20 16:38:30 -070015079 EXIT();
15080 return 0;
15081}
15082
15083/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053015084 * FUNCTION: hdd_isConnectionInProgress
15085 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015086 *
15087 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015088v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
15089 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015090{
15091 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15092 hdd_station_ctx_t *pHddStaCtx = NULL;
15093 hdd_adapter_t *pAdapter = NULL;
15094 VOS_STATUS status = 0;
15095 v_U8_t staId = 0;
15096 v_U8_t *staMac = NULL;
15097
15098 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15099
15100 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15101 {
15102 pAdapter = pAdapterNode->pAdapter;
15103
15104 if( pAdapter )
15105 {
15106 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015107 "%s: Adapter with device mode %s (%d) exists",
15108 __func__, hdd_device_modetoString(pAdapter->device_mode),
15109 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015110 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053015111 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15112 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
15113 (eConnectionState_Connecting ==
15114 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
15115 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015116 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015117 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053015118 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015119 if (session_id && reason)
15120 {
15121 *session_id = pAdapter->sessionId;
15122 *reason = eHDD_CONNECTION_IN_PROGRESS;
15123 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015124 return VOS_TRUE;
15125 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015126 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053015127 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015128 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015129 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015130 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015131 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015132 if (session_id && reason)
15133 {
15134 *session_id = pAdapter->sessionId;
15135 *reason = eHDD_REASSOC_IN_PROGRESS;
15136 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015137 return VOS_TRUE;
15138 }
15139 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015140 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15141 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015142 {
15143 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15144 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Vignesh Viswanathan0ac8e562018-06-14 17:24:10 +053015145 sme_is_sta_key_exchange_in_progress(pHddCtx->hHal,
15146 pAdapter->sessionId))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015147 {
15148 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015149 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015150 "%s: client " MAC_ADDRESS_STR
15151 " is in the middle of WPS/EAPOL exchange.", __func__,
15152 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015153 if (session_id && reason)
15154 {
15155 *session_id = pAdapter->sessionId;
15156 *reason = eHDD_EAPOL_IN_PROGRESS;
15157 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015158 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015159 }
15160 }
15161 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
15162 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
15163 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015164 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15165 ptSapContext pSapCtx = NULL;
15166 pSapCtx = VOS_GET_SAP_CB(pVosContext);
15167 if(pSapCtx == NULL){
15168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15169 FL("psapCtx is NULL"));
15170 return VOS_FALSE;
15171 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015172 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
15173 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015174 if ((pSapCtx->aStaInfo[staId].isUsed) &&
15175 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015176 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015177 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015178
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015179 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015180 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
15181 "middle of WPS/EAPOL exchange.", __func__,
15182 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015183 if (session_id && reason)
15184 {
15185 *session_id = pAdapter->sessionId;
15186 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
15187 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015188 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015189 }
15190 }
15191 }
15192 }
15193 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15194 pAdapterNode = pNext;
15195 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015196 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015197}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015198
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015199/**
15200 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
15201 * to the Scan request
15202 * @scanRequest: Pointer to the csr scan request
15203 * @request: Pointer to the scan request from supplicant
15204 *
15205 * Return: None
15206 */
15207#ifdef CFG80211_SCAN_BSSID
15208static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15209 struct cfg80211_scan_request *request)
15210{
15211 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
15212}
15213#else
15214static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15215 struct cfg80211_scan_request *request)
15216{
15217}
15218#endif
15219
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +053015220#if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \
15221 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
15222/**
15223 * hdd_is_wiphy_scan_random_support() - Check NL80211 scan randomization support
15224 * @wiphy: Pointer to wiphy structure
15225 *
15226 * This function is used to check whether @wiphy supports
15227 * NL80211 scan randomization feature.
15228 *
15229 * Return: If randomization is supported then return true else false.
15230 */
15231static bool
15232hdd_is_wiphy_scan_random_support(struct wiphy *wiphy)
15233{
15234 if (wiphy->features & NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR)
15235 return true;
15236
15237 return false;
15238}
15239
15240/**
15241 * hdd_is_nl_scan_random() - Check for randomization flag in cfg80211 scan
15242 * @nl_scan: cfg80211 scan request
15243 *
15244 * This function is used to check whether scan randomization flag is set for
15245 * current cfg80211 scan request identified by @nl_scan.
15246 *
15247 * Return: If randomization flag is set then return true else false.
15248 */
15249static bool
15250hdd_is_nl_scan_random(struct cfg80211_scan_request *nl_scan)
15251{
15252 if (nl_scan->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)
15253 return true;
15254
15255 return false;
15256}
15257#else
15258static bool
15259hdd_is_wiphy_scan_random_support(struct wiphy *wiphy)
15260{
15261 return false;
15262}
15263
15264static bool
15265hdd_is_nl_scan_random(struct cfg80211_scan_request *nl_scan)
15266{
15267 return false;
15268}
15269#endif
15270
15271/**
15272 * hdd_generate_scan_random_mac() - Generate Random mac addr for cfg80211 scan
15273 * @mac_addr: Input mac-addr from which random-mac address is to be generated
15274 * @mac_mask: Bits of mac_addr which should not be randomized
15275 * @random_mac: Output pointer to hold generated random mac address
15276 *
15277 * This function is used generate random mac address using @mac_addr and
15278 * @mac_mask with following logic:
15279 * Bit value 0 in the mask means that we should randomize that bit.
15280 * Bit value 1 in the mask means that we should take specific bit value
15281 * from mac address provided.
15282 *
15283 * Return: None
15284 */
15285static void
15286hdd_generate_scan_random_mac(uint8_t *mac_addr, uint8_t *mac_mask,
15287 uint8_t *random_mac)
15288{
15289 uint32_t i;
15290 uint8_t random_byte;
15291
15292 for (i = 0; i < VOS_MAC_ADDRESS_LEN; i++) {
15293 random_byte = 0;
15294 get_random_bytes(&random_byte, 1);
15295 random_mac[i] = (mac_addr[i] & mac_mask[i]) |
15296 (random_byte & (~(mac_mask[i])));
15297 }
15298
15299 /*
15300 * Make sure locally administered bit is set if that
15301 * particular bit in the mask is 0
15302 */
15303 if (!(mac_mask[0] & 0x2))
15304 random_mac[0] |= 0x2;
15305
15306 /*
15307 * Make sure multicast/group address bit is NOT set if that
15308 * particular bit in the mask is 0
15309 */
15310 if (!(mac_mask[0] & 0x1))
15311 random_mac[0] &= ~0x1;
15312}
15313
15314/**
15315 * hdd_spoof_scan() - Spoof cfg80211 scan
15316 * @wiphy: Pointer to wiphy
15317 * @adapter: Pointer to adapter for which scan is requested
15318 * @nl_scan: Cfg80211 scan request
15319 * @is_p2p_scan: Check for p2p scan
15320 * @csr_scan: Pointer to internal (csr) scan request
15321 *
15322 * This function is used for following purposes:
15323 * (a) If cfg80211 supports scan randomization then this function invokes helper
15324 * functions to generate random-mac address.
15325 * (b) If the cfg80211 doesn't support scan randomization then randomize scans
15326 * using spoof mac received with VENDOR_SUBCMD_MAC_OUI.
15327 * (c) Configure the random-mac in transport layer.
15328 *
15329 * Return: For success return 0 else return negative value.
15330 */
15331static int
15332hdd_spoof_scan(struct wiphy *wiphy, hdd_adapter_t *adapter,
15333 struct cfg80211_scan_request *nl_scan,
15334 bool is_p2p_scan, tCsrScanRequest *csr_scan)
15335{
15336 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
15337 hdd_config_t *config = hdd_ctx->cfg_ini;
15338 uint8_t random_mac[VOS_MAC_ADDRESS_LEN];
15339 VOS_STATUS vos_status;
15340 eHalStatus hal_status;
15341
15342 csr_scan->nl_scan = true;
15343 csr_scan->scan_randomize = false;
15344
15345 if (config->enableMacSpoofing != MAC_ADDR_SPOOFING_FW_HOST_ENABLE ||
15346 !sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN))
15347 return 0;
15348
15349 vos_flush_delayed_work(&hdd_ctx->spoof_mac_addr_work);
15350
15351 if (hdd_is_wiphy_scan_random_support(wiphy)) {
15352 if (!hdd_is_nl_scan_random(nl_scan) || is_p2p_scan)
15353 return 0;
15354
15355 hdd_generate_scan_random_mac(nl_scan->mac_addr,
15356 nl_scan->mac_addr_mask,
15357 random_mac);
15358
15359 hddLog(VOS_TRACE_LEVEL_INFO,
15360 FL("cfg80211 scan random attributes:"));
15361 hddLog(VOS_TRACE_LEVEL_INFO, "mac-addr: "MAC_ADDRESS_STR
15362 " mac-mask: "MAC_ADDRESS_STR
15363 " random-mac: "MAC_ADDRESS_STR,
15364 MAC_ADDR_ARRAY(nl_scan->mac_addr),
15365 MAC_ADDR_ARRAY(nl_scan->mac_addr_mask),
15366 MAC_ADDR_ARRAY(random_mac));
15367
15368 hal_status = sme_SpoofMacAddrReq(hdd_ctx->hHal,
15369 (v_MACADDR_t *)random_mac,
15370 false);
15371 if (hal_status != eHAL_STATUS_SUCCESS) {
15372 hddLog(LOGE,
15373 FL("Send of Spoof request failed"));
15374 hddLog(LOGE,
15375 FL("Disable spoofing and use self-mac"));
15376 return 0;
15377 }
15378
15379 vos_status = WLANTL_updateSpoofMacAddr(hdd_ctx->pvosContext,
15380 (v_MACADDR_t*)random_mac,
15381 &adapter->macAddressCurrent);
15382 if(vos_status != VOS_STATUS_SUCCESS) {
15383 hddLog(VOS_TRACE_LEVEL_ERROR,
15384 FL("Failed to update spoof mac in TL"));
15385 return -EINVAL;
15386 }
15387
15388 csr_scan->scan_randomize = true;
15389
15390 return 0;
15391 }
15392
15393 /*
15394 * If wiphy does not support cfg80211 scan randomization then scan
15395 * will be randomized using the vendor MAC OUI.
15396 */
15397 if (!hdd_ctx->spoofMacAddr.isEnabled)
15398 return 0;
15399
15400 hddLog(VOS_TRACE_LEVEL_INFO,
15401 FL("MAC Spoofing enabled for current scan and spoof addr is:"
15402 MAC_ADDRESS_STR),
15403 MAC_ADDR_ARRAY(hdd_ctx->spoofMacAddr.randomMacAddr.bytes));
15404
15405 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15406 * to fill TxBds for probe request during current scan
15407 */
15408 vos_status = WLANTL_updateSpoofMacAddr(hdd_ctx->pvosContext,
15409 &hdd_ctx->spoofMacAddr.randomMacAddr, &adapter->macAddressCurrent);
15410 if(vos_status != VOS_STATUS_SUCCESS) {
15411 hddLog(VOS_TRACE_LEVEL_ERROR,
15412 FL("Failed to update spoof mac in TL"));
15413 return -EINVAL;
15414 }
15415
15416 csr_scan->scan_randomize = true;
15417
15418 return 0;
15419}
15420
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015421/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015422 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070015423 * this scan respond to scan trigger and update cfg80211 scan database
15424 * later, scan dump command can be used to recieve scan results
15425 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015426int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015427#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15428 struct net_device *dev,
15429#endif
15430 struct cfg80211_scan_request *request)
15431{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015432 hdd_adapter_t *pAdapter = NULL;
15433 hdd_context_t *pHddCtx = NULL;
15434 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015435 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015436 tCsrScanRequest scanRequest;
15437 tANI_U8 *channelList = NULL, i;
15438 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015439 int status;
15440 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015441 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015442 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053015443 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015444 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015445 v_U8_t curr_session_id;
15446 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070015447
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015448#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
15449 struct net_device *dev = NULL;
15450 if (NULL == request)
15451 {
15452 hddLog(VOS_TRACE_LEVEL_ERROR,
15453 "%s: scan req param null", __func__);
15454 return -EINVAL;
15455 }
15456 dev = request->wdev->netdev;
15457#endif
15458
15459 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15460 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
15461 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15462
Jeff Johnson295189b2012-06-20 16:38:30 -070015463 ENTER();
15464
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015465 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
15466 __func__, hdd_device_modetoString(pAdapter->device_mode),
15467 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015468
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015469 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015470 if (0 != status)
15471 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015472 return status;
15473 }
15474
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015475 if (NULL == pwextBuf)
15476 {
15477 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
15478 __func__);
15479 return -EIO;
15480 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015481 cfg_param = pHddCtx->cfg_ini;
15482 pScanInfo = &pHddCtx->scan_info;
15483
Jeff Johnson295189b2012-06-20 16:38:30 -070015484#ifdef WLAN_BTAMP_FEATURE
15485 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015486 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070015487 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015488 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015489 "%s: No scanning when AMP is on", __func__);
15490 return -EOPNOTSUPP;
15491 }
15492#endif
15493 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015494 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070015495 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015496 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015497 "%s: Not scanning on device_mode = %s (%d)",
15498 __func__, hdd_device_modetoString(pAdapter->device_mode),
15499 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015500 return -EOPNOTSUPP;
15501 }
15502
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015503 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
15504 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
15505 return -EOPNOTSUPP;
15506 }
15507
Jeff Johnson295189b2012-06-20 16:38:30 -070015508 if (TRUE == pScanInfo->mScanPending)
15509 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015510 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
15511 {
15512 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
15513 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015514 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015515 }
15516
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053015517 // Don't allow scan if PNO scan is going on.
15518 if (pHddCtx->isPnoEnable)
15519 {
15520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15521 FL("pno scan in progress"));
15522 return -EBUSY;
15523 }
15524
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015525 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070015526 //Channel and action frame is pending
15527 //Otherwise Cancel Remain On Channel and allow Scan
15528 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015529 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070015530 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015531 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070015532 return -EBUSY;
15533 }
15534
Jeff Johnson295189b2012-06-20 16:38:30 -070015535 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
15536 {
15537 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080015538 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015539 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015540 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015541 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
15542 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015543 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015544 "%s: MAX TM Level Scan not allowed", __func__);
15545 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015546 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015547 }
15548 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
15549
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015550 /* Check if scan is allowed at this point of time.
15551 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053015552 if (TRUE == pHddCtx->btCoexModeSet)
15553 {
15554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15555 FL("BTCoex Mode operation in progress"));
15556 return -EBUSY;
15557 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015558 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015559 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015560
15561 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
15562 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
15563 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015564 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
15565 pHddCtx->last_scan_reject_reason != curr_reason ||
15566 !pHddCtx->last_scan_reject_timestamp)
15567 {
15568 pHddCtx->last_scan_reject_session_id = curr_session_id;
15569 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053015570 pHddCtx->last_scan_reject_timestamp =
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015571 jiffies + msecs_to_jiffies(SCAN_REJECT_THRESHOLD_TIME);
Abhishek Singhe4b12562017-06-20 16:53:39 +053015572 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053015573 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053015574 else
15575 {
15576 pHddCtx->scan_reject_cnt++;
15577
Abhishek Singhe4b12562017-06-20 16:53:39 +053015578 if ((pHddCtx->scan_reject_cnt >=
15579 SCAN_REJECT_THRESHOLD) &&
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015580 vos_system_time_after(jiffies,
Abhishek Singh3e500772017-07-17 10:13:43 +053015581 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015582 {
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015583 hddLog(LOGE, FL("Session %d reason %d reject cnt %d reject timestamp %lu jiffies %lu"),
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015584 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015585 pHddCtx->last_scan_reject_timestamp, jiffies);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015586 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015587 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015588 if (pHddCtx->cfg_ini->enableFatalEvent)
15589 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
15590 WLAN_LOG_INDICATOR_HOST_DRIVER,
15591 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
15592 FALSE, FALSE);
15593 else
15594 {
15595 hddLog(LOGE, FL("Triggering SSR"));
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +053015596 vos_wlanRestart(VOS_SCAN_REQ_EXPIRED);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015597 }
15598 }
15599 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015600 return -EBUSY;
15601 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015602 pHddCtx->last_scan_reject_timestamp = 0;
15603 pHddCtx->last_scan_reject_session_id = 0xFF;
15604 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015605 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015606
Jeff Johnson295189b2012-06-20 16:38:30 -070015607 vos_mem_zero( &scanRequest, sizeof(scanRequest));
15608
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015609 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
15610 * Becasue of this, driver is assuming that this is not wildcard scan and so
15611 * is not aging out the scan results.
15612 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053015613 if ((request->ssids) && (request->n_ssids == 1) &&
15614 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015615 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015616 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015617
15618 if ((request->ssids) && (0 < request->n_ssids))
15619 {
15620 tCsrSSIDInfo *SsidInfo;
15621 int j;
15622 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
15623 /* Allocate num_ssid tCsrSSIDInfo structure */
15624 SsidInfo = scanRequest.SSIDs.SSIDList =
15625 ( tCsrSSIDInfo *)vos_mem_malloc(
15626 request->n_ssids*sizeof(tCsrSSIDInfo));
15627
15628 if(NULL == scanRequest.SSIDs.SSIDList)
15629 {
15630 hddLog(VOS_TRACE_LEVEL_ERROR,
15631 "%s: memory alloc failed SSIDInfo buffer", __func__);
15632 return -ENOMEM;
15633 }
15634
15635 /* copy all the ssid's and their length */
15636 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
15637 {
15638 /* get the ssid length */
15639 SsidInfo->SSID.length = request->ssids[j].ssid_len;
15640 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
15641 SsidInfo->SSID.length);
15642 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
15643 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
15644 j, SsidInfo->SSID.ssId);
15645 }
15646 /* set the scan type to active */
15647 scanRequest.scanType = eSIR_ACTIVE_SCAN;
15648 }
15649 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015650 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015651 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15652 TRACE_CODE_HDD_CFG80211_SCAN,
15653 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070015654 /* set the scan type to active */
15655 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070015656 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015657 else
15658 {
15659 /*Set the scan type to default type, in this case it is ACTIVE*/
15660 scanRequest.scanType = pScanInfo->scan_mode;
15661 }
15662 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
15663 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070015664
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015665 csr_scan_request_assign_bssid(&scanRequest, request);
15666
Jeff Johnson295189b2012-06-20 16:38:30 -070015667 /* set BSSType to default type */
15668 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
15669
15670 /*TODO: scan the requested channels only*/
15671
15672 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015673 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070015674 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015675 hddLog(VOS_TRACE_LEVEL_WARN,
15676 "No of Scan Channels exceeded limit: %d", request->n_channels);
15677 request->n_channels = MAX_CHANNEL;
15678 }
15679
15680 hddLog(VOS_TRACE_LEVEL_INFO,
15681 "No of Scan Channels: %d", request->n_channels);
15682
15683
15684 if( request->n_channels )
15685 {
15686 char chList [(request->n_channels*5)+1];
15687 int len;
15688 channelList = vos_mem_malloc( request->n_channels );
15689 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053015690 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015691 hddLog(VOS_TRACE_LEVEL_ERROR,
15692 "%s: memory alloc failed channelList", __func__);
15693 status = -ENOMEM;
15694 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053015695 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015696
15697 for( i = 0, len = 0; i < request->n_channels ; i++ )
15698 {
15699 channelList[i] = request->channels[i]->hw_value;
15700 len += snprintf(chList+len, 5, "%d ", channelList[i]);
15701 }
15702
Nirav Shah20ac06f2013-12-12 18:14:06 +053015703 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015704 "Channel-List: %s ", chList);
15705 }
c_hpothu53512302014-04-15 18:49:53 +053015706
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015707 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
15708 scanRequest.ChannelInfo.ChannelList = channelList;
15709
15710 /* set requestType to full scan */
15711 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
15712
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015713 /* if there is back to back scan happening in driver with in
15714 * nDeferScanTimeInterval interval driver should defer new scan request
15715 * and should provide last cached scan results instead of new channel list.
15716 * This rule is not applicable if scan is p2p scan.
15717 * This condition will work only in case when last request no of channels
15718 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053015719 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053015720 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015721 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015722
Sushant Kaushik86592172015-04-27 16:35:03 +053015723 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
15724 /* if wps ie is NULL , then only defer scan */
15725 if ( pWpsIe == NULL &&
15726 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053015727 {
15728 if ( pScanInfo->last_scan_timestamp !=0 &&
15729 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
15730 {
15731 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
15732 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
15733 vos_mem_compare(pScanInfo->last_scan_channelList,
15734 channelList, pScanInfo->last_scan_numChannels))
15735 {
15736 hddLog(VOS_TRACE_LEVEL_WARN,
15737 " New and old station scan time differ is less then %u",
15738 pHddCtx->cfg_ini->nDeferScanTimeInterval);
15739
15740 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015741 pAdapter);
15742
Agarwal Ashish57e84372014-12-05 18:26:53 +053015743 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015744 "Return old cached scan as all channels and no of channels are same");
15745
Agarwal Ashish57e84372014-12-05 18:26:53 +053015746 if (0 > ret)
15747 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015748
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015749 hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015750
15751 status = eHAL_STATUS_SUCCESS;
15752 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053015753 }
15754 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015755 }
15756
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015757 /* Flush the scan results(only p2p beacons) for STA scan and P2P
15758 * search (Flush on both full scan and social scan but not on single
15759 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
15760 */
15761
15762 /* Supplicant does single channel scan after 8-way handshake
15763 * and in that case driver shoudnt flush scan results. If
15764 * driver flushes the scan results here and unfortunately if
15765 * the AP doesnt respond to our probe req then association
15766 * fails which is not desired
15767 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015768 if ((request->n_ssids == 1)
15769 && (request->ssids != NULL)
15770 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
15771 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015772
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015773 if( is_p2p_scan ||
15774 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015775 {
15776 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
15777 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
15778 pAdapter->sessionId );
15779 }
15780
15781 if( request->ie_len )
15782 {
15783 /* save this for future association (join requires this) */
15784 /*TODO: Array needs to be converted to dynamic allocation,
15785 * as multiple ie.s can be sent in cfg80211_scan_request structure
15786 * CR 597966
15787 */
15788 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
15789 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
15790 pScanInfo->scanAddIE.length = request->ie_len;
15791
15792 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15793 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15794 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015795 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015796 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070015797 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015798 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
15799 memcpy( pwextBuf->roamProfile.addIEScan,
15800 request->ie, request->ie_len);
15801 }
15802 else
15803 {
15804 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
15805 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070015806 }
15807
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015808 }
15809 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
15810 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
15811
15812 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
15813 request->ie_len);
15814 if (pP2pIe != NULL)
15815 {
15816#ifdef WLAN_FEATURE_P2P_DEBUG
15817 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
15818 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
15819 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053015820 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015821 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
15822 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15823 "Go nego completed to Connection is started");
15824 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15825 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053015826 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015827 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
15828 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015829 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015830 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
15831 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15832 "Disconnected state to Connection is started");
15833 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15834 "for 4way Handshake");
15835 }
15836#endif
15837
15838 /* no_cck will be set during p2p find to disable 11b rates */
15839 if(TRUE == request->no_cck)
15840 {
15841 hddLog(VOS_TRACE_LEVEL_INFO,
15842 "%s: This is a P2P Search", __func__);
15843 scanRequest.p2pSearch = 1;
15844
15845 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053015846 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015847 /* set requestType to P2P Discovery */
15848 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
15849 }
15850
15851 /*
15852 Skip Dfs Channel in case of P2P Search
15853 if it is set in ini file
15854 */
15855 if(cfg_param->skipDfsChnlInP2pSearch)
15856 {
15857 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015858 }
15859 else
15860 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015861 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015862 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015863
Agarwal Ashish4f616132013-12-30 23:32:50 +053015864 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015865 }
15866 }
15867
15868 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
15869
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015870#ifdef FEATURE_WLAN_TDLS
15871 /* if tdls disagree scan right now, return immediately.
15872 tdls will schedule the scan when scan is allowed. (return SUCCESS)
15873 or will reject the scan if any TDLS is in progress. (return -EBUSY)
15874 */
15875 status = wlan_hdd_tdls_scan_callback (pAdapter,
15876 wiphy,
15877#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15878 dev,
15879#endif
15880 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015881 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015882 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053015883 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015884 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
15885 "scan rejected %d", __func__, status);
15886 else
15887 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
15888 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015889 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053015890 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015891 }
15892#endif
15893
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015894 /* acquire the wakelock to avoid the apps suspend during the scan. To
15895 * address the following issues.
15896 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
15897 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
15898 * for long time, this result in apps running at full power for long time.
15899 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
15900 * be stuck in full power because of resume BMPS
15901 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015902 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015903
Nirav Shah20ac06f2013-12-12 18:14:06 +053015904 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
15905 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015906 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
15907 scanRequest.requestType, scanRequest.scanType,
15908 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053015909 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
15910
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +053015911 ret = hdd_spoof_scan(wiphy, pAdapter, request, is_p2p_scan, &scanRequest);
15912 if(ret) {
15913 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
15914 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053015915#ifdef FEATURE_WLAN_TDLS
15916 wlan_hdd_tdls_scan_done_callback(pAdapter);
15917#endif
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +053015918 goto free_mem;
Siddharth Bhal76972212014-10-15 16:22:51 +053015919 }
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +053015920
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053015921 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070015922 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015923 pAdapter->sessionId, &scanRequest, &scanId,
15924 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070015925
Jeff Johnson295189b2012-06-20 16:38:30 -070015926 if (eHAL_STATUS_SUCCESS != status)
15927 {
15928 hddLog(VOS_TRACE_LEVEL_ERROR,
15929 "%s: sme_ScanRequest returned error %d", __func__, status);
15930 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015931 if(eHAL_STATUS_RESOURCES == status)
15932 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015933 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
15934 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015935 status = -EBUSY;
15936 } else {
15937 status = -EIO;
15938 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015939 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015940
15941#ifdef FEATURE_WLAN_TDLS
15942 wlan_hdd_tdls_scan_done_callback(pAdapter);
15943#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015944 goto free_mem;
15945 }
15946
15947 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015948 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070015949 pAdapter->request = request;
15950 pScanInfo->scanId = scanId;
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015951 pScanInfo->no_cck = request->no_cck;
15952 pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
15953 for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
15954 pHddCtx->scan_info.last_scan_channelList[i] =
15955 request->channels[i]->hw_value;
15956 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015957
15958 complete(&pScanInfo->scan_req_completion_event);
15959
15960free_mem:
15961 if( scanRequest.SSIDs.SSIDList )
15962 {
15963 vos_mem_free(scanRequest.SSIDs.SSIDList);
15964 }
15965
15966 if( channelList )
15967 vos_mem_free( channelList );
15968
15969 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015970 return status;
15971}
15972
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015973int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
15974#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15975 struct net_device *dev,
15976#endif
15977 struct cfg80211_scan_request *request)
15978{
15979 int ret;
15980
15981 vos_ssr_protect(__func__);
15982 ret = __wlan_hdd_cfg80211_scan(wiphy,
15983#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15984 dev,
15985#endif
15986 request);
15987 vos_ssr_unprotect(__func__);
15988
15989 return ret;
15990}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015991
15992void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
15993{
15994 v_U8_t iniDot11Mode =
15995 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
15996 eHddDot11Mode hddDot11Mode = iniDot11Mode;
15997
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015998 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
15999 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016000 switch ( iniDot11Mode )
16001 {
16002 case eHDD_DOT11_MODE_AUTO:
16003 case eHDD_DOT11_MODE_11ac:
16004 case eHDD_DOT11_MODE_11ac_ONLY:
16005#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053016006 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
16007 sme_IsFeatureSupportedByFW(DOT11AC) )
16008 hddDot11Mode = eHDD_DOT11_MODE_11ac;
16009 else
16010 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016011#else
16012 hddDot11Mode = eHDD_DOT11_MODE_11n;
16013#endif
16014 break;
16015 case eHDD_DOT11_MODE_11n:
16016 case eHDD_DOT11_MODE_11n_ONLY:
16017 hddDot11Mode = eHDD_DOT11_MODE_11n;
16018 break;
16019 default:
16020 hddDot11Mode = iniDot11Mode;
16021 break;
16022 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053016023#ifdef WLAN_FEATURE_AP_HT40_24G
16024 if (operationChannel > SIR_11B_CHANNEL_END)
16025#endif
16026 {
16027 /* This call decides required channel bonding mode */
16028 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016029 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053016030 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053016031 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016032}
16033
Jeff Johnson295189b2012-06-20 16:38:30 -070016034/*
16035 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016036 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070016037 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016038int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053016039 const u8 *ssid, size_t ssid_len, const u8 *bssid,
16040 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070016041{
16042 int status = 0;
16043 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080016044 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053016045 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016046 v_U32_t roamId;
16047 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070016048 eCsrAuthType RSNAuthType;
16049
16050 ENTER();
16051
16052 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080016053 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053016054 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080016055
16056 status = wlan_hdd_validate_context(pHddCtx);
16057 if (status)
16058 {
Yue Mae36e3552014-03-05 17:06:20 -080016059 return status;
16060 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016061
Jeff Johnson295189b2012-06-20 16:38:30 -070016062 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
16063 {
16064 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
16065 return -EINVAL;
16066 }
16067
Nitesh Shah9b066282017-06-06 18:05:52 +053016068
Jeff Johnson295189b2012-06-20 16:38:30 -070016069 pRoamProfile = &pWextState->roamProfile;
16070
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016071 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070016072 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016073 hdd_station_ctx_t *pHddStaCtx;
16074 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053016075 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016076
Siddharth Bhalda0d1622015-04-24 15:47:49 +053016077 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
16078
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016079 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070016080 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
16081 {
16082 /*QoS not enabled in cfg file*/
16083 pRoamProfile->uapsd_mask = 0;
16084 }
16085 else
16086 {
16087 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016088 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070016089 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
16090 }
16091
16092 pRoamProfile->SSIDs.numOfSSIDs = 1;
16093 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
16094 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016095 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070016096 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
16097 ssid, ssid_len);
16098
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016099 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
16100 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
16101
Jeff Johnson295189b2012-06-20 16:38:30 -070016102 if (bssid)
16103 {
16104 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016105 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070016106 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016107 /* Save BSSID in seperate variable as well, as RoamProfile
16108 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070016109 case of join failure we should send valid BSSID to supplicant
16110 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016111 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070016112 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016113
Jeff Johnson295189b2012-06-20 16:38:30 -070016114 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016115 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070016116 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016117 /* Store bssid_hint to use in the scan filter. */
16118 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
16119 WNI_CFG_BSSID_LEN);
16120 /*
16121 * Save BSSID in seperate variable as well, as RoamProfile
16122 * BSSID is getting zeroed out in the association process. And in
16123 * case of join failure we should send valid BSSID to supplicant
16124 */
16125 vos_mem_copy(pWextState->req_bssId, bssid_hint,
16126 WNI_CFG_BSSID_LEN);
16127 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
16128 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070016129 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016130
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016131
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053016132 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
16133 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016134 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
16135 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016136 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016137 /*set gen ie*/
16138 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
16139 /*set auth*/
16140 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
16141 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016142#ifdef FEATURE_WLAN_WAPI
16143 if (pAdapter->wapi_info.nWapiMode)
16144 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016145 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016146 switch (pAdapter->wapi_info.wapiAuthMode)
16147 {
16148 case WAPI_AUTH_MODE_PSK:
16149 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016150 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016151 pAdapter->wapi_info.wapiAuthMode);
16152 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
16153 break;
16154 }
16155 case WAPI_AUTH_MODE_CERT:
16156 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016157 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016158 pAdapter->wapi_info.wapiAuthMode);
16159 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
16160 break;
16161 }
16162 } // End of switch
16163 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
16164 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
16165 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016166 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016167 pRoamProfile->AuthType.numEntries = 1;
16168 pRoamProfile->EncryptionType.numEntries = 1;
16169 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
16170 pRoamProfile->mcEncryptionType.numEntries = 1;
16171 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
16172 }
16173 }
16174#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016175#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016176 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016177 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
16178 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
16179 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016180 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
16181 sizeof (tSirGtkOffloadParams));
16182 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016183 }
16184#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016185 pRoamProfile->csrPersona = pAdapter->device_mode;
16186
Jeff Johnson32d95a32012-09-10 13:15:23 -070016187 if( operatingChannel )
16188 {
16189 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
16190 pRoamProfile->ChannelInfo.numOfChannels = 1;
16191 }
Chet Lanctot186b5732013-03-18 10:26:30 -070016192 else
16193 {
16194 pRoamProfile->ChannelInfo.ChannelList = NULL;
16195 pRoamProfile->ChannelInfo.numOfChannels = 0;
16196 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016197 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
16198 {
16199 hdd_select_cbmode(pAdapter,operatingChannel);
16200 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053016201
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016202 /*
16203 * Change conn_state to connecting before sme_RoamConnect(),
16204 * because sme_RoamConnect() has a direct path to call
16205 * hdd_smeRoamCallback(), which will change the conn_state
16206 * If direct path, conn_state will be accordingly changed
16207 * to NotConnected or Associated by either
16208 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
16209 * in sme_RoamCallback()
16210 * if sme_RomConnect is to be queued,
16211 * Connecting state will remain until it is completed.
16212 * If connection state is not changed,
16213 * connection state will remain in eConnectionState_NotConnected state.
16214 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
16215 * if conn state is eConnectionState_NotConnected.
16216 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
16217 * informed of connect result indication which is an issue.
16218 */
16219
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016220 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16221 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053016222 {
16223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016224 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016225 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
16226 eConnectionState_Connecting);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016227 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
16228 hdd_wait_for_ecsa_complete(pHddCtx);
Abhishek Singhf4669da2014-05-26 15:07:49 +053016229 }
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016230
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016231 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070016232 pAdapter->sessionId, pRoamProfile, &roamId);
16233
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016234 if ((eHAL_STATUS_SUCCESS != status) &&
16235 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16236 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016237
16238 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016239 hddLog(VOS_TRACE_LEVEL_ERROR,
16240 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
16241 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016242 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016243 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016244 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016245 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016246
16247 pRoamProfile->ChannelInfo.ChannelList = NULL;
16248 pRoamProfile->ChannelInfo.numOfChannels = 0;
16249
Jeff Johnson295189b2012-06-20 16:38:30 -070016250 }
16251 else
16252 {
16253 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
16254 return -EINVAL;
16255 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080016256 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016257 return status;
16258}
16259
16260/*
16261 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
16262 * This function is used to set the authentication type (OPEN/SHARED).
16263 *
16264 */
16265static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
16266 enum nl80211_auth_type auth_type)
16267{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016268 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016269 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16270
16271 ENTER();
16272
16273 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016274 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070016275 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016276 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016277 hddLog(VOS_TRACE_LEVEL_INFO,
16278 "%s: set authentication type to AUTOSWITCH", __func__);
16279 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
16280 break;
16281
16282 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016283#ifdef WLAN_FEATURE_VOWIFI_11R
16284 case NL80211_AUTHTYPE_FT:
16285#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016286 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016287 "%s: set authentication type to OPEN", __func__);
16288 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
16289 break;
16290
16291 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016292 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016293 "%s: set authentication type to SHARED", __func__);
16294 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
16295 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016296#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016297 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016298 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016299 "%s: set authentication type to CCKM WPA", __func__);
16300 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
16301 break;
16302#endif
16303
16304
16305 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016306 hddLog(VOS_TRACE_LEVEL_ERROR,
16307 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016308 auth_type);
16309 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
16310 return -EINVAL;
16311 }
16312
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016313 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016314 pHddStaCtx->conn_info.authType;
16315 return 0;
16316}
16317
16318/*
16319 * FUNCTION: wlan_hdd_set_akm_suite
16320 * This function is used to set the key mgmt type(PSK/8021x).
16321 *
16322 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016323static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016324 u32 key_mgmt
16325 )
16326{
16327 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16328 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053016329 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016330#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016331#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016332#endif
16333#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016334#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016335#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016336 /*set key mgmt type*/
16337 switch(key_mgmt)
16338 {
16339 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053016340 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016341#ifdef WLAN_FEATURE_VOWIFI_11R
16342 case WLAN_AKM_SUITE_FT_PSK:
16343#endif
16344 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070016345 __func__);
16346 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
16347 break;
16348
16349 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053016350 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016351#ifdef WLAN_FEATURE_VOWIFI_11R
16352 case WLAN_AKM_SUITE_FT_8021X:
16353#endif
16354 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070016355 __func__);
16356 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16357 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016358#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016359#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
16360#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
16361 case WLAN_AKM_SUITE_CCKM:
16362 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
16363 __func__);
16364 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
16365 break;
16366#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070016367#ifndef WLAN_AKM_SUITE_OSEN
16368#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
16369 case WLAN_AKM_SUITE_OSEN:
16370 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
16371 __func__);
16372 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16373 break;
16374#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016375
16376 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016377 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016378 __func__, key_mgmt);
16379 return -EINVAL;
16380
16381 }
16382 return 0;
16383}
16384
16385/*
16386 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016387 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070016388 * (NONE/WEP40/WEP104/TKIP/CCMP).
16389 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016390static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
16391 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070016392 bool ucast
16393 )
16394{
16395 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016396 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016397 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16398
16399 ENTER();
16400
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016401 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016402 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053016403 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070016404 __func__, cipher);
16405 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16406 }
16407 else
16408 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016409
Jeff Johnson295189b2012-06-20 16:38:30 -070016410 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016411 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016412 {
16413 case IW_AUTH_CIPHER_NONE:
16414 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16415 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016416
Jeff Johnson295189b2012-06-20 16:38:30 -070016417 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016418 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070016419 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016420
Jeff Johnson295189b2012-06-20 16:38:30 -070016421 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016422 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070016423 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016424
Jeff Johnson295189b2012-06-20 16:38:30 -070016425 case WLAN_CIPHER_SUITE_TKIP:
16426 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
16427 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016428
Jeff Johnson295189b2012-06-20 16:38:30 -070016429 case WLAN_CIPHER_SUITE_CCMP:
16430 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16431 break;
16432#ifdef FEATURE_WLAN_WAPI
16433 case WLAN_CIPHER_SUITE_SMS4:
16434 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
16435 break;
16436#endif
16437
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016438#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016439 case WLAN_CIPHER_SUITE_KRK:
16440 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
16441 break;
16442#endif
16443 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016444 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016445 __func__, cipher);
16446 return -EOPNOTSUPP;
16447 }
16448 }
16449
16450 if (ucast)
16451 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016452 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016453 __func__, encryptionType);
16454 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16455 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016456 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016457 encryptionType;
16458 }
16459 else
16460 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016461 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016462 __func__, encryptionType);
16463 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
16464 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
16465 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
16466 }
16467
16468 return 0;
16469}
16470
16471
16472/*
16473 * FUNCTION: wlan_hdd_cfg80211_set_ie
16474 * This function is used to parse WPA/RSN IE's.
16475 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016476int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016477#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16478 const u8 *ie,
16479#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016480 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016481#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016482 size_t ie_len
16483 )
16484{
16485 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016486#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16487 const u8 *genie = ie;
16488#else
Jeff Johnson295189b2012-06-20 16:38:30 -070016489 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016490#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016491 v_U16_t remLen = ie_len;
16492#ifdef FEATURE_WLAN_WAPI
16493 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
16494 u16 *tmp;
16495 v_U16_t akmsuiteCount;
16496 int *akmlist;
16497#endif
16498 ENTER();
16499
16500 /* clear previous assocAddIE */
16501 pWextState->assocAddIE.length = 0;
16502 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016503 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016504
16505 while (remLen >= 2)
16506 {
16507 v_U16_t eLen = 0;
16508 v_U8_t elementId;
16509 elementId = *genie++;
16510 eLen = *genie++;
16511 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016512
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053016513 /* Sanity check on eLen */
16514 if (eLen > remLen) {
16515 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
16516 __func__, eLen, elementId);
16517 VOS_ASSERT(0);
16518 return -EINVAL;
16519 }
16520
Arif Hussain6d2a3322013-11-17 19:50:10 -080016521 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070016522 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016523
16524 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070016525 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016526 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016527 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 -070016528 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016529 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016530 "%s: Invalid WPA IE", __func__);
16531 return -EINVAL;
16532 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016533 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070016534 {
16535 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016536 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016537 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016538
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016539 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016540 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016541 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
16542 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016543 VOS_ASSERT(0);
16544 return -ENOMEM;
16545 }
16546 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16547 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16548 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016549
Jeff Johnson295189b2012-06-20 16:38:30 -070016550 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
16551 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16552 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16553 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016554 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
16555 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053016556 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16557 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
16558 __func__, eLen);
16559 VOS_ASSERT(0);
16560 return -EINVAL;
16561 }
16562
Jeff Johnson295189b2012-06-20 16:38:30 -070016563 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
16564 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16565 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
16566 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
16567 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
16568 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016569 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053016570 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070016571 {
16572 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016573 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016574 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016575
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016576 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016577 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016578 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16579 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016580 VOS_ASSERT(0);
16581 return -ENOMEM;
16582 }
16583 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16584 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16585 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016586
Jeff Johnson295189b2012-06-20 16:38:30 -070016587 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16588 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16589 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016590#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016591 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
16592 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016593 /*Consider WFD IE, only for P2P Client */
16594 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
16595 {
16596 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016597 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016598 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016599
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016600 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016601 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016602 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16603 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016604 VOS_ASSERT(0);
16605 return -ENOMEM;
16606 }
16607 // WFD IE is saved to Additional IE ; it should be accumulated to handle
16608 // WPS IE + P2P IE + WFD IE
16609 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16610 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016611
Jeff Johnson295189b2012-06-20 16:38:30 -070016612 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16613 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16614 }
16615#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016616 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016617 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016618 HS20_OUI_TYPE_SIZE)) )
16619 {
16620 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016621 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016622 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016623
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016624 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016625 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016626 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16627 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016628 VOS_ASSERT(0);
16629 return -ENOMEM;
16630 }
16631 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16632 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016633
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016634 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16635 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16636 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016637 /* Appending OSEN Information Element in Assiciation Request */
16638 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
16639 OSEN_OUI_TYPE_SIZE)) )
16640 {
16641 v_U16_t curAddIELen = pWextState->assocAddIE.length;
16642 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
16643 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016644
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016645 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016646 {
16647 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16648 "Need bigger buffer space");
16649 VOS_ASSERT(0);
16650 return -ENOMEM;
16651 }
16652 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16653 pWextState->assocAddIE.length += eLen + 2;
16654
16655 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
16656 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16657 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16658 }
16659
Abhishek Singh4322e622015-06-10 15:42:54 +053016660 /* Update only for WPA IE */
16661 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
16662 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016663
16664 /* populating as ADDIE in beacon frames */
16665 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016666 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016667 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
16668 {
16669 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16670 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
16671 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16672 {
16673 hddLog(LOGE,
16674 "Coldn't pass "
16675 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
16676 }
16677 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
16678 else
16679 hddLog(LOGE,
16680 "Could not pass on "
16681 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
16682
16683 /* IBSS mode doesn't contain params->proberesp_ies still
16684 beaconIE's need to be populated in probe response frames */
16685 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
16686 {
16687 u16 rem_probe_resp_ie_len = eLen + 2;
16688 u8 probe_rsp_ie_len[3] = {0};
16689 u8 counter = 0;
16690
16691 /* Check Probe Resp Length if it is greater then 255 then
16692 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
16693 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
16694 not able Store More then 255 bytes into One Variable */
16695
16696 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
16697 {
16698 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
16699 {
16700 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
16701 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
16702 }
16703 else
16704 {
16705 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
16706 rem_probe_resp_ie_len = 0;
16707 }
16708 }
16709
16710 rem_probe_resp_ie_len = 0;
16711
16712 if (probe_rsp_ie_len[0] > 0)
16713 {
16714 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16715 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
16716 (tANI_U8*)(genie - 2),
16717 probe_rsp_ie_len[0], NULL,
16718 eANI_BOOLEAN_FALSE)
16719 == eHAL_STATUS_FAILURE)
16720 {
16721 hddLog(LOGE,
16722 "Could not pass"
16723 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
16724 }
16725 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
16726 }
16727
16728 if (probe_rsp_ie_len[1] > 0)
16729 {
16730 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16731 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
16732 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16733 probe_rsp_ie_len[1], NULL,
16734 eANI_BOOLEAN_FALSE)
16735 == eHAL_STATUS_FAILURE)
16736 {
16737 hddLog(LOGE,
16738 "Could not pass"
16739 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
16740 }
16741 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
16742 }
16743
16744 if (probe_rsp_ie_len[2] > 0)
16745 {
16746 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16747 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
16748 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16749 probe_rsp_ie_len[2], NULL,
16750 eANI_BOOLEAN_FALSE)
16751 == eHAL_STATUS_FAILURE)
16752 {
16753 hddLog(LOGE,
16754 "Could not pass"
16755 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
16756 }
16757 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
16758 }
16759
16760 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16761 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
16762 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16763 {
16764 hddLog(LOGE,
16765 "Could not pass"
16766 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
16767 }
16768 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016769 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070016770 break;
16771 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053016772 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16773 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
16774 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
16775 VOS_ASSERT(0);
16776 return -EINVAL;
16777 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016778 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
16779 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16780 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
16781 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
16782 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16783 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016784
Abhishek Singhb16f3562016-01-20 11:08:32 +053016785 /* Appending extended capabilities with Interworking or
16786 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016787 *
16788 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016789 * interworkingService or bsstransition bit is set to 1.
16790 * Driver is only interested in interworkingService and
16791 * bsstransition capability from supplicant.
16792 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016793 * required from supplicat, it needs to be handled while
16794 * sending Assoc Req in LIM.
16795 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016796 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016797 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016798 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016799 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016800 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016801
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016802 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016803 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016804 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16805 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016806 VOS_ASSERT(0);
16807 return -ENOMEM;
16808 }
16809 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16810 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016811
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016812 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16813 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16814 break;
16815 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016816#ifdef FEATURE_WLAN_WAPI
16817 case WLAN_EID_WAPI:
16818 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016819 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016820 pAdapter->wapi_info.nWapiMode);
16821 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016822 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016823 akmsuiteCount = WPA_GET_LE16(tmp);
16824 tmp = tmp + 1;
16825 akmlist = (int *)(tmp);
16826 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16827 {
16828 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16829 }
16830 else
16831 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016832 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016833 VOS_ASSERT(0);
16834 return -EINVAL;
16835 }
16836
16837 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16838 {
16839 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016840 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016841 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016842 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016843 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016844 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016845 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016846 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016847 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
16848 }
16849 break;
16850#endif
16851 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016852 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016853 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016854 /* when Unknown IE is received we should break and continue
16855 * to the next IE in the buffer instead we were returning
16856 * so changing this to break */
16857 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016858 }
16859 genie += eLen;
16860 remLen -= eLen;
16861 }
16862 EXIT();
16863 return 0;
16864}
16865
16866/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016867 * FUNCTION: hdd_isWPAIEPresent
16868 * Parse the received IE to find the WPA IE
16869 *
16870 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016871static bool hdd_isWPAIEPresent(
16872#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16873 const u8 *ie,
16874#else
16875 u8 *ie,
16876#endif
16877 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016878{
16879 v_U8_t eLen = 0;
16880 v_U16_t remLen = ie_len;
16881 v_U8_t elementId = 0;
16882
16883 while (remLen >= 2)
16884 {
16885 elementId = *ie++;
16886 eLen = *ie++;
16887 remLen -= 2;
16888 if (eLen > remLen)
16889 {
16890 hddLog(VOS_TRACE_LEVEL_ERROR,
16891 "%s: IE length is wrong %d", __func__, eLen);
16892 return FALSE;
16893 }
16894 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16895 {
16896 /* OUI - 0x00 0X50 0XF2
16897 WPA Information Element - 0x01
16898 WPA version - 0x01*/
16899 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16900 return TRUE;
16901 }
16902 ie += eLen;
16903 remLen -= eLen;
16904 }
16905 return FALSE;
16906}
16907
16908/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016909 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016910 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016911 * parameters during connect operation.
16912 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016913int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016914 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016915 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016916{
16917 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016918 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016919 ENTER();
16920
16921 /*set wpa version*/
16922 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
16923
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016924 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016925 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053016926 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016927 {
16928 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16929 }
16930 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
16931 {
16932 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16933 }
16934 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016935
16936 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016937 pWextState->wpaVersion);
16938
16939 /*set authentication type*/
16940 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
16941
16942 if (0 > status)
16943 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016944 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016945 "%s: failed to set authentication type ", __func__);
16946 return status;
16947 }
16948
16949 /*set key mgmt type*/
16950 if (req->crypto.n_akm_suites)
16951 {
16952 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
16953 if (0 > status)
16954 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016955 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070016956 __func__);
16957 return status;
16958 }
16959 }
16960
16961 /*set pairwise cipher type*/
16962 if (req->crypto.n_ciphers_pairwise)
16963 {
16964 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
16965 req->crypto.ciphers_pairwise[0], true);
16966 if (0 > status)
16967 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016968 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016969 "%s: failed to set unicast cipher type", __func__);
16970 return status;
16971 }
16972 }
16973 else
16974 {
16975 /*Reset previous cipher suite to none*/
16976 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
16977 if (0 > status)
16978 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016979 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016980 "%s: failed to set unicast cipher type", __func__);
16981 return status;
16982 }
16983 }
16984
16985 /*set group cipher type*/
16986 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
16987 false);
16988
16989 if (0 > status)
16990 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016991 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070016992 __func__);
16993 return status;
16994 }
16995
Chet Lanctot186b5732013-03-18 10:26:30 -070016996#ifdef WLAN_FEATURE_11W
16997 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
16998#endif
16999
Jeff Johnson295189b2012-06-20 16:38:30 -070017000 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
17001 if (req->ie_len)
17002 {
17003 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
17004 if ( 0 > status)
17005 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017006 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070017007 __func__);
17008 return status;
17009 }
17010 }
17011
17012 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017013 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070017014 {
17015 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
17016 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
17017 )
17018 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017019 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070017020 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
17021 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017022 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017023 __func__);
17024 return -EOPNOTSUPP;
17025 }
17026 else
17027 {
17028 u8 key_len = req->key_len;
17029 u8 key_idx = req->key_idx;
17030
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017031 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070017032 && (CSR_MAX_NUM_KEY > key_idx)
17033 )
17034 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017035 hddLog(VOS_TRACE_LEVEL_INFO,
17036 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017037 __func__, key_idx, key_len);
17038 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017039 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070017040 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017041 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070017042 (u8)key_len;
17043 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
17044 }
17045 }
17046 }
17047 }
17048
17049 return status;
17050}
17051
17052/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017053 * FUNCTION: wlan_hdd_try_disconnect
17054 * This function is used to disconnect from previous
17055 * connection
17056 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053017057int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017058{
17059 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017060 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017061 hdd_station_ctx_t *pHddStaCtx;
17062 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053017063 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017064
Abhishek Singh19a7dd92015-12-30 16:31:51 +053017065 ret = wlan_hdd_validate_context(pHddCtx);
17066 if (0 != ret)
17067 {
17068 return ret;
17069 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017070 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17071
17072 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
17073
17074 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
17075 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053017076 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017077 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
17078 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053017079 /* Indicate disconnect to SME so that in-progress connection or preauth
17080 * can be aborted
17081 */
17082 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
17083 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053017084 spin_lock_bh(&pAdapter->lock_for_active_session);
17085 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
17086 {
17087 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
17088 }
17089 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053017090 hdd_connSetConnectionState(pHddStaCtx,
17091 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017092 /* Issue disconnect to CSR */
17093 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017094 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017095 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017096 eCSR_DISCONNECT_REASON_UNSPECIFIED);
17097 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
17098 hddLog(LOG1,
17099 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
17100 } else if ( 0 != status ) {
17101 hddLog(LOGE,
17102 FL("csrRoamDisconnect failure, returned %d"),
17103 (int)status );
17104 result = -EINVAL;
17105 goto disconnected;
17106 }
17107 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017108 &pAdapter->disconnect_comp_var,
17109 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017110 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
17111 hddLog(LOGE,
17112 "%s: Failed to disconnect, timed out", __func__);
17113 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017114 }
17115 }
17116 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
17117 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017118 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017119 &pAdapter->disconnect_comp_var,
17120 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017121 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017122 {
17123 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017124 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017125 }
17126 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017127disconnected:
17128 hddLog(LOG1,
17129 FL("Set HDD connState to eConnectionState_NotConnected"));
17130 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
17131 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017132}
17133
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017134/**
17135 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
17136 * @adapter: Pointer to the HDD adapter
17137 * @req: Pointer to the structure cfg_connect_params receieved from user space
17138 *
Abhinav Kumar42c34902018-09-27 19:00:35 +053017139 * This function will start reassociation if prev_bssid is set and bssid/
17140 * bssid_hint, channel/channel_hint parameters are present in connect request.
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017141 *
17142 * Return: success if reassociation is happening
17143 * Error code if reassociation is not permitted or not happening
17144 */
17145#ifdef CFG80211_CONNECT_PREV_BSSID
17146static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
17147 struct cfg80211_connect_params *req)
17148{
17149 int status = -EPERM;
Abhinav Kumar42c34902018-09-27 19:00:35 +053017150 const uint8_t *bssid = NULL;
17151 uint16_t channel = 0;
17152
17153 if (req->bssid)
17154 bssid = req->bssid;
17155 else if (req->bssid_hint)
17156 bssid = req->bssid_hint;
17157
17158 if (req->channel)
17159 channel = req->channel->hw_value;
17160 else if (req->channel_hint)
17161 channel = req->channel_hint->hw_value;
17162
17163 if (bssid && channel && req->prev_bssid) {
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017164 hddLog(VOS_TRACE_LEVEL_INFO,
17165 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
Abhinav Kumar42c34902018-09-27 19:00:35 +053017166 channel, MAC_ADDR_ARRAY(bssid));
17167 status = hdd_reassoc(adapter, bssid, channel,
17168 CONNECT_CMD_USERSPACE);
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017169 }
17170 return status;
17171}
17172#else
17173static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
17174 struct cfg80211_connect_params *req)
17175{
17176 return -EPERM;
17177}
17178#endif
17179
Abhishek Singhe3beee22017-07-31 15:35:40 +053017180/**
17181 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
17182 * connect in HT20 mode
17183 * @hdd_ctx: hdd context
17184 * @adapter: Pointer to the HDD adapter
17185 * @req: Pointer to the structure cfg_connect_params receieved from user space
17186 *
17187 * This function will check if supplicant has indicated to to connect in HT20
17188 * mode. this is currently applicable only for 2.4Ghz mode only.
17189 * if feature is enabled and supplicant indicate HT20 set
17190 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
17191 *
17192 * Return: void
17193 */
17194#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
17195static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
17196 hdd_adapter_t *adapter,
17197 struct cfg80211_connect_params *req)
17198{
17199 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
17200 tCsrRoamProfile *roam_profile;
17201
17202 roam_profile = &wext_state->roamProfile;
17203 roam_profile->force_24ghz_in_ht20 = false;
17204 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
17205 !(req->ht_capa.cap_info &
17206 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
17207 roam_profile->force_24ghz_in_ht20 = true;
17208
17209 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
17210 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
17211}
17212#else
17213static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
17214 hdd_adapter_t *adapter,
17215 struct cfg80211_connect_params *req)
17216{
17217 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
17218 tCsrRoamProfile *roam_profile;
17219
17220 roam_profile = &wext_state->roamProfile;
17221 roam_profile->force_24ghz_in_ht20 = false;
17222}
17223#endif
17224
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017225/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053017226 * FUNCTION: __wlan_hdd_cfg80211_connect
17227 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070017228 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017229static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017230 struct net_device *ndev,
17231 struct cfg80211_connect_params *req
17232 )
17233{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017234 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017235 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053017236#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
17237 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017238 const u8 *bssid_hint = req->bssid_hint;
17239#else
17240 const u8 *bssid_hint = NULL;
17241#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017242 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017243 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053017244 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017245
17246 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017247
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017248 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17249 TRACE_CODE_HDD_CFG80211_CONNECT,
17250 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017251 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017252 "%s: device_mode = %s (%d)", __func__,
17253 hdd_device_modetoString(pAdapter->device_mode),
17254 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017255
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017256 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017257 if (!pHddCtx)
17258 {
17259 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17260 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053017261 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017262 }
17263
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017264 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017265 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017266 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017267 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017268 }
17269
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053017270 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
17271 return -EINVAL;
17272
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017273 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
17274 if (0 == status)
17275 return status;
17276
Agarwal Ashish51325b52014-06-16 16:50:49 +053017277
Jeff Johnson295189b2012-06-20 16:38:30 -070017278#ifdef WLAN_BTAMP_FEATURE
17279 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017280 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070017281 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017282 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017283 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080017284 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070017285 }
17286#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017287
17288 //If Device Mode is Station Concurrent Sessions Exit BMps
17289 //P2P Mode will be taken care in Open/close adapter
17290 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053017291 (vos_concurrent_open_sessions_running())) {
17292 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
17293 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017294 }
17295
17296 /*Try disconnecting if already in connected state*/
17297 status = wlan_hdd_try_disconnect(pAdapter);
17298 if ( 0 > status)
17299 {
17300 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17301 " connection"));
17302 return -EALREADY;
17303 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053017304 /* Check for max concurrent connections after doing disconnect if any*/
17305 if (vos_max_concurrent_connections_reached()) {
17306 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17307 return -ECONNREFUSED;
17308 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017309
Jeff Johnson295189b2012-06-20 16:38:30 -070017310 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017311 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070017312
17313 if ( 0 > status)
17314 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017315 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070017316 __func__);
17317 return status;
17318 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053017319
17320 if (pHddCtx->spoofMacAddr.isEnabled)
17321 {
17322 hddLog(VOS_TRACE_LEVEL_INFO,
17323 "%s: MAC Spoofing enabled ", __func__);
17324 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
17325 * to fill TxBds for probe request during SSID scan which may happen
17326 * as part of connect command
17327 */
17328 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
17329 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
17330 if (status != VOS_STATUS_SUCCESS)
17331 return -ECONNREFUSED;
17332 }
17333
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017334 if (req->channel)
17335 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070017336 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017337 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053017338
17339 /* Abort if any scan is going on */
17340 status = wlan_hdd_scan_abort(pAdapter);
17341 if (0 != status)
17342 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
17343
Abhishek Singhe3beee22017-07-31 15:35:40 +053017344 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
17345
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017346 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
17347 req->ssid_len, req->bssid,
17348 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017349
Sushant Kaushikd7083982015-03-18 14:33:24 +053017350 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017351 {
17352 //ReEnable BMPS if disabled
17353 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
17354 (NULL != pHddCtx))
17355 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053017356 if (pHddCtx->hdd_wlan_suspended)
17357 {
17358 hdd_set_pwrparams(pHddCtx);
17359 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017360 //ReEnable Bmps and Imps back
17361 hdd_enable_bmps_imps(pHddCtx);
17362 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053017363 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070017364 return status;
17365 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017366 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017367 EXIT();
17368 return status;
17369}
17370
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017371static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
17372 struct net_device *ndev,
17373 struct cfg80211_connect_params *req)
17374{
17375 int ret;
17376 vos_ssr_protect(__func__);
17377 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
17378 vos_ssr_unprotect(__func__);
17379
17380 return ret;
17381}
Jeff Johnson295189b2012-06-20 16:38:30 -070017382
17383/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017384 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070017385 * This function is used to issue a disconnect request to SME
17386 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017387static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017388 struct net_device *dev,
17389 u16 reason
17390 )
17391{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017392 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017393 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017394 tCsrRoamProfile *pRoamProfile;
17395 hdd_station_ctx_t *pHddStaCtx;
17396 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017397#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017398 tANI_U8 staIdx;
17399#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017400
Jeff Johnson295189b2012-06-20 16:38:30 -070017401 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017402
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017403 if (!pAdapter) {
17404 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17405 return -EINVAL;
17406 }
17407
17408 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17409 if (!pHddStaCtx) {
17410 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
17411 return -EINVAL;
17412 }
17413
17414 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17415 status = wlan_hdd_validate_context(pHddCtx);
17416 if (0 != status)
17417 {
17418 return status;
17419 }
17420
17421 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
17422
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017423 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17424 TRACE_CODE_HDD_CFG80211_DISCONNECT,
17425 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017426 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
17427 __func__, hdd_device_modetoString(pAdapter->device_mode),
17428 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017429
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017430 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
17431 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070017432
Jeff Johnson295189b2012-06-20 16:38:30 -070017433 if (NULL != pRoamProfile)
17434 {
17435 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017436 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
17437 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070017438 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017439 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070017440 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017441 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070017442 switch(reason)
17443 {
17444 case WLAN_REASON_MIC_FAILURE:
17445 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
17446 break;
17447
17448 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
17449 case WLAN_REASON_DISASSOC_AP_BUSY:
17450 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
17451 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
17452 break;
17453
17454 case WLAN_REASON_PREV_AUTH_NOT_VALID:
17455 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053017456 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070017457 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
17458 break;
17459
Jeff Johnson295189b2012-06-20 16:38:30 -070017460 default:
17461 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
17462 break;
17463 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017464 pScanInfo = &pHddCtx->scan_info;
17465 if (pScanInfo->mScanPending)
17466 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017467 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017468 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053017469 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017470 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017471 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053017472 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017473#ifdef FEATURE_WLAN_TDLS
17474 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017475 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017476 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017477 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
17478 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017479 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017480 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017481 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017483 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017484 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017485 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017486 status = sme_DeleteTdlsPeerSta(
17487 WLAN_HDD_GET_HAL_CTX(pAdapter),
17488 pAdapter->sessionId,
17489 mac);
17490 if (status != eHAL_STATUS_SUCCESS) {
17491 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
17492 return -EPERM;
17493 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017494 }
17495 }
17496#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053017497
17498 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
17499 reasonCode,
17500 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017501 status = wlan_hdd_disconnect(pAdapter, reasonCode);
17502 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070017503 {
17504 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017505 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017506 __func__, (int)status );
17507 return -EINVAL;
17508 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017509 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017510 else
17511 {
17512 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
17513 "called while in %d state", __func__,
17514 pHddStaCtx->conn_info.connState);
17515 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017516 }
17517 else
17518 {
17519 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
17520 }
17521
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017522 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017523 return status;
17524}
17525
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017526static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
17527 struct net_device *dev,
17528 u16 reason
17529 )
17530{
17531 int ret;
17532 vos_ssr_protect(__func__);
17533 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
17534 vos_ssr_unprotect(__func__);
17535
17536 return ret;
17537}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017538
Jeff Johnson295189b2012-06-20 16:38:30 -070017539/*
17540 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017541 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070017542 * settings in IBSS mode.
17543 */
17544static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017545 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070017546 struct cfg80211_ibss_params *params
17547 )
17548{
17549 int status = 0;
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017550 tANI_U32 ret;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017551 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070017552 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
17553 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017554
Jeff Johnson295189b2012-06-20 16:38:30 -070017555 ENTER();
17556
17557 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070017558 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070017559
17560 if (params->ie_len && ( NULL != params->ie) )
17561 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017562 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17563 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017564 {
17565 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
17566 encryptionType = eCSR_ENCRYPT_TYPE_AES;
17567 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017568 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017569 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017570 tDot11fIEWPA dot11WPAIE;
17571 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017572 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017573
Wilson Yang00256342013-10-10 23:13:38 -070017574 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017575 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17576 params->ie_len, DOT11F_EID_WPA);
17577 if ( NULL != ie )
17578 {
17579 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
Hanumanth Reddy Pothulad6d2d2c2018-06-27 12:28:12 +053017580
17581 if (ie[1] < DOT11F_IE_WPA_MIN_LEN ||
17582 ie[1] > DOT11F_IE_WPA_MAX_LEN) {
17583 hddLog(LOGE, FL("invalid ie len:%d"), ie[1]);
17584 return -EINVAL;
17585 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017586 // Unpack the WPA IE
17587 //Skip past the EID byte and length byte - and four byte WiFi OUI
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017588 ret = dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017589 &ie[2+4],
17590 ie[1] - 4,
17591 &dot11WPAIE);
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017592 if (DOT11F_FAILED(ret))
17593 {
17594 hddLog(LOGE,
17595 FL("unpack failed status:(0x%08x)"),
17596 ret);
17597 return -EINVAL;
17598 }
17599
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017600 /*Extract the multicast cipher, the encType for unicast
17601 cipher for wpa-none is none*/
17602 encryptionType =
17603 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
17604 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017605 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017606
Jeff Johnson295189b2012-06-20 16:38:30 -070017607 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
17608
17609 if (0 > status)
17610 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017611 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070017612 __func__);
17613 return status;
17614 }
17615 }
17616
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017617 pWextState->roamProfile.AuthType.authType[0] =
17618 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070017619 eCSR_AUTH_TYPE_OPEN_SYSTEM;
Jeff Johnson295189b2012-06-20 16:38:30 -070017620 if (params->privacy)
17621 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017622 /* Security enabled IBSS, At this time there is no information available
17623 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070017624 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017625 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070017626 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017627 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070017628 *enable privacy bit in beacons */
17629
17630 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
17631 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017632 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17633 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070017634 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
17635 pWextState->roamProfile.EncryptionType.numEntries = 1;
17636 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070017637 return status;
17638}
17639
17640/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017641 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017642 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017643 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017644static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017645 struct net_device *dev,
17646 struct cfg80211_ibss_params *params
17647 )
17648{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017649 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017650 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17651 tCsrRoamProfile *pRoamProfile;
17652 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017653 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17654 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017655 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070017656
17657 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017658
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017659 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17660 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
17661 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017662 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017663 "%s: device_mode = %s (%d)", __func__,
17664 hdd_device_modetoString(pAdapter->device_mode),
17665 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017666
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017667 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017668 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017669 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017670 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017671 }
17672
17673 if (NULL == pWextState)
17674 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017675 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017676 __func__);
17677 return -EIO;
17678 }
17679
Agarwal Ashish51325b52014-06-16 16:50:49 +053017680 if (vos_max_concurrent_connections_reached()) {
17681 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17682 return -ECONNREFUSED;
17683 }
17684
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017685 /*Try disconnecting if already in connected state*/
17686 status = wlan_hdd_try_disconnect(pAdapter);
17687 if ( 0 > status)
17688 {
17689 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17690 " IBSS connection"));
17691 return -EALREADY;
17692 }
17693
Jeff Johnson295189b2012-06-20 16:38:30 -070017694 pRoamProfile = &pWextState->roamProfile;
17695
17696 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
17697 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017698 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017699 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017700 return -EINVAL;
17701 }
17702
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017703 /* BSSID is provided by upper layers hence no need to AUTO generate */
17704 if (NULL != params->bssid) {
17705 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17706 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
17707 hddLog (VOS_TRACE_LEVEL_ERROR,
17708 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17709 return -EIO;
17710 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017711 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017712 }
krunal sonie9002db2013-11-25 14:24:17 -080017713 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
17714 {
17715 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17716 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
17717 {
17718 hddLog (VOS_TRACE_LEVEL_ERROR,
17719 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17720 return -EIO;
17721 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017722
17723 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080017724 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017725 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080017726 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017727
Jeff Johnson295189b2012-06-20 16:38:30 -070017728 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070017729 if (NULL !=
17730#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17731 params->chandef.chan)
17732#else
17733 params->channel)
17734#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017735 {
17736 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017737 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17738 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
17739 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17740 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017741
17742 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017743 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070017744 ieee80211_frequency_to_channel(
17745#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17746 params->chandef.chan->center_freq);
17747#else
17748 params->channel->center_freq);
17749#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017750
17751 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17752 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070017753 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017754 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
17755 __func__);
17756 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070017757 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017758
17759 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017760 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017761 if (channelNum == validChan[indx])
17762 {
17763 break;
17764 }
17765 }
17766 if (indx >= numChans)
17767 {
17768 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017769 __func__, channelNum);
17770 return -EINVAL;
17771 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017772 /* Set the Operational Channel */
17773 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
17774 channelNum);
17775 pRoamProfile->ChannelInfo.numOfChannels = 1;
17776 pHddStaCtx->conn_info.operationChannel = channelNum;
17777 pRoamProfile->ChannelInfo.ChannelList =
17778 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070017779 }
17780
17781 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017782 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070017783 if (status < 0)
17784 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017785 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070017786 __func__);
17787 return status;
17788 }
17789
17790 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017791 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053017792 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017793 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017794
17795 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017796 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017797
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017798 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017799 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017800}
17801
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017802static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17803 struct net_device *dev,
17804 struct cfg80211_ibss_params *params
17805 )
17806{
17807 int ret = 0;
17808
17809 vos_ssr_protect(__func__);
17810 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17811 vos_ssr_unprotect(__func__);
17812
17813 return ret;
17814}
17815
Jeff Johnson295189b2012-06-20 16:38:30 -070017816/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017817 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017818 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017819 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017820static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017821 struct net_device *dev
17822 )
17823{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017824 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017825 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17826 tCsrRoamProfile *pRoamProfile;
17827 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017828 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017829 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017830#ifdef WLAN_FEATURE_RMC
17831 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17832#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017833
17834 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017835
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017836 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17837 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17838 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017839 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017840 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017841 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017842 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017843 }
17844
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017845 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17846 hdd_device_modetoString(pAdapter->device_mode),
17847 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017848 if (NULL == pWextState)
17849 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017850 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017851 __func__);
17852 return -EIO;
17853 }
17854
17855 pRoamProfile = &pWextState->roamProfile;
17856
17857 /* Issue disconnect only if interface type is set to IBSS */
17858 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17859 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017860 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017861 __func__);
17862 return -EINVAL;
17863 }
17864
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017865#ifdef WLAN_FEATURE_RMC
17866 /* Clearing add IE of beacon */
17867 if (ccmCfgSetStr(pHddCtx->hHal,
17868 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17869 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17870 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17871 {
17872 hddLog (VOS_TRACE_LEVEL_ERROR,
17873 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17874 return -EINVAL;
17875 }
17876 if (ccmCfgSetInt(pHddCtx->hHal,
17877 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17878 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17879 {
17880 hddLog (VOS_TRACE_LEVEL_ERROR,
17881 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17882 __func__);
17883 return -EINVAL;
17884 }
17885
17886 // Reset WNI_CFG_PROBE_RSP Flags
17887 wlan_hdd_reset_prob_rspies(pAdapter);
17888
17889 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17890 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17891 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17892 {
17893 hddLog (VOS_TRACE_LEVEL_ERROR,
17894 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17895 __func__);
17896 return -EINVAL;
17897 }
17898#endif
17899
Jeff Johnson295189b2012-06-20 16:38:30 -070017900 /* Issue Disconnect request */
17901 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017902 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17903 pAdapter->sessionId,
17904 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17905 if (!HAL_STATUS_SUCCESS(hal_status)) {
17906 hddLog(LOGE,
17907 FL("sme_RoamDisconnect failed hal_status(%d)"),
17908 hal_status);
17909 return -EAGAIN;
17910 }
17911 status = wait_for_completion_timeout(
17912 &pAdapter->disconnect_comp_var,
17913 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17914 if (!status) {
17915 hddLog(LOGE,
17916 FL("wait on disconnect_comp_var failed"));
17917 return -ETIMEDOUT;
17918 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017919
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017920 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017921 return 0;
17922}
17923
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017924static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17925 struct net_device *dev
17926 )
17927{
17928 int ret = 0;
17929
17930 vos_ssr_protect(__func__);
17931 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17932 vos_ssr_unprotect(__func__);
17933
17934 return ret;
17935}
17936
Jeff Johnson295189b2012-06-20 16:38:30 -070017937/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017938 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017939 * This function is used to set the phy parameters
17940 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17941 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017942static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017943 u32 changed)
17944{
17945 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17946 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017947 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017948
17949 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017950
17951 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017952 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17953 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017954
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017955 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017956 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017957 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017958 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017959 }
17960
Jeff Johnson295189b2012-06-20 16:38:30 -070017961 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17962 {
17963 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17964 WNI_CFG_RTS_THRESHOLD_STAMAX :
17965 wiphy->rts_threshold;
17966
17967 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017968 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017969 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017970 hddLog(VOS_TRACE_LEVEL_ERROR,
17971 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017972 __func__, rts_threshold);
17973 return -EINVAL;
17974 }
17975
17976 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17977 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017978 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017979 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017980 hddLog(VOS_TRACE_LEVEL_ERROR,
17981 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017982 __func__, rts_threshold);
17983 return -EIO;
17984 }
17985
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017986 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017987 rts_threshold);
17988 }
17989
17990 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17991 {
17992 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17993 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17994 wiphy->frag_threshold;
17995
17996 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017997 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017998 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017999 hddLog(VOS_TRACE_LEVEL_ERROR,
18000 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070018001 frag_threshold);
18002 return -EINVAL;
18003 }
18004
18005 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
18006 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018007 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070018008 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018009 hddLog(VOS_TRACE_LEVEL_ERROR,
18010 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018011 __func__, frag_threshold);
18012 return -EIO;
18013 }
18014
18015 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
18016 frag_threshold);
18017 }
18018
18019 if ((changed & WIPHY_PARAM_RETRY_SHORT)
18020 || (changed & WIPHY_PARAM_RETRY_LONG))
18021 {
18022 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
18023 wiphy->retry_short :
18024 wiphy->retry_long;
18025
18026 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
18027 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
18028 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018029 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018030 __func__, retry_value);
18031 return -EINVAL;
18032 }
18033
18034 if (changed & WIPHY_PARAM_RETRY_SHORT)
18035 {
18036 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
18037 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018038 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070018039 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018040 hddLog(VOS_TRACE_LEVEL_ERROR,
18041 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018042 __func__, retry_value);
18043 return -EIO;
18044 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018045 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018046 __func__, retry_value);
18047 }
18048 else if (changed & WIPHY_PARAM_RETRY_SHORT)
18049 {
18050 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
18051 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018052 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070018053 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018054 hddLog(VOS_TRACE_LEVEL_ERROR,
18055 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018056 __func__, retry_value);
18057 return -EIO;
18058 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018059 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018060 __func__, retry_value);
18061 }
18062 }
18063
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018064 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018065 return 0;
18066}
18067
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053018068static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
18069 u32 changed)
18070{
18071 int ret;
18072
18073 vos_ssr_protect(__func__);
18074 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
18075 vos_ssr_unprotect(__func__);
18076
18077 return ret;
18078}
18079
Jeff Johnson295189b2012-06-20 16:38:30 -070018080/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053018081 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070018082 * This function is used to set the txpower
18083 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053018084static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070018085#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18086 struct wireless_dev *wdev,
18087#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018088#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018089 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070018090#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018091 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070018092#endif
18093 int dbm)
18094{
18095 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018096 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070018097 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
18098 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018099 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018100
18101 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018102
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018103 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18104 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
18105 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018106 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018107 if (0 != status)
18108 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018109 return status;
18110 }
18111
18112 hHal = pHddCtx->hHal;
18113
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018114 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
18115 dbm, ccmCfgSetCallback,
18116 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070018117 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018118 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018119 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
18120 return -EIO;
18121 }
18122
18123 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
18124 dbm);
18125
18126 switch(type)
18127 {
18128 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
18129 /* Fall through */
18130 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
18131 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
18132 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018133 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
18134 __func__);
18135 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070018136 }
18137 break;
18138 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018139 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070018140 __func__);
18141 return -EOPNOTSUPP;
18142 break;
18143 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018144 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
18145 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070018146 return -EIO;
18147 }
18148
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018149 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018150 return 0;
18151}
18152
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053018153static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
18154#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18155 struct wireless_dev *wdev,
18156#endif
18157#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
18158 enum tx_power_setting type,
18159#else
18160 enum nl80211_tx_power_setting type,
18161#endif
18162 int dbm)
18163{
18164 int ret;
18165 vos_ssr_protect(__func__);
18166 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
18167#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18168 wdev,
18169#endif
18170#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
18171 type,
18172#else
18173 type,
18174#endif
18175 dbm);
18176 vos_ssr_unprotect(__func__);
18177
18178 return ret;
18179}
18180
Jeff Johnson295189b2012-06-20 16:38:30 -070018181/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018182 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070018183 * This function is used to read the txpower
18184 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018185static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070018186#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18187 struct wireless_dev *wdev,
18188#endif
18189 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070018190{
18191
18192 hdd_adapter_t *pAdapter;
18193 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018194 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018195
Jeff Johnsone7245742012-09-05 17:12:55 -070018196 ENTER();
18197
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018198 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018199 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018200 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018201 *dbm = 0;
18202 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018203 }
18204
Jeff Johnson295189b2012-06-20 16:38:30 -070018205 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
18206 if (NULL == pAdapter)
18207 {
18208 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
18209 return -ENOENT;
18210 }
18211
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018212 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18213 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
18214 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070018215 wlan_hdd_get_classAstats(pAdapter);
18216 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
18217
Jeff Johnsone7245742012-09-05 17:12:55 -070018218 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018219 return 0;
18220}
18221
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018222static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
18223#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18224 struct wireless_dev *wdev,
18225#endif
18226 int *dbm)
18227{
18228 int ret;
18229
18230 vos_ssr_protect(__func__);
18231 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
18232#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18233 wdev,
18234#endif
18235 dbm);
18236 vos_ssr_unprotect(__func__);
18237
18238 return ret;
18239}
18240
Dustin Brown8c1d4092017-07-28 18:08:01 +053018241/*
18242 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
18243 * @stats: summary stats to use as a source
18244 * @info: kernel station_info struct to use as a destination
18245 *
18246 * Return: None
18247 */
18248static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
18249 struct station_info *info)
18250{
18251 int i;
18252
18253 info->rx_packets = stats->rx_frm_cnt;
18254 info->tx_packets = 0;
18255 info->tx_retries = 0;
18256 info->tx_failed = 0;
18257
18258 for (i = 0; i < 4; ++i) {
18259 info->tx_packets += stats->tx_frm_cnt[i];
18260 info->tx_retries += stats->multiple_retry_cnt[i];
18261 info->tx_failed += stats->fail_cnt[i];
18262 }
18263
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018264#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18265 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018266 info->filled |= STATION_INFO_TX_PACKETS |
18267 STATION_INFO_TX_RETRIES |
18268 STATION_INFO_TX_FAILED |
18269 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018270#else
18271 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
18272 BIT(NL80211_STA_INFO_TX_RETRIES) |
18273 BIT(NL80211_STA_INFO_TX_FAILED) |
18274 BIT(NL80211_STA_INFO_RX_PACKETS);
18275#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053018276}
18277
18278/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018279 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
18280 * @adapter: sap adapter pointer
18281 * @staid: station id of the client
18282 * @rssi: rssi value to fill
18283 *
18284 * Return: None
18285 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053018286void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018287wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
18288{
18289 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
18290
18291 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
18292}
18293
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018294#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18295 !defined(WITH_BACKPORTS)
18296static inline void wlan_hdd_fill_station_info_signal(struct station_info
18297 *sinfo)
18298{
18299 sinfo->filled |= STATION_INFO_SIGNAL;
18300}
18301#else
18302static inline void wlan_hdd_fill_station_info_signal(struct station_info
18303 *sinfo)
18304{
18305 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
18306}
18307#endif
18308
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018309/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053018310 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
18311 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018312 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053018313 * @info: kernel station_info struct to populate
18314 *
18315 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
18316 * support "station dump" and "station get" for SAP vdevs, even though they
18317 * aren't technically stations.
18318 *
18319 * Return: errno
18320 */
18321static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018322wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
18323#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18324 const u8* mac,
18325#else
18326 u8* mac,
18327#endif
18328 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018329{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018330 v_MACADDR_t *peerMacAddr;
18331 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018332 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018333 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018334
18335 status = wlan_hdd_get_station_stats(adapter);
18336 if (!VOS_IS_STATUS_SUCCESS(status)) {
18337 hddLog(VOS_TRACE_LEVEL_ERROR,
18338 "Failed to get SAP stats; status:%d", status);
18339 return 0;
18340 }
18341
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018342 peerMacAddr = (v_MACADDR_t *)mac;
18343 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
18344 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
18345 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
18346
18347 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
18348 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018349 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018350 }
18351
Dustin Brown8c1d4092017-07-28 18:08:01 +053018352 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
18353
18354 return 0;
18355}
18356
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018357static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018358#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18359 const u8* mac,
18360#else
18361 u8* mac,
18362#endif
18363 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070018364{
18365 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
18366 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18367 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053018368 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018369
18370 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
18371 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070018372
18373 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
18374 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
18375 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
18376 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
18377 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
18378 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
18379 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018380 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018381 tANI_U16 myRate;
18382 tANI_U16 currentRate = 0;
18383 tANI_U8 maxSpeedMCS = 0;
18384 tANI_U8 maxMCSIdx = 0;
18385 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053018386 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070018387 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018388 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018389
Leo Chang6f8870f2013-03-26 18:11:36 -070018390#ifdef WLAN_FEATURE_11AC
18391 tANI_U32 vht_mcs_map;
18392 eDataRate11ACMaxMcs vhtMaxMcs;
18393#endif /* WLAN_FEATURE_11AC */
18394
Jeff Johnsone7245742012-09-05 17:12:55 -070018395 ENTER();
18396
Dustin Brown8c1d4092017-07-28 18:08:01 +053018397 status = wlan_hdd_validate_context(pHddCtx);
18398 if (0 != status)
18399 {
18400 return status;
18401 }
18402
18403 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018404 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053018405
Jeff Johnson295189b2012-06-20 16:38:30 -070018406 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
18407 (0 == ssidlen))
18408 {
18409 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
18410 " Invalid ssidlen, %d", __func__, ssidlen);
18411 /*To keep GUI happy*/
18412 return 0;
18413 }
18414
Mukul Sharma811205f2014-07-09 21:07:30 +053018415 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
18416 {
18417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18418 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053018419 /* return a cached value */
18420 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053018421 return 0;
18422 }
18423
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053018424 wlan_hdd_get_station_stats(pAdapter);
18425 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018426
Kiet Lam3b17fc82013-09-27 05:24:08 +053018427 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018428 wlan_hdd_get_snr(pAdapter, &snr);
18429 pHddStaCtx->conn_info.signal = sinfo->signal;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018430 pHddStaCtx->cache_conn_info.signal = sinfo->signal;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018431 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018432 pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018433 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053018434
c_hpothu09f19542014-05-30 21:53:31 +053018435 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053018436 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
18437 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053018438 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053018439 {
18440 rate_flags = pAdapter->maxRateFlags;
18441 }
c_hpothu44ff4e02014-05-08 00:13:57 +053018442
Jeff Johnson295189b2012-06-20 16:38:30 -070018443 //convert to the UI units of 100kbps
18444 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
18445
18446#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070018447 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 -070018448 sinfo->signal,
18449 pCfg->reportMaxLinkSpeed,
18450 myRate,
18451 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018452 (int) pCfg->linkSpeedRssiMid,
18453 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070018454 (int) rate_flags,
18455 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070018456#endif //LINKSPEED_DEBUG_ENABLED
18457
Hanumanth Reddy Pothula596b8b32018-05-01 20:17:38 +053018458#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || defined(WITH_BACKPORTS)
18459 /* assume basic BW. anything else will override this later */
18460 sinfo->txrate.bw = RATE_INFO_BW_20;
18461#endif
18462
Jeff Johnson295189b2012-06-20 16:38:30 -070018463 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
18464 {
18465 // we do not want to necessarily report the current speed
18466 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
18467 {
18468 // report the max possible speed
18469 rssidx = 0;
18470 }
18471 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
18472 {
18473 // report the max possible speed with RSSI scaling
18474 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
18475 {
18476 // report the max possible speed
18477 rssidx = 0;
18478 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018479 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070018480 {
18481 // report middle speed
18482 rssidx = 1;
18483 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018484 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
18485 {
18486 // report middle speed
18487 rssidx = 2;
18488 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018489 else
18490 {
18491 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018492 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070018493 }
18494 }
18495 else
18496 {
18497 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
18498 hddLog(VOS_TRACE_LEVEL_ERROR,
18499 "%s: Invalid value for reportMaxLinkSpeed: %u",
18500 __func__, pCfg->reportMaxLinkSpeed);
18501 rssidx = 0;
18502 }
18503
18504 maxRate = 0;
18505
18506 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018507 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
18508 OperationalRates, &ORLeng))
18509 {
18510 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18511 /*To keep GUI happy*/
18512 return 0;
18513 }
18514
Jeff Johnson295189b2012-06-20 16:38:30 -070018515 for (i = 0; i < ORLeng; i++)
18516 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018517 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018518 {
18519 /* Validate Rate Set */
18520 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
18521 {
18522 currentRate = supported_data_rate[j].supported_rate[rssidx];
18523 break;
18524 }
18525 }
18526 /* Update MAX rate */
18527 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18528 }
18529
18530 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018531 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
18532 ExtendedRates, &ERLeng))
18533 {
18534 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18535 /*To keep GUI happy*/
18536 return 0;
18537 }
18538
Jeff Johnson295189b2012-06-20 16:38:30 -070018539 for (i = 0; i < ERLeng; i++)
18540 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018541 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018542 {
18543 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
18544 {
18545 currentRate = supported_data_rate[j].supported_rate[rssidx];
18546 break;
18547 }
18548 }
18549 /* Update MAX rate */
18550 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18551 }
c_hpothu79aab322014-07-14 21:11:01 +053018552
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018553 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053018554 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018555 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053018556 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070018557 {
c_hpothu79aab322014-07-14 21:11:01 +053018558 if (rate_flags & eHAL_TX_RATE_VHT80)
18559 mode = 2;
18560 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
18561 mode = 1;
18562 else
18563 mode = 0;
18564
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018565 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
18566 MCSRates, &MCSLeng))
18567 {
18568 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18569 /*To keep GUI happy*/
18570 return 0;
18571 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018572 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070018573#ifdef WLAN_FEATURE_11AC
18574 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018575 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070018576 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018577 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018578 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070018579 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070018580 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018581 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018582 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018583 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070018584 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018585 maxMCSIdx = 7;
18586 }
18587 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
18588 {
18589 maxMCSIdx = 8;
18590 }
18591 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
18592 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018593 //VHT20 is supporting 0~8
18594 if (rate_flags & eHAL_TX_RATE_VHT20)
18595 maxMCSIdx = 8;
18596 else
18597 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070018598 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018599
c_hpothu79aab322014-07-14 21:11:01 +053018600 if (0 != rssidx)/*check for scaled */
18601 {
18602 //get middle rate MCS index if rssi=1/2
18603 for (i=0; i <= maxMCSIdx; i++)
18604 {
18605 if (sinfo->signal <= rssiMcsTbl[mode][i])
18606 {
18607 maxMCSIdx = i;
18608 break;
18609 }
18610 }
18611 }
18612
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018613 if (rate_flags & eHAL_TX_RATE_VHT80)
18614 {
18615 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
18616 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
18617 }
18618 else if (rate_flags & eHAL_TX_RATE_VHT40)
18619 {
18620 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
18621 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
18622 }
18623 else if (rate_flags & eHAL_TX_RATE_VHT20)
18624 {
18625 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
18626 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
18627 }
18628
Leo Chang6f8870f2013-03-26 18:11:36 -070018629 maxSpeedMCS = 1;
18630 if (currentRate > maxRate)
18631 {
18632 maxRate = currentRate;
18633 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018634
Leo Chang6f8870f2013-03-26 18:11:36 -070018635 }
18636 else
18637#endif /* WLAN_FEATURE_11AC */
18638 {
18639 if (rate_flags & eHAL_TX_RATE_HT40)
18640 {
18641 rateFlag |= 1;
18642 }
18643 if (rate_flags & eHAL_TX_RATE_SGI)
18644 {
18645 rateFlag |= 2;
18646 }
18647
Girish Gowli01abcee2014-07-31 20:18:55 +053018648 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053018649 if (rssidx == 1 || rssidx == 2)
18650 {
18651 //get middle rate MCS index if rssi=1/2
18652 for (i=0; i <= 7; i++)
18653 {
18654 if (sinfo->signal <= rssiMcsTbl[mode][i])
18655 {
18656 temp = i+1;
18657 break;
18658 }
18659 }
18660 }
c_hpothu79aab322014-07-14 21:11:01 +053018661
18662 for (i = 0; i < MCSLeng; i++)
18663 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018664 for (j = 0; j < temp; j++)
18665 {
18666 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
18667 {
18668 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018669 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018670 break;
18671 }
18672 }
18673 if ((j < temp) && (currentRate > maxRate))
18674 {
18675 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070018676 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018677 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018678 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018679 }
18680 }
18681
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018682 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
18683 {
18684 maxRate = myRate;
18685 maxSpeedMCS = 1;
18686 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18687 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018688 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053018689 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070018690 {
18691 maxRate = myRate;
18692 if (rate_flags & eHAL_TX_RATE_LEGACY)
18693 {
18694 maxSpeedMCS = 0;
18695 }
18696 else
18697 {
18698 maxSpeedMCS = 1;
18699 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18700 }
18701 }
18702
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018703 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070018704 {
18705 sinfo->txrate.legacy = maxRate;
18706#ifdef LINKSPEED_DEBUG_ENABLED
18707 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
18708#endif //LINKSPEED_DEBUG_ENABLED
18709 }
18710 else
18711 {
18712 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070018713#ifdef WLAN_FEATURE_11AC
18714 sinfo->txrate.nss = 1;
18715 if (rate_flags & eHAL_TX_RATE_VHT80)
18716 {
18717 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018718#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18719 defined(WITH_BACKPORTS)
18720 sinfo->txrate.bw = RATE_INFO_BW_80;
18721#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018722 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018723#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018724 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018725 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070018726 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018727 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018728#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18729 defined(WITH_BACKPORTS)
18730 sinfo->txrate.bw = RATE_INFO_BW_40;
18731#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018732 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018733#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018734 }
18735 else if (rate_flags & eHAL_TX_RATE_VHT20)
18736 {
18737 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18738 }
18739#endif /* WLAN_FEATURE_11AC */
18740 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
18741 {
18742 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18743 if (rate_flags & eHAL_TX_RATE_HT40)
18744 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018745#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18746 defined(WITH_BACKPORTS)
18747 sinfo->txrate.bw = RATE_INFO_BW_40;
18748#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018749 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018750#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018751 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018752 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018753 if (rate_flags & eHAL_TX_RATE_SGI)
18754 {
18755 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18756 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018757
Jeff Johnson295189b2012-06-20 16:38:30 -070018758#ifdef LINKSPEED_DEBUG_ENABLED
18759 pr_info("Reporting MCS rate %d flags %x\n",
18760 sinfo->txrate.mcs,
18761 sinfo->txrate.flags );
18762#endif //LINKSPEED_DEBUG_ENABLED
18763 }
18764 }
18765 else
18766 {
18767 // report current rate instead of max rate
18768
18769 if (rate_flags & eHAL_TX_RATE_LEGACY)
18770 {
18771 //provide to the UI in units of 100kbps
18772 sinfo->txrate.legacy = myRate;
18773#ifdef LINKSPEED_DEBUG_ENABLED
18774 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
18775#endif //LINKSPEED_DEBUG_ENABLED
18776 }
18777 else
18778 {
18779 //must be MCS
18780 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018781#ifdef WLAN_FEATURE_11AC
18782 sinfo->txrate.nss = 1;
18783 if (rate_flags & eHAL_TX_RATE_VHT80)
18784 {
18785 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18786 }
18787 else
18788#endif /* WLAN_FEATURE_11AC */
18789 {
18790 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18791 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018792 if (rate_flags & eHAL_TX_RATE_SGI)
18793 {
18794 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18795 }
18796 if (rate_flags & eHAL_TX_RATE_HT40)
18797 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018798#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18799 defined(WITH_BACKPORTS)
18800 sinfo->txrate.bw = RATE_INFO_BW_40;
18801#else
Jeff Johnson295189b2012-06-20 16:38:30 -070018802 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018803#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018804 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018805#ifdef WLAN_FEATURE_11AC
18806 else if (rate_flags & eHAL_TX_RATE_VHT80)
18807 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018808#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18809 defined(WITH_BACKPORTS)
18810 sinfo->txrate.bw = RATE_INFO_BW_80;
18811#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018812 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018813#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018814 }
18815#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018816#ifdef LINKSPEED_DEBUG_ENABLED
18817 pr_info("Reporting actual MCS rate %d flags %x\n",
18818 sinfo->txrate.mcs,
18819 sinfo->txrate.flags );
18820#endif //LINKSPEED_DEBUG_ENABLED
18821 }
18822 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018823
18824#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18825 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018826 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018827#else
18828 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18829#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018830
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018831 sinfo->tx_packets =
18832 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18833 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18834 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18835 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18836
18837 sinfo->tx_retries =
18838 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18839 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18840 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18841 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18842
18843 sinfo->tx_failed =
18844 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18845 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18846 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18847 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18848
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018849#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18850 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018851 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018852 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018853 STATION_INFO_TX_PACKETS |
18854 STATION_INFO_TX_RETRIES |
18855 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018856#else
18857 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18858 BIT(NL80211_STA_INFO_TX_PACKETS) |
18859 BIT(NL80211_STA_INFO_TX_RETRIES) |
18860 BIT(NL80211_STA_INFO_TX_FAILED);
18861#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018862
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018863 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018864
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018865 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18866 &sinfo->txrate, sizeof(sinfo->txrate));
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018867 vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate,
18868 &sinfo->txrate, sizeof(sinfo->txrate));
18869
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018870 if (rate_flags & eHAL_TX_RATE_LEGACY)
18871 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18872 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18873 sinfo->rx_packets);
18874 else
18875 hddLog(LOG1,
18876 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18877 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18878 sinfo->tx_packets, sinfo->rx_packets);
18879
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018880 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18881 TRACE_CODE_HDD_CFG80211_GET_STA,
18882 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018883 EXIT();
18884 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018885}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018886#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18887static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18888 const u8* mac, struct station_info *sinfo)
18889#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018890static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18891 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018892#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018893{
18894 int ret;
18895
18896 vos_ssr_protect(__func__);
18897 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18898 vos_ssr_unprotect(__func__);
18899
18900 return ret;
18901}
18902
18903static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018904 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018905{
18906 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018907 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018908 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018909 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018910
Jeff Johnsone7245742012-09-05 17:12:55 -070018911 ENTER();
18912
Jeff Johnson295189b2012-06-20 16:38:30 -070018913 if (NULL == pAdapter)
18914 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018915 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018916 return -ENODEV;
18917 }
18918
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018919 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18920 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18921 pAdapter->sessionId, timeout));
18922
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018923 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018924 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018925 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018926 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018927 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018928 }
18929
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018930 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
18931 (TRUE == pHddCtx->hdd_wlan_suspended) &&
18932 (pHddCtx->cfg_ini->fhostArpOffload) &&
18933 (eConnectionState_Associated ==
18934 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
18935 {
Amar Singhald53568e2013-09-26 11:03:45 -070018936
18937 hddLog(VOS_TRACE_LEVEL_INFO,
18938 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053018939 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018940 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18941 {
18942 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018943 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018944 __func__, vos_status);
18945 }
18946 }
18947
Jeff Johnson295189b2012-06-20 16:38:30 -070018948 /**The get power cmd from the supplicant gets updated by the nl only
18949 *on successful execution of the function call
18950 *we are oppositely mapped w.r.t mode in the driver
18951 **/
18952 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
18953
18954 if (VOS_STATUS_E_FAILURE == vos_status)
18955 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18957 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018958 return -EINVAL;
18959 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018960 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018961 return 0;
18962}
18963
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018964static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
18965 struct net_device *dev, bool mode, int timeout)
18966{
18967 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018968
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018969 vos_ssr_protect(__func__);
18970 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
18971 vos_ssr_unprotect(__func__);
18972
18973 return ret;
18974}
Sushant Kaushik084f6592015-09-10 13:11:56 +053018975
Jeff Johnson295189b2012-06-20 16:38:30 -070018976#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018977static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
18978 struct net_device *netdev,
18979 u8 key_index)
18980{
18981 ENTER();
18982 return 0;
18983}
18984
Jeff Johnson295189b2012-06-20 16:38:30 -070018985static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018986 struct net_device *netdev,
18987 u8 key_index)
18988{
18989 int ret;
18990 vos_ssr_protect(__func__);
18991 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
18992 vos_ssr_unprotect(__func__);
18993 return ret;
18994}
18995#endif //LINUX_VERSION_CODE
18996
18997#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18998static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18999 struct net_device *dev,
19000 struct ieee80211_txq_params *params)
19001{
19002 ENTER();
19003 return 0;
19004}
19005#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19006static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
19007 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070019008{
Jeff Johnsone7245742012-09-05 17:12:55 -070019009 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070019010 return 0;
19011}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019012#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070019013
19014#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
19015static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019016 struct net_device *dev,
19017 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070019018{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019019 int ret;
19020
19021 vos_ssr_protect(__func__);
19022 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
19023 vos_ssr_unprotect(__func__);
19024 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070019025}
19026#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19027static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
19028 struct ieee80211_txq_params *params)
19029{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019030 int ret;
19031
19032 vos_ssr_protect(__func__);
19033 ret = __wlan_hdd_set_txq_params(wiphy, params);
19034 vos_ssr_unprotect(__func__);
19035 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070019036}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019037#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019038
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019039static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019040 struct net_device *dev,
19041 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070019042{
19043 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019044 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019045 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019046 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019047 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019048 v_CONTEXT_t pVosContext = NULL;
19049 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019050
Jeff Johnsone7245742012-09-05 17:12:55 -070019051 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019052
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019053 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070019054 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019055 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070019056 return -EINVAL;
19057 }
19058
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019059 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19060 TRACE_CODE_HDD_CFG80211_DEL_STA,
19061 pAdapter->sessionId, pAdapter->device_mode));
19062
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019063 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19064 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019065 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019066 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019067 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019068 }
19069
Jeff Johnson295189b2012-06-20 16:38:30 -070019070 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070019071 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070019072 )
19073 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019074 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
19075 pSapCtx = VOS_GET_SAP_CB(pVosContext);
19076 if(pSapCtx == NULL){
19077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19078 FL("psapCtx is NULL"));
19079 return -ENOENT;
19080 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053019081 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
19082 {
19083 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
19084 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
19085 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
19086 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019087 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070019088 {
19089 v_U16_t i;
19090 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
19091 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019092 if ((pSapCtx->aStaInfo[i].isUsed) &&
19093 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070019094 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019095 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019096 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019097 ETHER_ADDR_LEN);
19098
Jeff Johnson295189b2012-06-20 16:38:30 -070019099 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080019100 "%s: Delete STA with MAC::"
19101 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019102 __func__,
19103 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
19104 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070019105 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019106 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070019107 }
19108 }
19109 }
19110 else
19111 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019112
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019113 vos_status = hdd_softap_GetStaId(pAdapter,
19114 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019115 if (!VOS_IS_STATUS_SUCCESS(vos_status))
19116 {
19117 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080019118 "%s: Skip this DEL STA as this is not used::"
19119 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019120 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019121 return -ENOENT;
19122 }
19123
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019124 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019125 {
19126 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080019127 "%s: Skip this DEL STA as deauth is in progress::"
19128 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019129 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019130 return -ENOENT;
19131 }
19132
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019133 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019134
Jeff Johnson295189b2012-06-20 16:38:30 -070019135 hddLog(VOS_TRACE_LEVEL_INFO,
19136 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080019137 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070019138 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019139 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019140
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019141 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019142 if (!VOS_IS_STATUS_SUCCESS(vos_status))
19143 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019144 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019145 hddLog(VOS_TRACE_LEVEL_INFO,
19146 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080019147 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019148 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019149 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019150 return -ENOENT;
19151 }
19152
Jeff Johnson295189b2012-06-20 16:38:30 -070019153 }
19154 }
19155
19156 EXIT();
19157
19158 return 0;
19159}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019160
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019161#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053019162int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019163 struct net_device *dev,
19164 struct station_del_parameters *param)
19165#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019166#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053019167int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019168 struct net_device *dev, const u8 *mac)
19169#else
Kapil Gupta137ef892016-12-13 19:38:00 +053019170int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019171 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019172#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019173#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019174{
19175 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019176 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070019177
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019178 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019179
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019180#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019181 if (NULL == param) {
19182 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019183 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019184 return -EINVAL;
19185 }
19186
19187 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
19188 param->subtype, &delStaParams);
19189
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019190#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053019191 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019192 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019193#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019194 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
19195
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019196 vos_ssr_unprotect(__func__);
19197
19198 return ret;
19199}
19200
19201static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019202 struct net_device *dev,
19203#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19204 const u8 *mac,
19205#else
19206 u8 *mac,
19207#endif
19208 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019209{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019210 hdd_adapter_t *pAdapter;
19211 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019212 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019213#ifdef FEATURE_WLAN_TDLS
19214 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019215
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019216 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019217
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019218 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19219 if (NULL == pAdapter)
19220 {
19221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19222 "%s: Adapter is NULL",__func__);
19223 return -EINVAL;
19224 }
19225 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19226 status = wlan_hdd_validate_context(pHddCtx);
19227 if (0 != status)
19228 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019229 return status;
19230 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019231
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019232 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19233 TRACE_CODE_HDD_CFG80211_ADD_STA,
19234 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019235 mask = params->sta_flags_mask;
19236
19237 set = params->sta_flags_set;
19238
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019240 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
19241 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019242
19243 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
19244 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080019245 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019246 }
19247 }
19248#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019249 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019250 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070019251}
19252
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019253#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19254static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19255 struct net_device *dev, const u8 *mac,
19256 struct station_parameters *params)
19257#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019258static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19259 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019260#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019261{
19262 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019263
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019264 vos_ssr_protect(__func__);
19265 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
19266 vos_ssr_unprotect(__func__);
19267
19268 return ret;
19269}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019270#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070019271
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019272static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070019273 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019274{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019275 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19276 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019277 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019278 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019279 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019280 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070019281
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019282 ENTER();
19283
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019284 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019285 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019286 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019287 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019288 return -EINVAL;
19289 }
19290
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019291 if (!pmksa) {
19292 hddLog(LOGE, FL("pmksa is NULL"));
19293 return -EINVAL;
19294 }
19295
19296 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070019297 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019298 pmksa->bssid, pmksa->pmkid);
19299 return -EINVAL;
19300 }
19301
19302 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
19303 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19304
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019305 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19306 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019307 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019308 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019309 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019310 }
19311
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019312 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019313 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19314
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019315 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
19316 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019317
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019318 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019319 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019320 &pmk_id, 1, FALSE);
19321
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019322 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19323 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
19324 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019325
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019326 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019327 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019328}
19329
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019330static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
19331 struct cfg80211_pmksa *pmksa)
19332{
19333 int ret;
19334
19335 vos_ssr_protect(__func__);
19336 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
19337 vos_ssr_unprotect(__func__);
19338
19339 return ret;
19340}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019341
Wilson Yang6507c4e2013-10-01 20:11:19 -070019342
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019343static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070019344 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019345{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019346 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19347 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019348 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019349 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019350
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019351 ENTER();
19352
Wilson Yang6507c4e2013-10-01 20:11:19 -070019353 /* Validate pAdapter */
19354 if (NULL == pAdapter)
19355 {
19356 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
19357 return -EINVAL;
19358 }
19359
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019360 if (!pmksa) {
19361 hddLog(LOGE, FL("pmksa is NULL"));
19362 return -EINVAL;
19363 }
19364
19365 if (!pmksa->bssid) {
19366 hddLog(LOGE, FL("pmksa->bssid is NULL"));
19367 return -EINVAL;
19368 }
19369
Kiet Lam98c46a12014-10-31 15:34:57 -070019370 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
19371 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19372
Wilson Yang6507c4e2013-10-01 20:11:19 -070019373 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19374 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019375 if (0 != status)
19376 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019377 return status;
19378 }
19379
19380 /*Retrieve halHandle*/
19381 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19382
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019383 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19384 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
19385 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019386 /* Delete the PMKID CSR cache */
19387 if (eHAL_STATUS_SUCCESS !=
19388 sme_RoamDelPMKIDfromCache(halHandle,
19389 pAdapter->sessionId, pmksa->bssid, FALSE)) {
19390 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
19391 MAC_ADDR_ARRAY(pmksa->bssid));
19392 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019393 }
19394
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019395 EXIT();
19396 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019397}
19398
Wilson Yang6507c4e2013-10-01 20:11:19 -070019399
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019400static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
19401 struct cfg80211_pmksa *pmksa)
19402{
19403 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019404
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019405 vos_ssr_protect(__func__);
19406 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
19407 vos_ssr_unprotect(__func__);
19408
19409 return ret;
19410
19411}
19412
19413static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019414{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019415 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19416 tHalHandle halHandle;
19417 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019418 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019419
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019420 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070019421
19422 /* Validate pAdapter */
19423 if (NULL == pAdapter)
19424 {
19425 hddLog(VOS_TRACE_LEVEL_ERROR,
19426 "%s: Invalid Adapter" ,__func__);
19427 return -EINVAL;
19428 }
19429
19430 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19431 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019432 if (0 != status)
19433 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019434 return status;
19435 }
19436
19437 /*Retrieve halHandle*/
19438 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19439
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019440 /* Flush the PMKID cache in CSR */
19441 if (eHAL_STATUS_SUCCESS !=
19442 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
19443 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
19444 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019445 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019446 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080019447 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019448}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019449
19450static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
19451{
19452 int ret;
19453
19454 vos_ssr_protect(__func__);
19455 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
19456 vos_ssr_unprotect(__func__);
19457
19458 return ret;
19459}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019460#endif
19461
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019462#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019463static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19464 struct net_device *dev,
19465 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019466{
19467 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19468 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019469 hdd_context_t *pHddCtx;
19470 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019471
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019472 ENTER();
19473
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019474 if (NULL == pAdapter)
19475 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019476 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019477 return -ENODEV;
19478 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019479 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19480 ret = wlan_hdd_validate_context(pHddCtx);
19481 if (0 != ret)
19482 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019483 return ret;
19484 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019485 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019486 if (NULL == pHddStaCtx)
19487 {
19488 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
19489 return -EINVAL;
19490 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019491
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019492 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19493 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
19494 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019495 // Added for debug on reception of Re-assoc Req.
19496 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
19497 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019498 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019499 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080019500 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019501 }
19502
19503#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Abhinav Kumar36177e12018-10-30 11:55:48 +053019504 hddLog(LOG1, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019505 ftie->ie_len);
19506#endif
19507
19508 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053019509 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
19510 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019511 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019512
19513 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019514 return 0;
19515}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019516
19517static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19518 struct net_device *dev,
19519 struct cfg80211_update_ft_ies_params *ftie)
19520{
19521 int ret;
19522
19523 vos_ssr_protect(__func__);
19524 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
19525 vos_ssr_unprotect(__func__);
19526
19527 return ret;
19528}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019529#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019530
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019531#ifdef FEATURE_WLAN_SCAN_PNO
19532
19533void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
19534 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
19535{
19536 int ret;
19537 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
19538 hdd_context_t *pHddCtx;
19539
Nirav Shah80830bf2013-12-31 16:35:12 +053019540 ENTER();
19541
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019542 if (NULL == pAdapter)
19543 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019545 "%s: HDD adapter is Null", __func__);
19546 return ;
19547 }
19548
19549 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19550 if (NULL == pHddCtx)
19551 {
19552 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19553 "%s: HDD context is Null!!!", __func__);
19554 return ;
19555 }
19556
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019557 spin_lock(&pHddCtx->schedScan_lock);
19558 if (TRUE == pHddCtx->isWiphySuspended)
19559 {
19560 pHddCtx->isSchedScanUpdatePending = TRUE;
19561 spin_unlock(&pHddCtx->schedScan_lock);
19562 hddLog(VOS_TRACE_LEVEL_INFO,
19563 "%s: Update cfg80211 scan database after it resume", __func__);
19564 return ;
19565 }
19566 spin_unlock(&pHddCtx->schedScan_lock);
19567
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019568 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
19569
19570 if (0 > ret)
19571 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053019572 else
19573 {
19574 /* Acquire wakelock to handle the case where APP's tries to suspend
19575 * immediatly after the driver gets connect request(i.e after pno)
19576 * from supplicant, this result in app's is suspending and not able
19577 * to process the connect request to AP */
19578 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
19579 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019580 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19582 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019583}
19584
19585/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019586 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019587 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019588 */
19589static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
19590{
19591 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
19592 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019593 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019594 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19595 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053019596
19597 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
19598 {
19599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19600 "%s: PNO is allowed only in STA interface", __func__);
19601 return eHAL_STATUS_FAILURE;
19602 }
19603
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019604 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
19605
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019606 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053019607 * active sessions. PNO is allowed only in case when sap session
19608 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019609 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019610 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
19611 {
19612 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019613 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019614
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019615 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
19616 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
19617 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
19618 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053019619 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
19620 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053019621 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019622 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019623 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019624 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019625 }
19626 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19627 pAdapterNode = pNext;
19628 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019629 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019630}
19631
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019632void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
19633{
19634 hdd_adapter_t *pAdapter = callbackContext;
19635 hdd_context_t *pHddCtx;
19636
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019637 ENTER();
19638
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019639 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
19640 {
19641 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19642 FL("Invalid adapter or adapter has invalid magic"));
19643 return;
19644 }
19645
19646 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19647 if (0 != wlan_hdd_validate_context(pHddCtx))
19648 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019649 return;
19650 }
19651
c_hpothub53c45d2014-08-18 16:53:14 +053019652 if (VOS_STATUS_SUCCESS != status)
19653 {
19654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019655 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053019656 pHddCtx->isPnoEnable = FALSE;
19657 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019658
19659 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
19660 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019661 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019662}
19663
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019664#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
19665 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
19666/**
19667 * hdd_config_sched_scan_plan() - configures the sched scan plans
19668 * from the framework.
19669 * @pno_req: pointer to PNO scan request
19670 * @request: pointer to scan request from framework
19671 *
19672 * Return: None
19673 */
19674static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
19675 struct cfg80211_sched_scan_request *request,
19676 hdd_context_t *hdd_ctx)
19677{
19678 v_U32_t i = 0;
19679
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019680 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019681 for (i = 0; i < request->n_scan_plans; i++)
19682 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019683 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
19684 request->scan_plans[i].iterations;
19685 pno_req->scanTimers.aTimerValues[i].uTimerValue =
19686 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019687 }
19688}
19689#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019690static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019691 struct cfg80211_sched_scan_request *request,
19692 hdd_context_t *hdd_ctx)
19693{
19694 v_U32_t i, temp_int;
19695 /* Driver gets only one time interval which is hardcoded in
19696 * supplicant for 10000ms. Taking power consumption into account 6
19697 * timers will be used, Timervalue is increased exponentially
19698 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
19699 * timer is configurable through INI param gPNOScanTimerRepeatValue.
19700 * If it is set to 0 only one timer will be used and PNO scan cycle
19701 * will be repeated after each interval specified by supplicant
19702 * till PNO is disabled.
19703 */
19704 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019705 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019706 HDD_PNO_SCAN_TIMERS_SET_ONE;
19707 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019708 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019709 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
19710
19711 temp_int = (request->interval)/1000;
19712 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19713 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
19714 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019715 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019716 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019717 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019718 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019719 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019720 temp_int *= 2;
19721 }
19722 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019723 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019724}
19725#endif
19726
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019727/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019728 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
19729 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019730 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019731static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019732 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19733{
19734 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019735 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019736 hdd_context_t *pHddCtx;
19737 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019738 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053019739 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
19740 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019741 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
19742 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019743 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019744 hdd_config_t *pConfig = NULL;
19745 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019746
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019747 ENTER();
19748
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019749 if (NULL == pAdapter)
19750 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019752 "%s: HDD adapter is Null", __func__);
19753 return -ENODEV;
19754 }
19755
19756 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019757 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019758
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019759 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019760 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019761 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019762 }
19763
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019764 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019765 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19766 if (NULL == hHal)
19767 {
19768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19769 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019770 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019771 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019772 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19773 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
19774 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019775 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053019776 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019777 {
19778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19779 "%s: aborting the existing scan is unsuccessfull", __func__);
19780 return -EBUSY;
19781 }
19782
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019783 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019784 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019785 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019786 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019787 return -EBUSY;
19788 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019789
c_hpothu37f21312014-04-09 21:49:54 +053019790 if (TRUE == pHddCtx->isPnoEnable)
19791 {
19792 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19793 FL("already PNO is enabled"));
19794 return -EBUSY;
19795 }
c_hpothu225aa7c2014-10-22 17:45:13 +053019796
19797 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
19798 {
19799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19800 "%s: abort ROC failed ", __func__);
19801 return -EBUSY;
19802 }
19803
c_hpothu37f21312014-04-09 21:49:54 +053019804 pHddCtx->isPnoEnable = TRUE;
19805
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019806 pnoRequest.enable = 1; /*Enable PNO */
19807 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019808
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019809 if (( !pnoRequest.ucNetworksCount ) ||
19810 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019811 {
19812 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019813 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019814 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019815 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019816 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019817 goto error;
19818 }
19819
19820 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
19821 {
19822 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019823 "%s: Incorrect number of channels %d",
19824 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019825 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019826 goto error;
19827 }
19828
19829 /* Framework provides one set of channels(all)
19830 * common for all saved profile */
19831 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
19832 channels_allowed, &num_channels_allowed))
19833 {
19834 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19835 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019836 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019837 goto error;
19838 }
19839 /* Checking each channel against allowed channel list */
19840 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053019841 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019842 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019843 char chList [(request->n_channels*5)+1];
19844 int len;
19845 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019846 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019847 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019848 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019849 if (request->channels[i]->hw_value == channels_allowed[indx])
19850 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019851 if ((!pConfig->enableDFSPnoChnlScan) &&
19852 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
19853 {
19854 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19855 "%s : Dropping DFS channel : %d",
19856 __func__,channels_allowed[indx]);
19857 num_ignore_dfs_ch++;
19858 break;
19859 }
19860
Nirav Shah80830bf2013-12-31 16:35:12 +053019861 valid_ch[num_ch++] = request->channels[i]->hw_value;
19862 len += snprintf(chList+len, 5, "%d ",
19863 request->channels[i]->hw_value);
19864 break ;
19865 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019866 }
19867 }
Nirav Shah80830bf2013-12-31 16:35:12 +053019868 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019869
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019870 /*If all channels are DFS and dropped, then ignore the PNO request*/
19871 if (num_ignore_dfs_ch == request->n_channels)
19872 {
19873 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19874 "%s : All requested channels are DFS channels", __func__);
19875 ret = -EINVAL;
19876 goto error;
19877 }
19878 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019879
19880 pnoRequest.aNetworks =
19881 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19882 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019883 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019884 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19885 FL("failed to allocate memory aNetworks %u"),
19886 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19887 goto error;
19888 }
19889 vos_mem_zero(pnoRequest.aNetworks,
19890 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19891
19892 /* Filling per profile params */
19893 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
19894 {
19895 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019896 request->match_sets[i].ssid.ssid_len;
19897
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019898 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
19899 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019900 {
19901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019902 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019903 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019904 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019905 goto error;
19906 }
19907
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019908 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019909 request->match_sets[i].ssid.ssid,
19910 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019911 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19912 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019913 i, pnoRequest.aNetworks[i].ssId.ssId);
19914 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
19915 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
19916 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019917
19918 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019919 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
19920 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019921
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019922 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019923 }
19924
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019925 for (i = 0; i < request->n_ssids; i++)
19926 {
19927 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019928 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019929 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019930 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019931 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019932 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019933 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019934 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019935 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019936 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019937 break;
19938 }
19939 j++;
19940 }
19941 }
19942 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19943 "Number of hidden networks being Configured = %d",
19944 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080019946 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019947
19948 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19949 if (pnoRequest.p24GProbeTemplate == NULL)
19950 {
19951 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19952 FL("failed to allocate memory p24GProbeTemplate %u"),
19953 SIR_PNO_MAX_PB_REQ_SIZE);
19954 goto error;
19955 }
19956
19957 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19958 if (pnoRequest.p5GProbeTemplate == NULL)
19959 {
19960 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19961 FL("failed to allocate memory p5GProbeTemplate %u"),
19962 SIR_PNO_MAX_PB_REQ_SIZE);
19963 goto error;
19964 }
19965
19966 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19967 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19968
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053019969 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
19970 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019971 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019972 pnoRequest.us24GProbeTemplateLen = request->ie_len;
19973 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
19974 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019975
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019976 pnoRequest.us5GProbeTemplateLen = request->ie_len;
19977 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
19978 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019979 }
19980
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019981 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053019982
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019983 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019984
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019985 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019986 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19987 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019988 pAdapter->pno_req_status = 0;
19989
Nirav Shah80830bf2013-12-31 16:35:12 +053019990 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19991 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019992 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
19993 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053019994
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019995 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019996 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019997 hdd_cfg80211_sched_scan_done_callback, pAdapter);
19998 if (eHAL_STATUS_SUCCESS != status)
19999 {
20000 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053020001 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020002 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020003 goto error;
20004 }
20005
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020006 ret = wait_for_completion_timeout(
20007 &pAdapter->pno_comp_var,
20008 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
20009 if (0 >= ret)
20010 {
20011 // Did not receive the response for PNO enable in time.
20012 // Assuming the PNO enable was success.
20013 // Returning error from here, because we timeout, results
20014 // in side effect of Wifi (Wifi Setting) not to work.
20015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20016 FL("Timed out waiting for PNO to be Enabled"));
20017 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020018 }
20019
20020 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053020021 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020022
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020023error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20025 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053020026 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020027 if (pnoRequest.aNetworks)
20028 vos_mem_free(pnoRequest.aNetworks);
20029 if (pnoRequest.p24GProbeTemplate)
20030 vos_mem_free(pnoRequest.p24GProbeTemplate);
20031 if (pnoRequest.p5GProbeTemplate)
20032 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020033
20034 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020035 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020036}
20037
20038/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053020039 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
20040 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020041 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053020042static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
20043 struct net_device *dev, struct cfg80211_sched_scan_request *request)
20044{
20045 int ret;
20046
20047 vos_ssr_protect(__func__);
20048 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
20049 vos_ssr_unprotect(__func__);
20050
20051 return ret;
20052}
20053
20054/*
20055 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
20056 * Function to disable PNO
20057 */
20058static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020059 struct net_device *dev)
20060{
20061 eHalStatus status = eHAL_STATUS_FAILURE;
20062 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20063 hdd_context_t *pHddCtx;
20064 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020065 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020066 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020067
20068 ENTER();
20069
20070 if (NULL == pAdapter)
20071 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020072 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020073 "%s: HDD adapter is Null", __func__);
20074 return -ENODEV;
20075 }
20076
20077 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020078
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020079 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020080 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020082 "%s: HDD context is Null", __func__);
20083 return -ENODEV;
20084 }
20085
20086 /* The return 0 is intentional when isLogpInProgress and
20087 * isLoadUnloadInProgress. We did observe a crash due to a return of
20088 * failure in sched_scan_stop , especially for a case where the unload
20089 * of the happens at the same time. The function __cfg80211_stop_sched_scan
20090 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
20091 * success. If it returns a failure , then its next invocation due to the
20092 * clean up of the second interface will have the dev pointer corresponding
20093 * to the first one leading to a crash.
20094 */
20095 if (pHddCtx->isLogpInProgress)
20096 {
20097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20098 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053020099 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020100 return ret;
20101 }
20102
Mihir Shete18156292014-03-11 15:38:30 +053020103 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020104 {
20105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20106 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
20107 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020108 }
20109
20110 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
20111 if (NULL == hHal)
20112 {
20113 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20114 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020115 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020116 }
20117
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020118 pnoRequest.enable = 0; /* Disable PNO */
20119 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020120
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020121 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20122 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
20123 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053020124
20125 INIT_COMPLETION(pAdapter->pno_comp_var);
20126 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
20127 pnoRequest.callbackContext = pAdapter;
20128 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020129 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020130 pAdapter->sessionId,
20131 NULL, pAdapter);
20132 if (eHAL_STATUS_SUCCESS != status)
20133 {
20134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20135 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020136 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020137 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020138 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053020139 ret = wait_for_completion_timeout(
20140 &pAdapter->pno_comp_var,
20141 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
20142 if (0 >= ret)
20143 {
20144 // Did not receive the response for PNO disable in time.
20145 // Assuming the PNO disable was success.
20146 // Returning error from here, because we timeout, results
20147 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053020148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053020149 FL("Timed out waiting for PNO to be disabled"));
20150 ret = 0;
20151 }
20152
20153 ret = pAdapter->pno_req_status;
20154 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020155
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020156error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020157 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020158 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020159
20160 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020161 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020162}
20163
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053020164/*
20165 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
20166 * NL interface to disable PNO
20167 */
20168static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
20169 struct net_device *dev)
20170{
20171 int ret;
20172
20173 vos_ssr_protect(__func__);
20174 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
20175 vos_ssr_unprotect(__func__);
20176
20177 return ret;
20178}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020179#endif /*FEATURE_WLAN_SCAN_PNO*/
20180
20181
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020182#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020183#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020184static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20185 struct net_device *dev,
20186 u8 *peer, u8 action_code,
20187 u8 dialog_token,
20188 u16 status_code, u32 peer_capability,
20189 const u8 *buf, size_t len)
20190#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020191#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20192 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020193static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20194 struct net_device *dev,
20195 const u8 *peer, u8 action_code,
20196 u8 dialog_token, u16 status_code,
20197 u32 peer_capability, bool initiator,
20198 const u8 *buf, size_t len)
20199#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20200static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20201 struct net_device *dev,
20202 const u8 *peer, u8 action_code,
20203 u8 dialog_token, u16 status_code,
20204 u32 peer_capability, const u8 *buf,
20205 size_t len)
20206#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20207static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20208 struct net_device *dev,
20209 u8 *peer, u8 action_code,
20210 u8 dialog_token,
20211 u16 status_code, u32 peer_capability,
20212 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020213#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020214static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20215 struct net_device *dev,
20216 u8 *peer, u8 action_code,
20217 u8 dialog_token,
20218 u16 status_code, const u8 *buf,
20219 size_t len)
20220#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020221#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020222{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020223 hdd_adapter_t *pAdapter;
20224 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020225 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070020226 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080020227 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070020228 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020229 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020230 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020231#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020232 u32 peer_capability = 0;
20233#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020234 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020235 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020236 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020237
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020238 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20239 if (NULL == pAdapter)
20240 {
20241 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20242 "%s: Adapter is NULL",__func__);
20243 return -EINVAL;
20244 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020245 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20246 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
20247 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020248
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020249 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020250 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020251 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020253 "Invalid arguments");
20254 return -EINVAL;
20255 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020256
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020257 if (pHddCtx->isLogpInProgress)
20258 {
20259 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20260 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053020261 wlan_hdd_tdls_set_link_status(pAdapter,
20262 peer,
20263 eTDLS_LINK_IDLE,
20264 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020265 return -EBUSY;
20266 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020267
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020268 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
20269 {
20270 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20271 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
20272 return -EAGAIN;
20273 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020274
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020275 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
20276 if (!pHddTdlsCtx) {
20277 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20278 "%s: pHddTdlsCtx not valid.", __func__);
Hanumanth Reddy Pothula36dfa522018-03-12 16:42:08 +053020279 return -EINVAL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020280 }
20281
Hoonki Lee27511902013-03-14 18:19:06 -070020282 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020283 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020284 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020285 "%s: TDLS mode is disabled OR not enabled in FW."
20286 MAC_ADDRESS_STR " action %d declined.",
20287 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020288 return -ENOTSUPP;
20289 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020290
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020291 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20292
20293 if( NULL == pHddStaCtx )
20294 {
20295 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20296 "%s: HDD station context NULL ",__func__);
20297 return -EINVAL;
20298 }
20299
20300 /* STA should be connected and authenticated
20301 * before sending any TDLS frames
20302 */
20303 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
20304 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
20305 {
20306 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20307 "STA is not connected or unauthenticated. "
20308 "connState %u, uIsAuthenticated %u",
20309 pHddStaCtx->conn_info.connState,
20310 pHddStaCtx->conn_info.uIsAuthenticated);
20311 return -EAGAIN;
20312 }
20313
Hoonki Lee27511902013-03-14 18:19:06 -070020314 /* other than teardown frame, other mgmt frames are not sent if disabled */
20315 if (SIR_MAC_TDLS_TEARDOWN != action_code)
20316 {
20317 /* if tdls_mode is disabled to respond to peer's request */
20318 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
20319 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020320 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020321 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020322 " TDLS mode is disabled. action %d declined.",
20323 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070020324
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020325 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070020326 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053020327
20328 if (vos_max_concurrent_connections_reached())
20329 {
20330 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
20331 return -EINVAL;
20332 }
Hoonki Lee27511902013-03-14 18:19:06 -070020333 }
20334
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020335 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
20336 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053020337 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020338 {
20339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020340 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020341 " TDLS setup is ongoing. action %d declined.",
20342 __func__, MAC_ADDR_ARRAY(peer), action_code);
20343 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020344 }
20345 }
20346
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020347 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
20348 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080020349 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020350 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20351 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020352 {
20353 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
20354 we return error code at 'add_station()'. Hence we have this
20355 check again in addtion to add_station().
20356 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020357 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020358 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020359 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20360 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020361 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
20362 __func__, MAC_ADDR_ARRAY(peer), action_code,
20363 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053020364 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080020365 }
20366 else
20367 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020368 /* maximum reached. tweak to send error code to peer and return
20369 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020370 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20372 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020373 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
20374 __func__, MAC_ADDR_ARRAY(peer), status_code,
20375 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070020376 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020377 /* fall through to send setup resp with failure status
20378 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020379 }
20380 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020381 else
20382 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020383 mutex_lock(&pHddCtx->tdls_lock);
20384 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020385 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020386 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020387 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020389 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
20390 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020391 return -EPERM;
20392 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020393 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020394 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020395 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020396
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020398 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020399 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
20400 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020401
Hoonki Leea34dd892013-02-05 22:56:02 -080020402 /*Except teardown responder will not be used so just make 0*/
20403 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020404 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080020405 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020406
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020407 mutex_lock(&pHddCtx->tdls_lock);
20408 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020409
20410 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
20411 responder = pTdlsPeer->is_responder;
20412 else
Hoonki Leea34dd892013-02-05 22:56:02 -080020413 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020415 "%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 -070020416 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
20417 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020418 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020419 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080020420 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020421 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020422 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020423
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020424 /* Discard TDLS setup if peer is removed by user app */
20425 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
20426 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20427 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
20428 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
20429
20430 mutex_lock(&pHddCtx->tdls_lock);
20431 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20432 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
20433 mutex_unlock(&pHddCtx->tdls_lock);
20434 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
20435 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
20436 MAC_ADDR_ARRAY(peer), action_code);
20437 return -EINVAL;
20438 }
20439 mutex_unlock(&pHddCtx->tdls_lock);
20440 }
20441
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020442 /* For explicit trigger of DIS_REQ come out of BMPS for
20443 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070020444 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053020445 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020446 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
20447 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070020448 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020449 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020450 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020451 "%s: Sending frame action_code %u.Disable BMPS", __func__,
20452 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020453 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
20454 if (status != VOS_STATUS_SUCCESS) {
20455 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020456 } else {
20457 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020458 }
Hoonki Lee14621352013-04-16 17:51:19 -070020459 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020460 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020461 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020462 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
20463 }
20464 }
Hoonki Lee14621352013-04-16 17:51:19 -070020465 }
20466
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020467 /* make sure doesn't call send_mgmt() while it is pending */
20468 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
20469 {
20470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080020471 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020472 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020473 ret = -EBUSY;
20474 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020475 }
20476
20477 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020478 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
20479
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020480 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
20481 pAdapter->sessionId, peer, action_code, dialog_token,
20482 status_code, peer_capability, (tANI_U8 *)buf, len,
20483 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020484
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020485 if (VOS_STATUS_SUCCESS != status)
20486 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20488 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020489 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020490 ret = -EINVAL;
20491 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020492 }
20493
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020494 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20495 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
20496 WAIT_TIME_TDLS_MGMT);
20497
Hoonki Leed37cbb32013-04-20 00:31:14 -070020498 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
20499 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
20500
20501 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020502 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070020503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070020504 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070020505 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020506 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080020507
20508 if (pHddCtx->isLogpInProgress)
20509 {
20510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20511 "%s: LOGP in Progress. Ignore!!!", __func__);
20512 return -EAGAIN;
20513 }
Abhishek Singh837adf22015-10-01 17:37:37 +053020514 if (rc <= 0)
20515 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
20516 WLAN_LOG_INDICATOR_HOST_DRIVER,
20517 WLAN_LOG_REASON_HDD_TIME_OUT,
20518 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080020519
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020520 ret = -EINVAL;
20521 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020522 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020523 else
20524 {
20525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20526 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
20527 __func__, rc, pAdapter->mgmtTxCompletionStatus);
20528 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020529
Gopichand Nakkala05922802013-03-14 12:23:19 -070020530 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070020531 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020532 ret = max_sta_failed;
20533 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070020534 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020535
Hoonki Leea34dd892013-02-05 22:56:02 -080020536 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
20537 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020538 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020539 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20540 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020541 }
20542 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
20543 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020544 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020545 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20546 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020547 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020548
20549 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020550
20551tx_failed:
20552 /* add_station will be called before sending TDLS_SETUP_REQ and
20553 * TDLS_SETUP_RSP and as part of add_station driver will enable
20554 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
20555 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
20556 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
20557 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
20558 */
20559
20560 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20561 (SIR_MAC_TDLS_SETUP_RSP == action_code))
20562 wlan_hdd_tdls_check_bmps(pAdapter);
20563 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020564}
20565
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020566#if TDLS_MGMT_VERSION2
20567static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20568 u8 *peer, u8 action_code, u8 dialog_token,
20569 u16 status_code, u32 peer_capability,
20570 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020571#else /* TDLS_MGMT_VERSION2 */
20572#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20573static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20574 struct net_device *dev,
20575 const u8 *peer, u8 action_code,
20576 u8 dialog_token, u16 status_code,
20577 u32 peer_capability, bool initiator,
20578 const u8 *buf, size_t len)
20579#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20580static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20581 struct net_device *dev,
20582 const u8 *peer, u8 action_code,
20583 u8 dialog_token, u16 status_code,
20584 u32 peer_capability, const u8 *buf,
20585 size_t len)
20586#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20587static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20588 struct net_device *dev,
20589 u8 *peer, u8 action_code,
20590 u8 dialog_token,
20591 u16 status_code, u32 peer_capability,
20592 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020593#else
20594static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20595 u8 *peer, u8 action_code, u8 dialog_token,
20596 u16 status_code, const u8 *buf, size_t len)
20597#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020598#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020599{
20600 int ret;
20601
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020602 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020603#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020604 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20605 dialog_token, status_code,
20606 peer_capability, buf, len);
20607#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020608#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20609 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020610 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20611 dialog_token, status_code,
20612 peer_capability, initiator,
20613 buf, len);
20614#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20615 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20616 dialog_token, status_code,
20617 peer_capability, buf, len);
20618#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20619 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20620 dialog_token, status_code,
20621 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020622#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020623 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20624 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020625#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020626#endif
20627 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020628
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020629 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020630}
Atul Mittal115287b2014-07-08 13:26:33 +053020631
20632int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020633#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20634 const u8 *peer,
20635#else
Atul Mittal115287b2014-07-08 13:26:33 +053020636 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020637#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020638 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053020639 cfg80211_exttdls_callback callback)
20640{
20641
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020642 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053020643 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020644 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053020645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20646 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
20647 __func__, MAC_ADDR_ARRAY(peer));
20648
20649 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20650 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20651
20652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020653 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20654 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20655 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020656 return -ENOTSUPP;
20657 }
20658
20659 /* To cater the requirement of establishing the TDLS link
20660 * irrespective of the data traffic , get an entry of TDLS peer.
20661 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020662 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020663 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
20664 if (pTdlsPeer == NULL) {
20665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20666 "%s: peer " MAC_ADDRESS_STR " not existing",
20667 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020668 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020669 return -EINVAL;
20670 }
20671
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020672 /* check FW TDLS Off Channel capability */
20673 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020674 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020675 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020676 {
20677 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
20678 pTdlsPeer->peerParams.global_operating_class =
20679 tdls_peer_params->global_operating_class;
20680 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
20681 pTdlsPeer->peerParams.min_bandwidth_kbps =
20682 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020683 /* check configured channel is valid, non dfs and
20684 * not current operating channel */
20685 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
20686 tdls_peer_params->channel)) &&
20687 (pHddStaCtx) &&
20688 (tdls_peer_params->channel !=
20689 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020690 {
20691 pTdlsPeer->isOffChannelConfigured = TRUE;
20692 }
20693 else
20694 {
20695 pTdlsPeer->isOffChannelConfigured = FALSE;
20696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20697 "%s: Configured Tdls Off Channel is not valid", __func__);
20698
20699 }
20700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020701 "%s: tdls_off_channel %d isOffChannelConfigured %d "
20702 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020703 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020704 pTdlsPeer->isOffChannelConfigured,
20705 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020706 }
20707 else
20708 {
20709 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020710 "%s: TDLS off channel FW capability %d, "
20711 "host capab %d or Invalid TDLS Peer Params", __func__,
20712 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
20713 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020714 }
20715
Atul Mittal115287b2014-07-08 13:26:33 +053020716 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
20717
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020718 mutex_unlock(&pHddCtx->tdls_lock);
20719
Atul Mittal115287b2014-07-08 13:26:33 +053020720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20721 " %s TDLS Add Force Peer Failed",
20722 __func__);
20723 return -EINVAL;
20724 }
20725 /*EXT TDLS*/
20726
20727 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020728 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20730 " %s TDLS set callback Failed",
20731 __func__);
20732 return -EINVAL;
20733 }
20734
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020735 mutex_unlock(&pHddCtx->tdls_lock);
20736
Atul Mittal115287b2014-07-08 13:26:33 +053020737 return(0);
20738
20739}
20740
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020741int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
20742#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20743 const u8 *peer
20744#else
20745 u8 *peer
20746#endif
20747)
Atul Mittal115287b2014-07-08 13:26:33 +053020748{
20749
20750 hddTdlsPeer_t *pTdlsPeer;
20751 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020752
Atul Mittal115287b2014-07-08 13:26:33 +053020753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20754 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
20755 __func__, MAC_ADDR_ARRAY(peer));
20756
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020757 if (0 != wlan_hdd_validate_context(pHddCtx)) {
20758 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
20759 return -EINVAL;
20760 }
20761
Atul Mittal115287b2014-07-08 13:26:33 +053020762 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20763 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20764
20765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020766 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20767 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20768 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020769 return -ENOTSUPP;
20770 }
20771
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020772 mutex_lock(&pHddCtx->tdls_lock);
20773 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053020774
20775 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020776 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020777 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020778 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053020779 __func__, MAC_ADDR_ARRAY(peer));
20780 return -EINVAL;
20781 }
20782 else {
20783 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
20784 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020785 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
20786 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020787 /* if channel switch is configured, reset
20788 the channel for this peer */
20789 if (TRUE == pTdlsPeer->isOffChannelConfigured)
20790 {
20791 pTdlsPeer->peerParams.channel = 0;
20792 pTdlsPeer->isOffChannelConfigured = FALSE;
20793 }
Atul Mittal115287b2014-07-08 13:26:33 +053020794 }
20795
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020796 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020797 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020798 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053020799 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020800 }
Atul Mittal115287b2014-07-08 13:26:33 +053020801
20802 /*EXT TDLS*/
20803
20804 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020805 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20807 " %s TDLS set callback Failed",
20808 __func__);
20809 return -EINVAL;
20810 }
Atul Mittal115287b2014-07-08 13:26:33 +053020811
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020812 mutex_unlock(&pHddCtx->tdls_lock);
20813
20814 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053020815}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020816static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020817#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20818 const u8 *peer,
20819#else
20820 u8 *peer,
20821#endif
20822 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020823{
20824 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20825 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020826 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020827 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020828
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020829 ENTER();
20830
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020831 if (!pAdapter) {
20832 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
20833 return -EINVAL;
20834 }
20835
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020836 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20837 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
20838 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020839 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020840 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070020842 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020843 return -EINVAL;
20844 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020845
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020846 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020847 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020848 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020849 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020850 }
20851
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020852
20853 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020854 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020855 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020857 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
20858 "Cannot process TDLS commands",
20859 pHddCtx->cfg_ini->fEnableTDLSSupport,
20860 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020861 return -ENOTSUPP;
20862 }
20863
20864 switch (oper) {
20865 case NL80211_TDLS_ENABLE_LINK:
20866 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020867 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020868 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053020869 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
20870 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053020871 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020872 tANI_U16 numCurrTdlsPeers = 0;
20873 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020874 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020875 tSirMacAddr peerMac;
20876 int channel;
20877 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020878
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020879 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20880 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
20881 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020882
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020883 mutex_lock(&pHddCtx->tdls_lock);
20884 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020885 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053020886 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020887 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020888 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20889 " (oper %d) not exsting. ignored",
20890 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20891 return -EINVAL;
20892 }
20893
20894 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20895 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20896 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20897 "NL80211_TDLS_ENABLE_LINK");
20898
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020899 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
20900 {
20901 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
20902 MAC_ADDRESS_STR " failed",
20903 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020904 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020905 return -EINVAL;
20906 }
20907
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020908 /* before starting tdls connection, set tdls
20909 * off channel established status to default value */
20910 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020911
20912 mutex_unlock(&pHddCtx->tdls_lock);
20913
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053020914 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020915 /* TDLS Off Channel, Disable tdls channel switch,
20916 when there are more than one tdls link */
20917 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053020918 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020919 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020920 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020921 /* get connected peer and send disable tdls off chan */
20922 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020923 if ((connPeer) &&
20924 (connPeer->isOffChannelSupported == TRUE) &&
20925 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020926 {
20927 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20928 "%s: More then one peer connected, Disable "
20929 "TDLS channel switch", __func__);
20930
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020931 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020932 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
20933 channel = connPeer->peerParams.channel;
20934
20935 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020936
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020937 ret = sme_SendTdlsChanSwitchReq(
20938 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020939 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020940 peerMac,
20941 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020942 TDLS_OFF_CHANNEL_BW_OFFSET,
20943 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020944 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020945 hddLog(VOS_TRACE_LEVEL_ERROR,
20946 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020947 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020948 }
20949 else
20950 {
20951 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20952 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020953 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020954 "isOffChannelConfigured %d",
20955 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020956 (connPeer ? (connPeer->isOffChannelSupported)
20957 : -1),
20958 (connPeer ? (connPeer->isOffChannelConfigured)
20959 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020960 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020961 }
20962 }
20963
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020964 mutex_lock(&pHddCtx->tdls_lock);
20965 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20966 if ( NULL == pTdlsPeer ) {
20967 mutex_unlock(&pHddCtx->tdls_lock);
20968 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20969 "%s: " MAC_ADDRESS_STR
20970 " (oper %d) peer got freed in other context. ignored",
20971 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20972 return -EINVAL;
20973 }
20974 peer_status = pTdlsPeer->link_status;
20975 mutex_unlock(&pHddCtx->tdls_lock);
20976
20977 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020978 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020979 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053020980
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020981 if (0 != wlan_hdd_tdls_get_link_establish_params(
20982 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020983 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020984 return -EINVAL;
20985 }
20986 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020987
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020988 ret = sme_SendTdlsLinkEstablishParams(
20989 WLAN_HDD_GET_HAL_CTX(pAdapter),
20990 pAdapter->sessionId, peer,
20991 &tdlsLinkEstablishParams);
20992 if (ret != VOS_STATUS_SUCCESS) {
20993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
20994 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020995 /* Send TDLS peer UAPSD capabilities to the firmware and
20996 * register with the TL on after the response for this operation
20997 * is received .
20998 */
20999 ret = wait_for_completion_interruptible_timeout(
21000 &pAdapter->tdls_link_establish_req_comp,
21001 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053021002
21003 mutex_lock(&pHddCtx->tdls_lock);
21004 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21005 if ( NULL == pTdlsPeer ) {
21006 mutex_unlock(&pHddCtx->tdls_lock);
21007 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21008 "%s %d: " MAC_ADDRESS_STR
21009 " (oper %d) peer got freed in other context. ignored",
21010 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
21011 (int)oper);
21012 return -EINVAL;
21013 }
21014 peer_status = pTdlsPeer->link_status;
21015 mutex_unlock(&pHddCtx->tdls_lock);
21016
21017 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053021018 {
21019 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021020 FL("Link Establish Request Failed Status %ld"),
21021 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053021022 return -EINVAL;
21023 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021024 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053021025
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021026 mutex_lock(&pHddCtx->tdls_lock);
21027 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21028 if ( NULL == pTdlsPeer ) {
21029 mutex_unlock(&pHddCtx->tdls_lock);
21030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21031 "%s: " MAC_ADDRESS_STR
21032 " (oper %d) peer got freed in other context. ignored",
21033 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
21034 return -EINVAL;
21035 }
21036
Atul Mittal115287b2014-07-08 13:26:33 +053021037 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
21038 eTDLS_LINK_CONNECTED,
21039 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053021040 staDesc.ucSTAId = pTdlsPeer->staId;
21041 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053021042
21043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21044 "%s: tdlsLinkEstablishParams of peer "
21045 MAC_ADDRESS_STR "uapsdQueues: %d"
21046 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
21047 "isResponder: %d peerstaId: %d",
21048 __func__,
21049 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
21050 tdlsLinkEstablishParams.uapsdQueues,
21051 tdlsLinkEstablishParams.qos,
21052 tdlsLinkEstablishParams.maxSp,
21053 tdlsLinkEstablishParams.isBufSta,
21054 tdlsLinkEstablishParams.isOffChannelSupported,
21055 tdlsLinkEstablishParams.isResponder,
21056 pTdlsPeer->staId);
21057
21058 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21059 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
21060 __func__,
21061 staDesc.ucSTAId,
21062 staDesc.ucQosEnabled);
21063
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021064 ret = WLANTL_UpdateTdlsSTAClient(
21065 pHddCtx->pvosContext,
21066 &staDesc);
21067 if (ret != VOS_STATUS_SUCCESS) {
21068 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
21069 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053021070
Gopichand Nakkala471708b2013-06-04 20:03:01 +053021071 /* Mark TDLS client Authenticated .*/
21072 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
21073 pTdlsPeer->staId,
21074 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070021075 if (VOS_STATUS_SUCCESS == status)
21076 {
Hoonki Lee14621352013-04-16 17:51:19 -070021077 if (pTdlsPeer->is_responder == 0)
21078 {
21079 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053021080 tdlsConnInfo_t *tdlsInfo;
21081
21082 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
21083
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053021084 if (!vos_timer_is_initialized(
21085 &pTdlsPeer->initiatorWaitTimeoutTimer))
21086 {
21087 /* Initialize initiator wait callback */
21088 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053021089 &pTdlsPeer->initiatorWaitTimeoutTimer,
21090 VOS_TIMER_TYPE_SW,
21091 wlan_hdd_tdls_initiator_wait_cb,
21092 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053021093 }
Hoonki Lee14621352013-04-16 17:51:19 -070021094 wlan_hdd_tdls_timer_restart(pAdapter,
21095 &pTdlsPeer->initiatorWaitTimeoutTimer,
21096 WAIT_TIME_TDLS_INITIATOR);
21097 /* suspend initiator TX until it receives direct packet from the
21098 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021099 ret = WLANTL_SuspendDataTx(
21100 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
21101 &staId, NULL);
21102 if (ret != VOS_STATUS_SUCCESS) {
21103 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
21104 }
Hoonki Lee14621352013-04-16 17:51:19 -070021105 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021106
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021107 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021108 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021109 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021110 suppChannelLen =
21111 tdlsLinkEstablishParams.supportedChannelsLen;
21112
21113 if ((suppChannelLen > 0) &&
21114 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
21115 {
21116 tANI_U8 suppPeerChannel = 0;
21117 int i = 0;
21118 for (i = 0U; i < suppChannelLen; i++)
21119 {
21120 suppPeerChannel =
21121 tdlsLinkEstablishParams.supportedChannels[i];
21122
21123 pTdlsPeer->isOffChannelSupported = FALSE;
21124 if (suppPeerChannel ==
21125 pTdlsPeer->peerParams.channel)
21126 {
21127 pTdlsPeer->isOffChannelSupported = TRUE;
21128 break;
21129 }
21130 }
21131 }
21132 else
21133 {
21134 pTdlsPeer->isOffChannelSupported = FALSE;
21135 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021136 }
21137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21138 "%s: TDLS channel switch request for channel "
21139 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021140 "%d isOffChannelSupported %d", __func__,
21141 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021142 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021143 suppChannelLen,
21144 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021145
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021146 /* TDLS Off Channel, Enable tdls channel switch,
21147 when their is only one tdls link and it supports */
21148 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
21149 if ((numCurrTdlsPeers == 1) &&
21150 (TRUE == pTdlsPeer->isOffChannelSupported) &&
21151 (TRUE == pTdlsPeer->isOffChannelConfigured))
21152 {
21153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21154 "%s: Send TDLS channel switch request for channel %d",
21155 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053021156
21157 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021158 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
21159 channel = pTdlsPeer->peerParams.channel;
21160
21161 mutex_unlock(&pHddCtx->tdls_lock);
21162
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021163 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
21164 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021165 peerMac,
21166 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021167 TDLS_OFF_CHANNEL_BW_OFFSET,
21168 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021169 if (ret != VOS_STATUS_SUCCESS) {
21170 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
21171 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021172 }
21173 else
21174 {
21175 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21176 "%s: TDLS channel switch request not sent"
21177 " numCurrTdlsPeers %d "
21178 "isOffChannelSupported %d "
21179 "isOffChannelConfigured %d",
21180 __func__, numCurrTdlsPeers,
21181 pTdlsPeer->isOffChannelSupported,
21182 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021183 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021184 }
21185
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070021186 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021187 else
21188 mutex_unlock(&pHddCtx->tdls_lock);
21189
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021190 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021191
21192 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021193 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
21194 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021195 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021196 int ac;
21197 uint8 ucAc[4] = { WLANTL_AC_VO,
21198 WLANTL_AC_VI,
21199 WLANTL_AC_BK,
21200 WLANTL_AC_BE };
21201 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
21202 for(ac=0; ac < 4; ac++)
21203 {
21204 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
21205 pTdlsPeer->staId, ucAc[ac],
21206 tlTid[ac], tlTid[ac], 0, 0,
21207 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021208 if (status != VOS_STATUS_SUCCESS) {
21209 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
21210 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021211 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021212 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021213 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021214
Bhargav Shah66896792015-10-01 18:17:37 +053021215 /* stop TCP delack timer if TDLS is enable */
21216 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21217 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053021218 hdd_wlan_tdls_enable_link_event(peer,
21219 pTdlsPeer->isOffChannelSupported,
21220 pTdlsPeer->isOffChannelConfigured,
21221 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021222 }
21223 break;
21224 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080021225 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021226 tANI_U16 numCurrTdlsPeers = 0;
21227 hddTdlsPeer_t *connPeer = NULL;
21228
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021229 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21230 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
21231 __func__, MAC_ADDR_ARRAY(peer));
21232
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021233 mutex_lock(&pHddCtx->tdls_lock);
21234 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021235
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021236
Sunil Dutt41de4e22013-11-14 18:09:02 +053021237 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021238 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021239 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21240 " (oper %d) not exsting. ignored",
21241 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
21242 return -EINVAL;
21243 }
21244
21245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21246 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
21247 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
21248 "NL80211_TDLS_DISABLE_LINK");
21249
Hoonki Lee5305c3a2013-04-29 23:28:59 -070021250 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080021251 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021252 long status;
21253
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053021254 /* set tdls off channel status to false for this peer */
21255 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053021256 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
21257 eTDLS_LINK_TEARING,
21258 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
21259 eTDLS_LINK_UNSPECIFIED:
21260 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021261 mutex_unlock(&pHddCtx->tdls_lock);
21262
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021263 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
21264
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021265 status = sme_DeleteTdlsPeerSta(
21266 WLAN_HDD_GET_HAL_CTX(pAdapter),
21267 pAdapter->sessionId, peer );
21268 if (status != VOS_STATUS_SUCCESS) {
21269 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
21270 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021271
21272 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
21273 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021274
21275 mutex_lock(&pHddCtx->tdls_lock);
21276 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21277 if ( NULL == pTdlsPeer ) {
21278 mutex_unlock(&pHddCtx->tdls_lock);
21279 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21280 " peer was freed in other context",
21281 __func__, MAC_ADDR_ARRAY(peer));
21282 return -EINVAL;
21283 }
21284
Atul Mittal271a7652014-09-12 13:18:22 +053021285 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053021286 eTDLS_LINK_IDLE,
21287 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021288 mutex_unlock(&pHddCtx->tdls_lock);
21289
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021290 if (status <= 0)
21291 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021292 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21293 "%s: Del station failed status %ld",
21294 __func__, status);
21295 return -EPERM;
21296 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021297
21298 /* TDLS Off Channel, Enable tdls channel switch,
21299 when their is only one tdls link and it supports */
21300 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
21301 if (numCurrTdlsPeers == 1)
21302 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021303 tSirMacAddr peerMac;
21304 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021305
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021306 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021307 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021308
21309 if (connPeer == NULL) {
21310 mutex_unlock(&pHddCtx->tdls_lock);
21311 hddLog(VOS_TRACE_LEVEL_ERROR,
21312 "%s connPeer is NULL", __func__);
21313 return -EINVAL;
21314 }
21315
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021316 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
21317 channel = connPeer->peerParams.channel;
21318
21319 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21320 "%s: TDLS channel switch "
21321 "isOffChannelSupported %d "
21322 "isOffChannelConfigured %d "
21323 "isOffChannelEstablished %d",
21324 __func__,
21325 (connPeer ? connPeer->isOffChannelSupported : -1),
21326 (connPeer ? connPeer->isOffChannelConfigured : -1),
21327 (connPeer ? connPeer->isOffChannelEstablished : -1));
21328
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021329 if ((connPeer) &&
21330 (connPeer->isOffChannelSupported == TRUE) &&
21331 (connPeer->isOffChannelConfigured == TRUE))
21332 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053021333 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021334 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021335 status = sme_SendTdlsChanSwitchReq(
21336 WLAN_HDD_GET_HAL_CTX(pAdapter),
21337 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021338 peerMac,
21339 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021340 TDLS_OFF_CHANNEL_BW_OFFSET,
21341 TDLS_CHANNEL_SWITCH_ENABLE);
21342 if (status != VOS_STATUS_SUCCESS) {
21343 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
21344 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021345 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021346 else
21347 mutex_unlock(&pHddCtx->tdls_lock);
21348 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021349 else
21350 {
21351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21352 "%s: TDLS channel switch request not sent "
21353 "numCurrTdlsPeers %d ",
21354 __func__, numCurrTdlsPeers);
21355 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021356 }
21357 else
21358 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021359 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021360 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21361 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080021362 }
Bhargav Shah66896792015-10-01 18:17:37 +053021363 if (numCurrTdlsPeers == 0) {
21364 /* start TCP delack timer if TDLS is disable */
21365 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21366 hdd_manage_delack_timer(pHddCtx);
21367 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021368 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021369 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021370 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021371 {
Atul Mittal115287b2014-07-08 13:26:33 +053021372 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021373
Atul Mittal115287b2014-07-08 13:26:33 +053021374 if (0 != status)
21375 {
21376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021377 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053021378 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021379 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053021380 break;
21381 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021382 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021383 {
Atul Mittal115287b2014-07-08 13:26:33 +053021384 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
21385 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021386 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053021387 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021388
Atul Mittal115287b2014-07-08 13:26:33 +053021389 if (0 != status)
21390 {
21391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021392 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053021393 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053021394 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053021395 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021396 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021397 case NL80211_TDLS_DISCOVERY_REQ:
21398 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021400 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021401 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021402 return -ENOTSUPP;
21403 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21405 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021406 return -ENOTSUPP;
21407 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021408
21409 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021410 return 0;
21411}
Chilam NG571c65a2013-01-19 12:27:36 +053021412
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021413static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021414#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
21415 const u8 *peer,
21416#else
21417 u8 *peer,
21418#endif
21419 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021420{
21421 int ret;
21422
21423 vos_ssr_protect(__func__);
21424 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
21425 vos_ssr_unprotect(__func__);
21426
21427 return ret;
21428}
21429
Chilam NG571c65a2013-01-19 12:27:36 +053021430int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
21431 struct net_device *dev, u8 *peer)
21432{
Arif Hussaina7c8e412013-11-20 11:06:42 -080021433 hddLog(VOS_TRACE_LEVEL_INFO,
21434 "tdls send discover req: "MAC_ADDRESS_STR,
21435 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021436#if TDLS_MGMT_VERSION2
21437 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21438 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21439#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021440#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
21441 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21442 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
21443#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
21444 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21445 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21446#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
21447 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21448 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21449#else
Chilam NG571c65a2013-01-19 12:27:36 +053021450 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21451 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021452#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021453#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053021454}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021455#endif
21456
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021457#ifdef WLAN_FEATURE_GTK_OFFLOAD
21458/*
21459 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
21460 * Callback rountine called upon receiving response for
21461 * get offload info
21462 */
21463void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
21464 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
21465{
21466
21467 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021468 tANI_U8 tempReplayCounter[8];
21469 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021470
21471 ENTER();
21472
21473 if (NULL == pAdapter)
21474 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053021475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021476 "%s: HDD adapter is Null", __func__);
21477 return ;
21478 }
21479
21480 if (NULL == pGtkOffloadGetInfoRsp)
21481 {
21482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21483 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
21484 return ;
21485 }
21486
21487 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
21488 {
21489 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21490 "%s: wlan Failed to get replay counter value",
21491 __func__);
21492 return ;
21493 }
21494
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021495 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21496 /* Update replay counter */
21497 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
21498 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21499
21500 {
21501 /* changing from little to big endian since supplicant
21502 * works on big endian format
21503 */
21504 int i;
21505 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21506
21507 for (i = 0; i < 8; i++)
21508 {
21509 tempReplayCounter[7-i] = (tANI_U8)p[i];
21510 }
21511 }
21512
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021513 /* Update replay counter to NL */
21514 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021515 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021516}
21517
21518/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021519 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021520 * This function is used to offload GTK rekeying job to the firmware.
21521 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021522int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021523 struct cfg80211_gtk_rekey_data *data)
21524{
21525 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21526 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21527 hdd_station_ctx_t *pHddStaCtx;
21528 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021529 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021530 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021531 eHalStatus status = eHAL_STATUS_FAILURE;
21532
21533 ENTER();
21534
21535 if (NULL == pAdapter)
21536 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053021537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021538 "%s: HDD adapter is Null", __func__);
21539 return -ENODEV;
21540 }
21541
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053021542 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21543 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
21544 pAdapter->sessionId, pAdapter->device_mode));
21545
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021546 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021547 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021548 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021549 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021550 }
21551
21552 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21553 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
21554 if (NULL == hHal)
21555 {
21556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21557 "%s: HAL context is Null!!!", __func__);
21558 return -EAGAIN;
21559 }
21560
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021561 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
21562 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
21563 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
21564 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021565 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021566 {
21567 /* changing from big to little endian since driver
21568 * works on little endian format
21569 */
21570 tANI_U8 *p =
21571 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
21572 int i;
21573
21574 for (i = 0; i < 8; i++)
21575 {
21576 p[7-i] = data->replay_ctr[i];
21577 }
21578 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021579
21580 if (TRUE == pHddCtx->hdd_wlan_suspended)
21581 {
21582 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021583 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
21584 sizeof (tSirGtkOffloadParams));
21585 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021586 pAdapter->sessionId);
21587
21588 if (eHAL_STATUS_SUCCESS != status)
21589 {
21590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21591 "%s: sme_SetGTKOffload failed, returned %d",
21592 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021593
21594 /* Need to clear any trace of key value in the memory.
21595 * Thus zero out the memory even though it is local
21596 * variable.
21597 */
21598 vos_mem_zero(&hddGtkOffloadReqParams,
21599 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021600 return status;
21601 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21603 "%s: sme_SetGTKOffload successfull", __func__);
21604 }
21605 else
21606 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21608 "%s: wlan not suspended GTKOffload request is stored",
21609 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021610 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021611
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021612 /* Need to clear any trace of key value in the memory.
21613 * Thus zero out the memory even though it is local
21614 * variable.
21615 */
21616 vos_mem_zero(&hddGtkOffloadReqParams,
21617 sizeof(hddGtkOffloadReqParams));
21618
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021619 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021620 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021621}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021622
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021623int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
21624 struct cfg80211_gtk_rekey_data *data)
21625{
21626 int ret;
21627
21628 vos_ssr_protect(__func__);
21629 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
21630 vos_ssr_unprotect(__func__);
21631
21632 return ret;
21633}
21634#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021635/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021636 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021637 * This function is used to set access control policy
21638 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021639static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21640 struct net_device *dev,
21641 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021642{
21643 int i;
21644 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21645 hdd_hostapd_state_t *pHostapdState;
21646 tsap_Config_t *pConfig;
21647 v_CONTEXT_t pVosContext = NULL;
21648 hdd_context_t *pHddCtx;
21649 int status;
21650
21651 ENTER();
21652
21653 if (NULL == pAdapter)
21654 {
21655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21656 "%s: HDD adapter is Null", __func__);
21657 return -ENODEV;
21658 }
21659
21660 if (NULL == params)
21661 {
21662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21663 "%s: params is Null", __func__);
21664 return -EINVAL;
21665 }
21666
21667 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21668 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021669 if (0 != status)
21670 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021671 return status;
21672 }
21673
21674 pVosContext = pHddCtx->pvosContext;
21675 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
21676
21677 if (NULL == pHostapdState)
21678 {
21679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21680 "%s: pHostapdState is Null", __func__);
21681 return -EINVAL;
21682 }
21683
21684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
21685 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021686 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21687 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
21688 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021689
21690 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
21691 {
21692 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
21693
21694 /* default value */
21695 pConfig->num_accept_mac = 0;
21696 pConfig->num_deny_mac = 0;
21697
21698 /**
21699 * access control policy
21700 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
21701 * listed in hostapd.deny file.
21702 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
21703 * listed in hostapd.accept file.
21704 */
21705 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
21706 {
21707 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
21708 }
21709 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
21710 {
21711 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
21712 }
21713 else
21714 {
21715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21716 "%s:Acl Policy : %d is not supported",
21717 __func__, params->acl_policy);
21718 return -ENOTSUPP;
21719 }
21720
21721 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
21722 {
21723 pConfig->num_accept_mac = params->n_acl_entries;
21724 for (i = 0; i < params->n_acl_entries; i++)
21725 {
21726 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21727 "** Add ACL MAC entry %i in WhiletList :"
21728 MAC_ADDRESS_STR, i,
21729 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21730
21731 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
21732 sizeof(qcmacaddr));
21733 }
21734 }
21735 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
21736 {
21737 pConfig->num_deny_mac = params->n_acl_entries;
21738 for (i = 0; i < params->n_acl_entries; i++)
21739 {
21740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21741 "** Add ACL MAC entry %i in BlackList :"
21742 MAC_ADDRESS_STR, i,
21743 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21744
21745 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
21746 sizeof(qcmacaddr));
21747 }
21748 }
21749
21750 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
21751 {
21752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21753 "%s: SAP Set Mac Acl fail", __func__);
21754 return -EINVAL;
21755 }
21756 }
21757 else
21758 {
21759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053021760 "%s: Invalid device_mode = %s (%d)",
21761 __func__, hdd_device_modetoString(pAdapter->device_mode),
21762 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021763 return -EINVAL;
21764 }
21765
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021766 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021767 return 0;
21768}
21769
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021770static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21771 struct net_device *dev,
21772 const struct cfg80211_acl_data *params)
21773{
21774 int ret;
21775 vos_ssr_protect(__func__);
21776 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
21777 vos_ssr_unprotect(__func__);
21778
21779 return ret;
21780}
21781
Leo Chang9056f462013-08-01 19:21:11 -070021782#ifdef WLAN_NL80211_TESTMODE
21783#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070021784void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070021785(
21786 void *pAdapter,
21787 void *indCont
21788)
21789{
Leo Changd9df8aa2013-09-26 13:32:26 -070021790 tSirLPHBInd *lphbInd;
21791 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053021792 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070021793
21794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021795 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070021796
c_hpothu73f35e62014-04-18 13:40:08 +053021797 if (pAdapter == NULL)
21798 {
21799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21800 "%s: pAdapter is NULL\n",__func__);
21801 return;
21802 }
21803
Leo Chang9056f462013-08-01 19:21:11 -070021804 if (NULL == indCont)
21805 {
21806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021807 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070021808 return;
21809 }
21810
c_hpothu73f35e62014-04-18 13:40:08 +053021811 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070021812 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070021813 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053021814 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070021815 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070021816 GFP_ATOMIC);
21817 if (!skb)
21818 {
21819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21820 "LPHB timeout, NL buffer alloc fail");
21821 return;
21822 }
21823
Leo Changac3ba772013-10-07 09:47:04 -070021824 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070021825 {
21826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21827 "WLAN_HDD_TM_ATTR_CMD put fail");
21828 goto nla_put_failure;
21829 }
Leo Changac3ba772013-10-07 09:47:04 -070021830 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070021831 {
21832 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21833 "WLAN_HDD_TM_ATTR_TYPE put fail");
21834 goto nla_put_failure;
21835 }
Leo Changac3ba772013-10-07 09:47:04 -070021836 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070021837 sizeof(tSirLPHBInd), lphbInd))
21838 {
21839 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21840 "WLAN_HDD_TM_ATTR_DATA put fail");
21841 goto nla_put_failure;
21842 }
Leo Chang9056f462013-08-01 19:21:11 -070021843 cfg80211_testmode_event(skb, GFP_ATOMIC);
21844 return;
21845
21846nla_put_failure:
21847 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21848 "NLA Put fail");
21849 kfree_skb(skb);
21850
21851 return;
21852}
21853#endif /* FEATURE_WLAN_LPHB */
21854
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021855static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070021856{
21857 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
21858 int err = 0;
21859#ifdef FEATURE_WLAN_LPHB
21860 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070021861 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021862
21863 ENTER();
21864
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021865 err = wlan_hdd_validate_context(pHddCtx);
21866 if (0 != err)
21867 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021868 return err;
21869 }
Leo Chang9056f462013-08-01 19:21:11 -070021870#endif /* FEATURE_WLAN_LPHB */
21871
21872 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
21873 if (err)
21874 {
21875 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21876 "%s Testmode INV ATTR", __func__);
21877 return err;
21878 }
21879
21880 if (!tb[WLAN_HDD_TM_ATTR_CMD])
21881 {
21882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21883 "%s Testmode INV CMD", __func__);
21884 return -EINVAL;
21885 }
21886
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021887 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21888 TRACE_CODE_HDD_CFG80211_TESTMODE,
21889 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070021890 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
21891 {
21892#ifdef FEATURE_WLAN_LPHB
21893 /* Low Power Heartbeat configuration request */
21894 case WLAN_HDD_TM_CMD_WLAN_HB:
21895 {
21896 int buf_len;
21897 void *buf;
21898 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080021899 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070021900
21901 if (!tb[WLAN_HDD_TM_ATTR_DATA])
21902 {
21903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21904 "%s Testmode INV DATA", __func__);
21905 return -EINVAL;
21906 }
21907
21908 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
21909 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080021910
Manjeet Singh3c577442017-02-10 19:03:38 +053021911 if (buf_len > sizeof(*hb_params)) {
21912 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
21913 buf_len);
21914 return -ERANGE;
21915 }
21916
Amar Singhal05852702014-02-04 14:40:00 -080021917 hb_params_temp =(tSirLPHBReq *)buf;
21918 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
21919 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
21920 return -EINVAL;
21921
Leo Chang9056f462013-08-01 19:21:11 -070021922 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
21923 if (NULL == hb_params)
21924 {
21925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21926 "%s Request Buffer Alloc Fail", __func__);
21927 return -EINVAL;
21928 }
21929
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053021930 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070021931 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070021932 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
21933 hb_params,
21934 wlan_hdd_cfg80211_lphb_ind_handler);
21935 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070021936 {
Leo Changd9df8aa2013-09-26 13:32:26 -070021937 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21938 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070021939 vos_mem_free(hb_params);
21940 }
Leo Chang9056f462013-08-01 19:21:11 -070021941 return 0;
21942 }
21943#endif /* FEATURE_WLAN_LPHB */
21944 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21946 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070021947 return -EOPNOTSUPP;
21948 }
21949
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021950 EXIT();
21951 return err;
Leo Chang9056f462013-08-01 19:21:11 -070021952}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021953
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053021954static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
21955#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
21956 struct wireless_dev *wdev,
21957#endif
21958 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021959{
21960 int ret;
21961
21962 vos_ssr_protect(__func__);
21963 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
21964 vos_ssr_unprotect(__func__);
21965
21966 return ret;
21967}
Leo Chang9056f462013-08-01 19:21:11 -070021968#endif /* CONFIG_NL80211_TESTMODE */
21969
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021970extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021971static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021972 struct net_device *dev,
21973 int idx, struct survey_info *survey)
21974{
21975 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21976 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053021977 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021978 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053021979 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021980 v_S7_t snr,rssi;
21981 int status, i, j, filled = 0;
21982
21983 ENTER();
21984
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021985 if (NULL == pAdapter)
21986 {
21987 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21988 "%s: HDD adapter is Null", __func__);
21989 return -ENODEV;
21990 }
21991
21992 if (NULL == wiphy)
21993 {
21994 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21995 "%s: wiphy is Null", __func__);
21996 return -ENODEV;
21997 }
21998
21999 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
22000 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022001 if (0 != status)
22002 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022003 return status;
22004 }
22005
Mihir Sheted9072e02013-08-21 17:02:29 +053022006 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
22007
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022008 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053022009 0 != pAdapter->survey_idx ||
22010 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022011 {
22012 /* The survey dump ops when implemented completely is expected to
22013 * return a survey of all channels and the ops is called by the
22014 * kernel with incremental values of the argument 'idx' till it
22015 * returns -ENONET. But we can only support the survey for the
22016 * operating channel for now. survey_idx is used to track
22017 * that the ops is called only once and then return -ENONET for
22018 * the next iteration
22019 */
22020 pAdapter->survey_idx = 0;
22021 return -ENONET;
22022 }
22023
Mukul Sharma9d5233b2015-06-11 20:28:20 +053022024 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
22025 {
22026 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22027 "%s: Roaming in progress, hence return ", __func__);
22028 return -ENONET;
22029 }
22030
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022031 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
22032
22033 wlan_hdd_get_snr(pAdapter, &snr);
22034 wlan_hdd_get_rssi(pAdapter, &rssi);
22035
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022036 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
22037 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
22038 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022039 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
22040 hdd_wlan_get_freq(channel, &freq);
22041
22042
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053022043 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022044 {
22045 if (NULL == wiphy->bands[i])
22046 {
22047 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
22048 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
22049 continue;
22050 }
22051
22052 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
22053 {
22054 struct ieee80211_supported_band *band = wiphy->bands[i];
22055
22056 if (band->channels[j].center_freq == (v_U16_t)freq)
22057 {
22058 survey->channel = &band->channels[j];
22059 /* The Rx BDs contain SNR values in dB for the received frames
22060 * while the supplicant expects noise. So we calculate and
22061 * return the value of noise (dBm)
22062 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
22063 */
22064 survey->noise = rssi - snr;
22065 survey->filled = SURVEY_INFO_NOISE_DBM;
22066 filled = 1;
22067 }
22068 }
22069 }
22070
22071 if (filled)
22072 pAdapter->survey_idx = 1;
22073 else
22074 {
22075 pAdapter->survey_idx = 0;
22076 return -ENONET;
22077 }
22078
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022079 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022080 return 0;
22081}
22082
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053022083static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
22084 struct net_device *dev,
22085 int idx, struct survey_info *survey)
22086{
22087 int ret;
22088
22089 vos_ssr_protect(__func__);
22090 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
22091 vos_ssr_unprotect(__func__);
22092
22093 return ret;
22094}
22095
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022096/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022097 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022098 * this is called when cfg80211 driver resume
22099 * driver updates latest sched_scan scan result(if any) to cfg80211 database
22100 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022101int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022102{
22103 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
22104 hdd_adapter_t *pAdapter;
22105 hdd_adapter_list_node_t *pAdapterNode, *pNext;
22106 VOS_STATUS status = VOS_STATUS_SUCCESS;
22107
22108 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022109
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053022110 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022111 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022112 return 0;
22113 }
22114
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022115 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
22116 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053022117
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053022118 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053022119 {
22120 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22121 "%s: Resume SoftAP", __func__);
22122 hdd_set_wlan_suspend_mode(false);
22123 }
22124
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022125 spin_lock(&pHddCtx->schedScan_lock);
22126 pHddCtx->isWiphySuspended = FALSE;
22127 if (TRUE != pHddCtx->isSchedScanUpdatePending)
22128 {
22129 spin_unlock(&pHddCtx->schedScan_lock);
22130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22131 "%s: Return resume is not due to PNO indication", __func__);
22132 return 0;
22133 }
22134 // Reset flag to avoid updatating cfg80211 data old results again
22135 pHddCtx->isSchedScanUpdatePending = FALSE;
22136 spin_unlock(&pHddCtx->schedScan_lock);
22137
22138 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
22139
22140 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
22141 {
22142 pAdapter = pAdapterNode->pAdapter;
22143 if ( (NULL != pAdapter) &&
22144 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
22145 {
22146 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053022147 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
22149 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053022150 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022151 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053022152 {
22153 /* Acquire wakelock to handle the case where APP's tries to
22154 * suspend immediately after updating the scan results. Whis
22155 * results in app's is in suspended state and not able to
22156 * process the connect request to AP
22157 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053022158 hdd_prevent_suspend_timeout(2000,
22159 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022160 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053022161 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022162
22163 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22164 "%s : cfg80211 scan result database updated", __func__);
22165
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022166 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022167 return 0;
22168
22169 }
22170 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
22171 pAdapterNode = pNext;
22172 }
22173
22174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22175 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022176 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022177 return 0;
22178}
22179
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022180int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
22181{
22182 int ret;
22183
22184 vos_ssr_protect(__func__);
22185 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
22186 vos_ssr_unprotect(__func__);
22187
22188 return ret;
22189}
22190
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022191/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022192 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022193 * this is called when cfg80211 driver suspends
22194 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022195int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022196 struct cfg80211_wowlan *wow)
22197{
22198 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022199 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022200
22201 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022202
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022203 ret = wlan_hdd_validate_context(pHddCtx);
22204 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022205 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022206 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022207 }
22208
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053022209 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053022210 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22211 "%s: Suspend SoftAP", __func__);
22212 hdd_set_wlan_suspend_mode(true);
22213 }
22214
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022215
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022216 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
22217 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
22218 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022219 pHddCtx->isWiphySuspended = TRUE;
22220
22221 EXIT();
22222
22223 return 0;
22224}
22225
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022226int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
22227 struct cfg80211_wowlan *wow)
22228{
22229 int ret;
22230
22231 vos_ssr_protect(__func__);
22232 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
22233 vos_ssr_unprotect(__func__);
22234
22235 return ret;
22236}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022237
22238#ifdef FEATURE_OEM_DATA_SUPPORT
22239static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022240 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022241{
22242 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22243
22244 ENTER();
22245
22246 if (wlan_hdd_validate_context(pHddCtx)) {
22247 return;
22248 }
22249 if (!pMsg)
22250 {
22251 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
22252 return;
22253 }
22254
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022255 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022256
22257 EXIT();
22258 return;
22259
22260}
22261
22262void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022263 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022264{
22265 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22266
22267 ENTER();
22268
22269 if (wlan_hdd_validate_context(pHddCtx)) {
22270 return;
22271 }
22272
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022273 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022274
22275 switch(evType) {
22276 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022277 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022278 break;
22279 default:
22280 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
22281 break;
22282 }
22283 EXIT();
22284}
22285#endif
22286
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022287#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22288 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022289/**
22290 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
22291 * @wiphy: Pointer to wiphy
22292 * @wdev: Pointer to wireless device structure
22293 *
22294 * This function is used to abort an ongoing scan
22295 *
22296 * Return: None
22297 */
22298static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22299 struct wireless_dev *wdev)
22300{
22301 struct net_device *dev = wdev->netdev;
22302 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22303 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
22304 int ret;
22305
22306 ENTER();
22307
22308 if (NULL == adapter) {
22309 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
22310 return;
22311 }
22312
22313 ret = wlan_hdd_validate_context(hdd_ctx);
22314 if (0 != ret)
22315 return;
22316
22317 wlan_hdd_scan_abort(adapter);
22318
22319 return;
22320}
22321
22322/**
22323 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
22324 * @wiphy: Pointer to wiphy
22325 * @wdev: Pointer to wireless device structure
22326 *
22327 * Return: None
22328 */
22329void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22330 struct wireless_dev *wdev)
22331{
22332 vos_ssr_protect(__func__);
22333 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
22334 vos_ssr_unprotect(__func__);
22335
22336 return;
22337}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022338#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022339
Abhishek Singh936c6932017-11-07 17:28:23 +053022340#ifdef CHANNEL_SWITCH_SUPPORTED
22341/**
22342 * __wlan_hdd_cfg80211_channel_switch()- function to switch
22343 * channel in SAP/GO
22344 * @wiphy: wiphy pointer
22345 * @dev: dev pointer.
22346 * @csa_params: Change channel params
22347 *
22348 * This function is called to switch channel in SAP/GO
22349 *
22350 * Return: 0 if success else return non zero
22351 */
22352static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22353 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22354{
22355 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22356 hdd_context_t *hdd_ctx;
22357 uint8_t channel;
22358 int ret;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022359 ptSapContext sap_ctx;
Abhishek Singh936c6932017-11-07 17:28:23 +053022360 v_CONTEXT_t vos_ctx;
22361
22362 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
22363
22364 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
22365 ret = wlan_hdd_validate_context(hdd_ctx);
22366 if (ret)
22367 return ret;
22368
22369 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
22370 if (!vos_ctx) {
22371 hddLog(LOGE, FL("Vos ctx is null"));
22372 return -EINVAL;
22373 }
22374
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022375 if (WLAN_HDD_SOFTAP != adapter->device_mode)
Abhishek Singh936c6932017-11-07 17:28:23 +053022376 return -ENOTSUPP;
22377
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022378 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
22379 if (!sap_ctx) {
22380 hddLog(LOGE, FL("sap_ctx is NULL"));
22381 return -EINVAL;
22382 }
22383
22384 ret = wlansap_chk_n_set_chan_change_in_progress(sap_ctx);
22385 if (ret)
22386 return ret;
22387
22388 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
22389
Abhishek Singh936c6932017-11-07 17:28:23 +053022390 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053022391 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053022392
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022393 if (ret) {
22394 wlansap_reset_chan_change_in_progress(sap_ctx);
22395 complete(&sap_ctx->ecsa_info.chan_switch_comp);
22396 }
22397
Abhishek Singh936c6932017-11-07 17:28:23 +053022398 return ret;
22399}
22400
22401/**
22402 * wlan_hdd_cfg80211_channel_switch()- function to switch
22403 * channel in SAP/GO
22404 * @wiphy: wiphy pointer
22405 * @dev: dev pointer.
22406 * @csa_params: Change channel params
22407 *
22408 * This function is called to switch channel in SAP/GO
22409 *
22410 * Return: 0 if success else return non zero
22411 */
22412static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22413 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22414{
22415 int ret;
22416
22417 vos_ssr_protect(__func__);
22418 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
22419 vos_ssr_unprotect(__func__);
22420
22421 return ret;
22422}
22423#endif
22424
Jeff Johnson295189b2012-06-20 16:38:30 -070022425/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053022426static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070022427{
22428 .add_virtual_intf = wlan_hdd_add_virtual_intf,
22429 .del_virtual_intf = wlan_hdd_del_virtual_intf,
22430 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
22431 .change_station = wlan_hdd_change_station,
22432#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
22433 .add_beacon = wlan_hdd_cfg80211_add_beacon,
22434 .del_beacon = wlan_hdd_cfg80211_del_beacon,
22435 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022436#else
22437 .start_ap = wlan_hdd_cfg80211_start_ap,
22438 .change_beacon = wlan_hdd_cfg80211_change_beacon,
22439 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070022440#endif
22441 .change_bss = wlan_hdd_cfg80211_change_bss,
22442 .add_key = wlan_hdd_cfg80211_add_key,
22443 .get_key = wlan_hdd_cfg80211_get_key,
22444 .del_key = wlan_hdd_cfg80211_del_key,
22445 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022446#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070022447 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022448#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022449 .scan = wlan_hdd_cfg80211_scan,
22450 .connect = wlan_hdd_cfg80211_connect,
22451 .disconnect = wlan_hdd_cfg80211_disconnect,
22452 .join_ibss = wlan_hdd_cfg80211_join_ibss,
22453 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
22454 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
22455 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
22456 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070022457 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
22458 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053022459 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070022460#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
22461 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
22462 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
22463 .set_txq_params = wlan_hdd_set_txq_params,
22464#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022465 .get_station = wlan_hdd_cfg80211_get_station,
22466 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
22467 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022468 .add_station = wlan_hdd_cfg80211_add_station,
22469#ifdef FEATURE_WLAN_LFR
22470 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
22471 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
22472 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
22473#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070022474#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
22475 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
22476#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080022477#ifdef FEATURE_WLAN_TDLS
22478 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
22479 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
22480#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053022481#ifdef WLAN_FEATURE_GTK_OFFLOAD
22482 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
22483#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053022484#ifdef FEATURE_WLAN_SCAN_PNO
22485 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
22486 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
22487#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022488 .resume = wlan_hdd_cfg80211_resume_wlan,
22489 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053022490 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070022491#ifdef WLAN_NL80211_TESTMODE
22492 .testmode_cmd = wlan_hdd_cfg80211_testmode,
22493#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022494 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022495#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22496 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022497 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022498#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053022499#ifdef CHANNEL_SWITCH_SUPPORTED
22500 .channel_switch = wlan_hdd_cfg80211_channel_switch,
22501#endif
22502
Jeff Johnson295189b2012-06-20 16:38:30 -070022503};
22504