blob: 93619aeb1352c3746613f5262204a6b68d268075 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05302 * Copyright (c) 2012-2018 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
307 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
308 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
309 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
310 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
311 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
312 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
313};
314
Jeff Johnson295189b2012-06-20 16:38:30 -0700315static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
316{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530317 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700318 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530319 .band = HDD_NL80211_BAND_5GHZ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700320 .bitrates = a_mode_rates,
321 .n_bitrates = a_mode_rates_size,
322 .ht_cap.ht_supported = 1,
323 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
324 | IEEE80211_HT_CAP_GRN_FLD
325 | IEEE80211_HT_CAP_DSSSCCK40
326 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
327 | IEEE80211_HT_CAP_SGI_40
328 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
329 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
330 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
331 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
332 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
333 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
334};
335
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530336/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700337 TX/RX direction for each kind of interface */
338static const struct ieee80211_txrx_stypes
339wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
340 [NL80211_IFTYPE_STATION] = {
341 .tx = 0xffff,
342 .rx = BIT(SIR_MAC_MGMT_ACTION) |
343 BIT(SIR_MAC_MGMT_PROBE_REQ),
344 },
345 [NL80211_IFTYPE_AP] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
348 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
349 BIT(SIR_MAC_MGMT_PROBE_REQ) |
350 BIT(SIR_MAC_MGMT_DISASSOC) |
351 BIT(SIR_MAC_MGMT_AUTH) |
352 BIT(SIR_MAC_MGMT_DEAUTH) |
353 BIT(SIR_MAC_MGMT_ACTION),
354 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700355 [NL80211_IFTYPE_ADHOC] = {
356 .tx = 0xffff,
357 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
358 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
359 BIT(SIR_MAC_MGMT_PROBE_REQ) |
360 BIT(SIR_MAC_MGMT_DISASSOC) |
361 BIT(SIR_MAC_MGMT_AUTH) |
362 BIT(SIR_MAC_MGMT_DEAUTH) |
363 BIT(SIR_MAC_MGMT_ACTION),
364 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700365 [NL80211_IFTYPE_P2P_CLIENT] = {
366 .tx = 0xffff,
367 .rx = BIT(SIR_MAC_MGMT_ACTION) |
368 BIT(SIR_MAC_MGMT_PROBE_REQ),
369 },
370 [NL80211_IFTYPE_P2P_GO] = {
371 /* This is also same as for SoftAP */
372 .tx = 0xffff,
373 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
374 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
375 BIT(SIR_MAC_MGMT_PROBE_REQ) |
376 BIT(SIR_MAC_MGMT_DISASSOC) |
377 BIT(SIR_MAC_MGMT_AUTH) |
378 BIT(SIR_MAC_MGMT_DEAUTH) |
379 BIT(SIR_MAC_MGMT_ACTION),
380 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700381};
382
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800383#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800384static const struct ieee80211_iface_limit
385wlan_hdd_iface_limit[] = {
386 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800387 /* max = 3 ; Our driver create two interfaces during driver init
388 * wlan0 and p2p0 interfaces. p2p0 is considered as station
389 * interface until a group is formed. In JB architecture, once the
390 * group is formed, interface type of p2p0 is changed to P2P GO or
391 * Client.
392 * When supplicant remove the group, it first issue a set interface
393 * cmd to change the mode back to Station. In JB this works fine as
394 * we advertize two station type interface during driver init.
395 * Some vendors create separate interface for P2P GO/Client,
396 * after group formation(Third one). But while group remove
397 * supplicant first tries to change the mode(3rd interface) to STATION
398 * But as we advertized only two sta type interfaces nl80211 was
399 * returning error for the third one which was leading to failure in
400 * delete interface. Ideally while removing the group, supplicant
401 * should not try to change the 3rd interface mode to Station type.
402 * Till we get a fix in wpa_supplicant, we advertize max STA
403 * interface type to 3
404 */
405 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800406 .types = BIT(NL80211_IFTYPE_STATION),
407 },
408 {
409 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700410 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 },
412 {
413 .max = 1,
414 .types = BIT(NL80211_IFTYPE_P2P_GO) |
415 BIT(NL80211_IFTYPE_P2P_CLIENT),
416 },
417};
418
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530419/* interface limits for sta + monitor SCC */
420static const struct ieee80211_iface_limit
421wlan_hdd_iface_sta_mon_limit[] = {
422 {
423 .max = 1,
424 .types = BIT(NL80211_IFTYPE_STATION),
425 },
426 {
427 .max = 1, /* Monitor interface */
428 .types = BIT(NL80211_IFTYPE_MONITOR),
429 },
430};
431
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800432/* By default, only single channel concurrency is allowed */
433static struct ieee80211_iface_combination
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530434wlan_hdd_iface_combination[] = {
435 {
436 .limits = wlan_hdd_iface_limit,
437 .num_different_channels = 1,
438 /*
439 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
440 * and p2p0 interfaces during driver init
441 * Some vendors create separate interface for P2P operations.
442 * wlan0: STA interface
443 * p2p0: P2P Device interface, action frames goes
444 * through this interface.
445 * p2p-xx: P2P interface, After GO negotiation this interface is
446 * created for p2p operations(GO/CLIENT interface).
447 */
448 .max_interfaces = WLAN_MAX_INTERFACES,
449 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
450 .beacon_int_infra_match = false,
451 },
452 {
453 .limits = wlan_hdd_iface_sta_mon_limit,
454 .num_different_channels = 1,
455 .max_interfaces = WLAN_STA_AND_MON_INTERFACES,
456 .n_limits = ARRAY_SIZE(wlan_hdd_iface_sta_mon_limit),
457 .beacon_int_infra_match = false,
458 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800459};
460#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800461
Nachiket Kukade5b2e7332018-04-06 14:40:22 +0530462#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
463static const struct wiphy_wowlan_support wowlan_support_cfg80211_init = {
Nachiket Kukade1e1b90e2018-05-10 15:26:13 +0530464 .flags = WIPHY_WOWLAN_ANY |
465 WIPHY_WOWLAN_MAGIC_PKT,
Nachiket Kukade5b2e7332018-04-06 14:40:22 +0530466 .n_patterns = WOWL_MAX_PTRNS_ALLOWED,
467 .pattern_min_len = 1,
468 .pattern_max_len = WOWL_PTRN_MAX_SIZE,
469};
470#endif
471
Jeff Johnson295189b2012-06-20 16:38:30 -0700472static struct cfg80211_ops wlan_hdd_cfg80211_ops;
473
474/* Data rate 100KBPS based on IE Index */
475struct index_data_rate_type
476{
477 v_U8_t beacon_rate_index;
478 v_U16_t supported_rate[4];
479};
480
481/* 11B, 11G Rate table include Basic rate and Extended rate
482 The IDX field is the rate index
483 The HI field is the rate when RSSI is strong or being ignored
484 (in this case we report actual rate)
485 The MID field is the rate when RSSI is moderate
486 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
487 The LO field is the rate when RSSI is low
488 (in this case we don't report rates, actual current rate used)
489 */
490static const struct
491{
492 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700493 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700494} supported_data_rate[] =
495{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700496/* IDX HI HM LM LO (RSSI-based index */
497 {2, { 10, 10, 10, 0}},
498 {4, { 20, 20, 10, 0}},
499 {11, { 55, 20, 10, 0}},
500 {12, { 60, 55, 20, 0}},
501 {18, { 90, 55, 20, 0}},
502 {22, {110, 55, 20, 0}},
503 {24, {120, 90, 60, 0}},
504 {36, {180, 120, 60, 0}},
505 {44, {220, 180, 60, 0}},
506 {48, {240, 180, 90, 0}},
507 {66, {330, 180, 90, 0}},
508 {72, {360, 240, 90, 0}},
509 {96, {480, 240, 120, 0}},
510 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700511};
512
513/* MCS Based rate table */
514static struct index_data_rate_type supported_mcs_rate[] =
515{
516/* MCS L20 L40 S20 S40 */
517 {0, {65, 135, 72, 150}},
518 {1, {130, 270, 144, 300}},
519 {2, {195, 405, 217, 450}},
520 {3, {260, 540, 289, 600}},
521 {4, {390, 810, 433, 900}},
522 {5, {520, 1080, 578, 1200}},
523 {6, {585, 1215, 650, 1350}},
524 {7, {650, 1350, 722, 1500}}
525};
526
Leo Chang6f8870f2013-03-26 18:11:36 -0700527#ifdef WLAN_FEATURE_11AC
528
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530529#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700530
531struct index_vht_data_rate_type
532{
533 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530534 v_U16_t supported_VHT80_rate[2];
535 v_U16_t supported_VHT40_rate[2];
536 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700537};
538
539typedef enum
540{
541 DATA_RATE_11AC_MAX_MCS_7,
542 DATA_RATE_11AC_MAX_MCS_8,
543 DATA_RATE_11AC_MAX_MCS_9,
544 DATA_RATE_11AC_MAX_MCS_NA
545} eDataRate11ACMaxMcs;
546
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530547/* SSID broadcast type */
548typedef enum eSSIDBcastType
549{
550 eBCAST_UNKNOWN = 0,
551 eBCAST_NORMAL = 1,
552 eBCAST_HIDDEN = 2,
553} tSSIDBcastType;
554
Leo Chang6f8870f2013-03-26 18:11:36 -0700555/* MCS Based VHT rate table */
556static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
557{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530558/* MCS L80 S80 L40 S40 L20 S40*/
559 {0, {293, 325}, {135, 150}, {65, 72}},
560 {1, {585, 650}, {270, 300}, {130, 144}},
561 {2, {878, 975}, {405, 450}, {195, 217}},
562 {3, {1170, 1300}, {540, 600}, {260, 289}},
563 {4, {1755, 1950}, {810, 900}, {390, 433}},
564 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
565 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
566 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
567 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
568 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700569};
570#endif /* WLAN_FEATURE_11AC */
571
c_hpothu79aab322014-07-14 21:11:01 +0530572/*array index points to MCS and array value points respective rssi*/
573static int rssiMcsTbl[][10] =
574{
575/*MCS 0 1 2 3 4 5 6 7 8 9*/
576 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
577 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
578 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
579};
580
Jeff Johnson295189b2012-06-20 16:38:30 -0700581extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530582#ifdef FEATURE_WLAN_SCAN_PNO
583static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
584#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700585
Leo Chang9056f462013-08-01 19:21:11 -0700586#ifdef WLAN_NL80211_TESTMODE
587enum wlan_hdd_tm_attr
588{
589 WLAN_HDD_TM_ATTR_INVALID = 0,
590 WLAN_HDD_TM_ATTR_CMD = 1,
591 WLAN_HDD_TM_ATTR_DATA = 2,
592 WLAN_HDD_TM_ATTR_TYPE = 3,
593 /* keep last */
594 WLAN_HDD_TM_ATTR_AFTER_LAST,
595 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
596};
597
598enum wlan_hdd_tm_cmd
599{
600 WLAN_HDD_TM_CMD_WLAN_HB = 1,
601};
602
603#define WLAN_HDD_TM_DATA_MAX_LEN 5000
604
605static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
606{
607 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
608 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
609 .len = WLAN_HDD_TM_DATA_MAX_LEN },
610};
611#endif /* WLAN_NL80211_TESTMODE */
612
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800613#ifdef FEATURE_WLAN_CH_AVOID
614/*
615 * FUNCTION: wlan_hdd_send_avoid_freq_event
616 * This is called when wlan driver needs to send vendor specific
617 * avoid frequency range event to userspace
618 */
619int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
620 tHddAvoidFreqList *pAvoidFreqList)
621{
622 struct sk_buff *vendor_event;
623
624 ENTER();
625
626 if (!pHddCtx)
627 {
628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
629 "%s: HDD context is null", __func__);
630 return -1;
631 }
632
633 if (!pAvoidFreqList)
634 {
635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
636 "%s: pAvoidFreqList is null", __func__);
637 return -1;
638 }
639
640 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530641#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
642 NULL,
643#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800644 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530645 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800646 GFP_KERNEL);
647 if (!vendor_event)
648 {
649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
650 "%s: cfg80211_vendor_event_alloc failed", __func__);
651 return -1;
652 }
653
654 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
655 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
656
657 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
658
659 EXIT();
660 return 0;
661}
662#endif /* FEATURE_WLAN_CH_AVOID */
663
Srinivas Dasari030bad32015-02-18 23:23:54 +0530664/*
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +0530665 * define short names for the global vendor params
666 * used by QCA_NL80211_VENDOR_SUBCMD_HANG
667 */
668#define HANG_REASON_INDEX QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX
669
670/**
671 * hdd_convert_hang_reason() - Convert cds recovery reason to vendor specific
672 * hang reason
673 * @reason: cds recovery reason
674 *
675 * Return: Vendor specific reason code
676 */
677static enum qca_wlan_vendor_hang_reason
678hdd_convert_hang_reason(enum vos_hang_reason reason)
679{
680 unsigned int ret_val;
681
682 switch (reason) {
683 case VOS_GET_MSG_BUFF_FAILURE:
684 ret_val = QCA_WLAN_HANG_GET_MSG_BUFF_FAILURE;
685 break;
686 case VOS_ACTIVE_LIST_TIMEOUT:
687 ret_val = QCA_WLAN_HANG_ACTIVE_LIST_TIMEOUT;
688 break;
689 case VOS_SCAN_REQ_EXPIRED:
690 ret_val = QCA_WLAN_HANG_SCAN_REQ_EXPIRED;
691 break;
692 case VOS_TRANSMISSIONS_TIMEOUT:
693 ret_val = QCA_WLAN_HANG_TRANSMISSIONS_TIMEOUT;
694 break;
695 case VOS_DXE_FAILURE:
696 ret_val = QCA_WLAN_HANG_DXE_FAILURE;
697 break;
698 case VOS_WDI_FAILURE:
699 ret_val = QCA_WLAN_HANG_WDI_FAILURE;
700 break;
701 case VOS_REASON_UNSPECIFIED:
702 default:
703 ret_val = QCA_WLAN_HANG_REASON_UNSPECIFIED;
704 }
705 return ret_val;
706}
707
708/**
709 * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace
710 * @hdd_ctx: Pointer to hdd context
711 * @reason: cds recovery reason
712 *
713 * Return: 0 on success or failure reason
714 */
715int wlan_hdd_send_hang_reason_event(hdd_context_t *hdd_ctx,
716 enum vos_hang_reason reason)
717{
718 struct sk_buff *vendor_event;
719 enum qca_wlan_vendor_hang_reason hang_reason;
720
721 ENTER();
722
723 if (!hdd_ctx) {
724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
725 "HDD context is null");
726 return -EINVAL;
727 }
728
729 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
730#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
731 NULL,
732#endif
733 sizeof(unsigned int),
734 HANG_REASON_INDEX,
735 GFP_KERNEL);
736 if (!vendor_event) {
737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
738 "cfg80211_vendor_event_alloc failed");
739 return -ENOMEM;
740 }
741
742 hang_reason = hdd_convert_hang_reason(reason);
743
744 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_HANG_REASON,
745 (unsigned int) hang_reason)) {
746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
747 "QCA_WLAN_VENDOR_ATTR_HANG_REASON put fail");
748 kfree_skb(vendor_event);
749 return -EINVAL;
750 }
751
752 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
753
754 EXIT();
755 return 0;
756}
757#undef HANG_REASON_INDEX
758
759/*
Srinivas Dasari030bad32015-02-18 23:23:54 +0530760 * FUNCTION: __wlan_hdd_cfg80211_nan_request
761 * This is called when wlan driver needs to send vendor specific
762 * nan request event.
763 */
764static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
765 struct wireless_dev *wdev,
766 const void *data, int data_len)
767{
768 tNanRequestReq nan_req;
769 VOS_STATUS status;
770 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530771 struct net_device *dev = wdev->netdev;
772 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
773 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530774 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
775
776 if (0 == data_len)
777 {
778 hddLog(VOS_TRACE_LEVEL_ERROR,
779 FL("NAN - Invalid Request, length = 0"));
780 return ret_val;
781 }
782
783 if (NULL == data)
784 {
785 hddLog(VOS_TRACE_LEVEL_ERROR,
786 FL("NAN - Invalid Request, data is NULL"));
787 return ret_val;
788 }
789
790 status = wlan_hdd_validate_context(pHddCtx);
791 if (0 != status)
792 {
793 hddLog(VOS_TRACE_LEVEL_ERROR,
794 FL("HDD context is not valid"));
795 return -EINVAL;
796 }
797
798 hddLog(LOG1, FL("Received NAN command"));
799 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
800 (tANI_U8 *)data, data_len);
801
802 /* check the NAN Capability */
803 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
804 {
805 hddLog(VOS_TRACE_LEVEL_ERROR,
806 FL("NAN is not supported by Firmware"));
807 return -EINVAL;
808 }
809
810 nan_req.request_data_len = data_len;
811 nan_req.request_data = data;
812
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530813 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530814 if (VOS_STATUS_SUCCESS == status)
815 {
816 ret_val = 0;
817 }
818 return ret_val;
819}
820
821/*
822 * FUNCTION: wlan_hdd_cfg80211_nan_request
823 * Wrapper to protect the nan vendor command from ssr
824 */
825static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
826 struct wireless_dev *wdev,
827 const void *data, int data_len)
828{
829 int ret;
830
831 vos_ssr_protect(__func__);
832 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
833 vos_ssr_unprotect(__func__);
834
835 return ret;
836}
837
838/*
839 * FUNCTION: wlan_hdd_cfg80211_nan_callback
840 * This is a callback function and it gets called
841 * when we need to report nan response event to
842 * upper layers.
843 */
844static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
845{
846 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
847 struct sk_buff *vendor_event;
848 int status;
849 tSirNanEvent *data;
850
851 ENTER();
852 if (NULL == msg)
853 {
854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
855 FL(" msg received here is null"));
856 return;
857 }
858 data = msg;
859
860 status = wlan_hdd_validate_context(pHddCtx);
861
862 if (0 != status)
863 {
864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
865 FL("HDD context is not valid"));
866 return;
867 }
868
869 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530870#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
871 NULL,
872#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530873 data->event_data_len +
874 NLMSG_HDRLEN,
875 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
876 GFP_KERNEL);
877
878 if (!vendor_event)
879 {
880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
881 FL("cfg80211_vendor_event_alloc failed"));
882 return;
883 }
884 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
885 data->event_data_len, data->event_data))
886 {
887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
888 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
889 kfree_skb(vendor_event);
890 return;
891 }
892 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
893 EXIT();
894}
895
896/*
897 * FUNCTION: wlan_hdd_cfg80211_nan_init
898 * This function is called to register the callback to sme layer
899 */
900inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
901{
902 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
903}
904
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530905/*
906 * define short names for the global vendor params
907 * used by __wlan_hdd_cfg80211_get_station_cmd()
908 */
909#define STATION_INVALID \
910 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
911#define STATION_INFO \
912 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
913#define STATION_ASSOC_FAIL_REASON \
914 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +0530915#define STATION_REMOTE \
916 QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530917#define STATION_MAX \
918 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
919
920static const struct nla_policy
921hdd_get_station_policy[STATION_MAX + 1] = {
922 [STATION_INFO] = {.type = NLA_FLAG},
923 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
924};
925
926/**
927 * hdd_get_station_assoc_fail() - Handle get station assoc fail
928 * @hdd_ctx: HDD context within host driver
929 * @wdev: wireless device
930 *
931 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
932 * Validate cmd attributes and send the station info to upper layers.
933 *
934 * Return: Success(0) or reason code for failure
935 */
936static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
937 hdd_adapter_t *adapter)
938{
939 struct sk_buff *skb = NULL;
940 uint32_t nl_buf_len;
941 hdd_station_ctx_t *hdd_sta_ctx;
942
943 nl_buf_len = NLMSG_HDRLEN;
944 nl_buf_len += sizeof(uint32_t);
945 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
946
947 if (!skb) {
948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
949 return -ENOMEM;
950 }
951
952 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
953
954 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
955 hdd_sta_ctx->conn_info.assoc_status_code)) {
956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
957 goto fail;
958 }
959 return cfg80211_vendor_cmd_reply(skb);
960fail:
961 if (skb)
962 kfree_skb(skb);
963 return -EINVAL;
964}
965
966/**
967 * hdd_map_auth_type() - transform auth type specific to
968 * vendor command
969 * @auth_type: csr auth type
970 *
971 * Return: Success(0) or reason code for failure
972 */
973static int hdd_convert_auth_type(uint32_t auth_type)
974{
975 uint32_t ret_val;
976
977 switch (auth_type) {
978 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
979 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
980 break;
981 case eCSR_AUTH_TYPE_SHARED_KEY:
982 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
983 break;
984 case eCSR_AUTH_TYPE_WPA:
985 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
986 break;
987 case eCSR_AUTH_TYPE_WPA_PSK:
988 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
989 break;
990 case eCSR_AUTH_TYPE_AUTOSWITCH:
991 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
992 break;
993 case eCSR_AUTH_TYPE_WPA_NONE:
994 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
995 break;
996 case eCSR_AUTH_TYPE_RSN:
997 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
998 break;
999 case eCSR_AUTH_TYPE_RSN_PSK:
1000 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
1001 break;
1002 case eCSR_AUTH_TYPE_FT_RSN:
1003 ret_val = QCA_WLAN_AUTH_TYPE_FT;
1004 break;
1005 case eCSR_AUTH_TYPE_FT_RSN_PSK:
1006 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
1007 break;
1008 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
1009 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
1010 break;
1011 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
1012 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
1013 break;
1014#ifdef FEATURE_WLAN_ESE
1015 case eCSR_AUTH_TYPE_CCKM_WPA:
1016 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
1017 break;
1018 case eCSR_AUTH_TYPE_CCKM_RSN:
1019 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
1020 break;
1021#endif
1022 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
1023 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
1024 break;
1025 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
1026 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
1027 break;
1028 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
1029 case eCSR_AUTH_TYPE_FAILED:
1030 case eCSR_AUTH_TYPE_NONE:
1031 default:
1032 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
1033 break;
1034 }
1035 return ret_val;
1036}
1037
1038/**
1039 * hdd_map_dot_11_mode() - transform dot11mode type specific to
1040 * vendor command
1041 * @dot11mode: dot11mode
1042 *
1043 * Return: Success(0) or reason code for failure
1044 */
1045static int hdd_convert_dot11mode(uint32_t dot11mode)
1046{
1047 uint32_t ret_val;
1048
1049 switch (dot11mode) {
1050 case eCSR_CFG_DOT11_MODE_11A:
1051 ret_val = QCA_WLAN_802_11_MODE_11A;
1052 break;
1053 case eCSR_CFG_DOT11_MODE_11B:
1054 ret_val = QCA_WLAN_802_11_MODE_11B;
1055 break;
1056 case eCSR_CFG_DOT11_MODE_11G:
1057 ret_val = QCA_WLAN_802_11_MODE_11G;
1058 break;
1059 case eCSR_CFG_DOT11_MODE_11N:
1060 ret_val = QCA_WLAN_802_11_MODE_11N;
1061 break;
1062 case eCSR_CFG_DOT11_MODE_11AC:
1063 ret_val = QCA_WLAN_802_11_MODE_11AC;
1064 break;
1065 case eCSR_CFG_DOT11_MODE_AUTO:
1066 case eCSR_CFG_DOT11_MODE_ABG:
1067 default:
1068 ret_val = QCA_WLAN_802_11_MODE_INVALID;
1069 }
1070 return ret_val;
1071}
1072
1073/**
1074 * hdd_add_tx_bitrate() - add tx bitrate attribute
1075 * @skb: pointer to sk buff
1076 * @hdd_sta_ctx: pointer to hdd station context
1077 * @idx: attribute index
1078 *
1079 * Return: Success(0) or reason code for failure
1080 */
1081static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
1082 hdd_station_ctx_t *hdd_sta_ctx,
1083 int idx)
1084{
1085 struct nlattr *nla_attr;
1086 uint32_t bitrate, bitrate_compat;
1087
1088 nla_attr = nla_nest_start(skb, idx);
1089 if (!nla_attr)
1090 goto fail;
1091 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301092 bitrate = cfg80211_calculate_bitrate(
1093 &hdd_sta_ctx->cache_conn_info.txrate);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301094
1095 /* report 16-bit bitrate only if we can */
1096 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
1097 if (bitrate > 0 &&
1098 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
1099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1100 goto fail;
1101 }
1102 if (bitrate_compat > 0 &&
1103 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
1104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1105 goto fail;
1106 }
1107 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301108 hdd_sta_ctx->cache_conn_info.txrate.nss)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1110 goto fail;
1111 }
1112 nla_nest_end(skb, nla_attr);
1113 return 0;
1114fail:
1115 return -EINVAL;
1116}
1117
1118/**
1119 * hdd_add_sta_info() - add station info attribute
1120 * @skb: pointer to sk buff
1121 * @hdd_sta_ctx: pointer to hdd station context
1122 * @idx: attribute index
1123 *
1124 * Return: Success(0) or reason code for failure
1125 */
1126static int32_t hdd_add_sta_info(struct sk_buff *skb,
1127 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1128{
1129 struct nlattr *nla_attr;
1130
1131 nla_attr = nla_nest_start(skb, idx);
1132 if (!nla_attr)
1133 goto fail;
1134 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301135 (hdd_sta_ctx->cache_conn_info.signal + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301136 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1137 goto fail;
1138 }
1139 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1140 goto fail;
1141 nla_nest_end(skb, nla_attr);
1142 return 0;
1143fail:
1144 return -EINVAL;
1145}
1146
1147/**
1148 * hdd_add_survey_info() - add survey info attribute
1149 * @skb: pointer to sk buff
1150 * @hdd_sta_ctx: pointer to hdd station context
1151 * @idx: attribute index
1152 *
1153 * Return: Success(0) or reason code for failure
1154 */
1155static int32_t hdd_add_survey_info(struct sk_buff *skb,
1156 hdd_station_ctx_t *hdd_sta_ctx,
1157 int idx)
1158{
1159 struct nlattr *nla_attr;
1160
1161 nla_attr = nla_nest_start(skb, idx);
1162 if (!nla_attr)
1163 goto fail;
1164 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301165 hdd_sta_ctx->cache_conn_info.freq) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301166 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301167 (hdd_sta_ctx->cache_conn_info.noise + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1169 goto fail;
1170 }
1171 nla_nest_end(skb, nla_attr);
1172 return 0;
1173fail:
1174 return -EINVAL;
1175}
1176
1177/**
1178 * hdd_add_link_standard_info() - add link info attribute
1179 * @skb: pointer to sk buff
1180 * @hdd_sta_ctx: pointer to hdd station context
1181 * @idx: attribute index
1182 *
1183 * Return: Success(0) or reason code for failure
1184 */
1185static int32_t
1186hdd_add_link_standard_info(struct sk_buff *skb,
1187 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1188{
1189 struct nlattr *nla_attr;
1190
1191 nla_attr = nla_nest_start(skb, idx);
1192 if (!nla_attr)
1193 goto fail;
1194 if (nla_put(skb,
1195 NL80211_ATTR_SSID,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301196 hdd_sta_ctx->cache_conn_info.SSID.SSID.length,
1197 hdd_sta_ctx->cache_conn_info.SSID.SSID.ssId)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1199 goto fail;
1200 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301201 if (nla_put(skb, NL80211_ATTR_MAC, VOS_MAC_ADDR_SIZE,
1202 hdd_sta_ctx->cache_conn_info.bssId))
1203 goto fail;
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301204 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1205 goto fail;
1206 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1207 goto fail;
1208 nla_nest_end(skb, nla_attr);
1209 return 0;
1210fail:
1211 return -EINVAL;
1212}
1213
1214/**
1215 * hdd_add_ap_standard_info() - add ap info attribute
1216 * @skb: pointer to sk buff
1217 * @hdd_sta_ctx: pointer to hdd station context
1218 * @idx: attribute index
1219 *
1220 * Return: Success(0) or reason code for failure
1221 */
1222static int32_t
1223hdd_add_ap_standard_info(struct sk_buff *skb,
1224 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1225{
1226 struct nlattr *nla_attr;
1227
1228 nla_attr = nla_nest_start(skb, idx);
1229 if (!nla_attr)
1230 goto fail;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301231 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301232 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301233 sizeof(hdd_sta_ctx->cache_conn_info.vht_caps),
1234 &hdd_sta_ctx->cache_conn_info.vht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1236 goto fail;
1237 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301238 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301239 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301240 sizeof(hdd_sta_ctx->cache_conn_info.ht_caps),
1241 &hdd_sta_ctx->cache_conn_info.ht_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 }
1245 nla_nest_end(skb, nla_attr);
1246 return 0;
1247fail:
1248 return -EINVAL;
1249}
1250
1251/**
1252 * hdd_get_station_info() - send BSS information to supplicant
1253 * @hdd_ctx: pointer to hdd context
1254 * @adapter: pointer to adapter
1255 *
1256 * Return: 0 if success else error status
1257 */
1258static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1259 hdd_adapter_t *adapter)
1260{
1261 struct sk_buff *skb = NULL;
1262 uint8_t *tmp_hs20 = NULL;
1263 uint32_t nl_buf_len;
1264 hdd_station_ctx_t *hdd_sta_ctx;
1265
1266 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1267
1268 nl_buf_len = NLMSG_HDRLEN;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301269
1270 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.SSID.SSID.length) +
1271 VOS_MAC_ADDR_SIZE +
1272 sizeof(hdd_sta_ctx->cache_conn_info.freq) +
1273 sizeof(hdd_sta_ctx->cache_conn_info.noise) +
1274 sizeof(hdd_sta_ctx->cache_conn_info.signal) +
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301275 (sizeof(uint32_t) * 2) +
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301276 sizeof(hdd_sta_ctx->cache_conn_info.txrate.nss) +
1277 sizeof(hdd_sta_ctx->cache_conn_info.roam_count) +
1278 sizeof(hdd_sta_ctx->cache_conn_info.authType) +
1279 sizeof(hdd_sta_ctx->cache_conn_info.dot11Mode);
1280 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
1281 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.vht_caps);
1282 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
1283 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_caps);
1284 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) {
1285 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->
1286 cache_conn_info.hs20vendor_ie);
1287 nl_buf_len +=
1288 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie) -
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301289 1);
1290 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301291 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
1292 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_operation);
1293 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
1294 nl_buf_len +=
1295 sizeof(hdd_sta_ctx->cache_conn_info.vht_operation);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301296
1297
1298 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1299 if (!skb) {
1300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1301 __func__, __LINE__);
1302 return -ENOMEM;
1303 }
1304
1305 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1306 LINK_INFO_STANDARD_NL80211_ATTR)) {
1307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1308 goto fail;
1309 }
1310 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1311 AP_INFO_STANDARD_NL80211_ATTR)) {
1312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1313 goto fail;
1314 }
1315 if (nla_put_u32(skb, INFO_ROAM_COUNT,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301316 hdd_sta_ctx->cache_conn_info.roam_count) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301317 nla_put_u32(skb, INFO_AKM,
1318 hdd_convert_auth_type(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301319 hdd_sta_ctx->cache_conn_info.authType)) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301320 nla_put_u32(skb, WLAN802_11_MODE,
1321 hdd_convert_dot11mode(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301322 hdd_sta_ctx->cache_conn_info.dot11Mode))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1324 goto fail;
1325 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301326 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301327 if (nla_put(skb, HT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301328 (sizeof(hdd_sta_ctx->cache_conn_info.ht_operation)),
1329 &hdd_sta_ctx->cache_conn_info.ht_operation)) {
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.vht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301334 if (nla_put(skb, VHT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301335 (sizeof(hdd_sta_ctx->
1336 cache_conn_info.vht_operation)),
1337 &hdd_sta_ctx->cache_conn_info.vht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1339 goto fail;
1340 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301341 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301342 if (nla_put(skb, AP_INFO_HS20_INDICATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301343 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie)
1344 - 1), tmp_hs20 + 1)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301345 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1346 goto fail;
1347 }
1348
1349 return cfg80211_vendor_cmd_reply(skb);
1350fail:
1351 if (skb)
1352 kfree_skb(skb);
1353 return -EINVAL;
1354}
1355
1356/**
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301357 * hdd_add_survey_info_sap_get_len - get data length used in
1358 * hdd_add_survey_info_sap()
1359 *
1360 * This function calculates the data length used in hdd_add_survey_info_sap()
1361 *
1362 * Return: total data length used in hdd_add_survey_info_sap()
1363 */
1364static uint32_t hdd_add_survey_info_sap_get_len(void)
1365{
1366 return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
1367}
1368
1369/**
1370 * hdd_add_survey_info - add survey info attribute
1371 * @skb: pointer to response skb buffer
1372 * @stainfo: station information
1373 * @idx: attribute type index for nla_next_start()
1374 *
1375 * This function adds survey info attribute to response skb buffer
1376 *
1377 * Return : 0 on success and errno on failure
1378 */
1379static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
1380 struct hdd_cache_sta_info *stainfo,
1381 int idx)
1382{
1383 struct nlattr *nla_attr;
1384
1385 nla_attr = nla_nest_start(skb, idx);
1386 if (!nla_attr)
1387 goto fail;
1388 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1389 stainfo->freq)) {
1390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1391 FL("put fail"));
1392 goto fail;
1393 }
1394 nla_nest_end(skb, nla_attr);
1395 return 0;
1396fail:
1397 return -EINVAL;
1398}
1399
1400/**
1401 * hdd_add_tx_bitrate_sap_get_len - get data length used in
1402 * hdd_add_tx_bitrate_sap()
1403 *
1404 * This function calculates the data length used in hdd_add_tx_bitrate_sap()
1405 *
1406 * Return: total data length used in hdd_add_tx_bitrate_sap()
1407 */
1408static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
1409{
1410 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
1411}
1412
1413/**
1414 * hdd_add_tx_bitrate_sap - add vht nss info attribute
1415 * @skb: pointer to response skb buffer
1416 * @stainfo: station information
1417 * @idx: attribute type index for nla_next_start()
1418 *
1419 * This function adds vht nss attribute to response skb buffer
1420 *
1421 * Return : 0 on success and errno on failure
1422 */
1423static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
1424 struct hdd_cache_sta_info *stainfo,
1425 int idx)
1426{
1427 struct nlattr *nla_attr;
1428
1429 nla_attr = nla_nest_start(skb, idx);
1430 if (!nla_attr)
1431 goto fail;
1432
1433 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1434 stainfo->nss)) {
1435 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1436 FL("put fail"));
1437 goto fail;
1438 }
1439 nla_nest_end(skb, nla_attr);
1440 return 0;
1441fail:
1442 return -EINVAL;
1443}
1444
1445/**
1446 * hdd_add_sta_info_sap_get_len - get data length used in
1447 * hdd_add_sta_info_sap()
1448 *
1449 * This function calculates the data length used in hdd_add_sta_info_sap()
1450 *
1451 * Return: total data length used in hdd_add_sta_info_sap()
1452 */
1453static uint32_t hdd_add_sta_info_sap_get_len(void)
1454{
1455 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
1456 hdd_add_tx_bitrate_sap_get_len());
1457}
1458
1459/**
1460 * hdd_add_sta_info_sap - add sta signal info attribute
1461 * @skb: pointer to response skb buffer
1462 * @rssi: peer rssi value
1463 * @stainfo: station information
1464 * @idx: attribute type index for nla_next_start()
1465 *
1466 * This function adds sta signal attribute to response skb buffer
1467 *
1468 * Return : 0 on success and errno on failure
1469 */
1470static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
1471 struct hdd_cache_sta_info *stainfo, int idx)
1472{
1473 struct nlattr *nla_attr;
1474
1475 nla_attr = nla_nest_start(skb, idx);
1476 if (!nla_attr)
1477 goto fail;
1478
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05301479 /* upperlayer expects positive rssi value */
1480 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, (rssi + 96))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301481 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1482 FL("put fail"));
1483 goto fail;
1484 }
1485 if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE)) {
1486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1487 FL("put fail"));
1488 goto fail;
1489 }
1490
1491 nla_nest_end(skb, nla_attr);
1492 return 0;
1493fail:
1494 return -EINVAL;
1495}
1496
1497/**
1498 * hdd_add_link_standard_info_sap_get_len - get data length used in
1499 * hdd_add_link_standard_info_sap()
1500 *
1501 * This function calculates the data length used in
1502 * hdd_add_link_standard_info_sap()
1503 *
1504 * Return: total data length used in hdd_add_link_standard_info_sap()
1505 */
1506static uint32_t hdd_add_link_standard_info_sap_get_len(void)
1507{
1508 return ((NLA_HDRLEN) +
1509 hdd_add_survey_info_sap_get_len() +
1510 hdd_add_sta_info_sap_get_len() +
1511 (sizeof(uint32_t) + NLA_HDRLEN));
1512}
1513
1514/**
1515 * hdd_add_link_standard_info_sap - add add link info attribut
1516 * @skb: pointer to response skb buffer
1517 * @stainfo: station information
1518 * @idx: attribute type index for nla_next_start()
1519 *
1520 * This function adds link info attribut to response skb buffer
1521 *
1522 * Return : 0 on success and errno on failure
1523 */
1524static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
1525 struct hdd_cache_sta_info *stainfo,
1526 int idx)
1527{
1528 struct nlattr *nla_attr;
1529
1530 nla_attr = nla_nest_start(skb, idx);
1531 if (!nla_attr)
1532 goto fail;
1533 if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
1534 goto fail;
1535 if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
1536 goto fail;
1537
1538 if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
1539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1540 FL("put fail"));
1541 goto fail;
1542 }
1543
1544 nla_nest_end(skb, nla_attr);
1545 return 0;
1546fail:
1547 return -EINVAL;
1548}
1549
1550/**
1551 * hdd_add_ap_standard_info_sap_get_len - get data length used in
1552 * hdd_add_ap_standard_info_sap()
1553 * @stainfo: station information
1554 *
1555 * This function calculates the data length used in
1556 * hdd_add_ap_standard_info_sap()
1557 *
1558 * Return: total data length used in hdd_add_ap_standard_info_sap()
1559 */
1560static uint32_t hdd_add_ap_standard_info_sap_get_len(
1561 struct hdd_cache_sta_info *stainfo)
1562{
1563 uint32_t len;
1564
1565 len = NLA_HDRLEN;
1566 if (stainfo->vht_present)
1567 len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
1568 if (stainfo->ht_present)
1569 len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
1570
1571 return len;
1572}
1573
1574/**
1575 * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
1576 * @skb: pointer to response skb buffer
1577 * @stainfo: station information
1578 * @idx: attribute type index for nla_next_start()
1579 *
1580 * This function adds HT and VHT info attributes to response skb buffer
1581 *
1582 * Return : 0 on success and errno on failure
1583 */
1584static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
1585 struct hdd_cache_sta_info *stainfo,
1586 int idx)
1587{
1588 struct nlattr *nla_attr;
1589
1590 nla_attr = nla_nest_start(skb, idx);
1591 if (!nla_attr)
1592 goto fail;
1593
1594 if (stainfo->vht_present) {
1595 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1596 sizeof(stainfo->vht_caps),
1597 &stainfo->vht_caps)) {
1598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1599 FL("put fail"));
1600 goto fail;
1601 }
1602 }
1603 if (stainfo->ht_present) {
1604 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1605 sizeof(stainfo->ht_caps),
1606 &stainfo->ht_caps)) {
1607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1608 FL("put fail"));
1609 goto fail;
1610 }
1611 }
1612 nla_nest_end(skb, nla_attr);
1613 return 0;
1614fail:
1615 return -EINVAL;
1616}
1617
1618/**
1619 * hdd_decode_ch_width - decode channel band width based
1620 * @ch_width: encoded enum value holding channel band width
1621 *
1622 * This function decodes channel band width from the given encoded enum value.
1623 *
1624 * Returns: decoded channel band width.
1625 */
1626static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
1627{
1628 switch (ch_width) {
1629 case 0:
1630 return 20;
1631 case 1:
1632 return 40;
1633 case 2:
1634 return 80;
1635 default:
1636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1637 "invalid enum: %d", ch_width);
1638 return 20;
1639 }
1640}
1641
1642/**
1643 * hdd_get_cached_station_remote() - get cached(deleted) peer's info
1644 * @hdd_ctx: hdd context
1645 * @adapter: hostapd interface
1646 * @mac_addr: mac address of requested peer
1647 *
1648 * This function collect and indicate the cached(deleted) peer's info
1649 *
1650 * Return: 0 on success, otherwise error value
1651 */
1652static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx,
1653 hdd_adapter_t *adapter,
1654 v_MACADDR_t mac_addr)
1655{
1656 struct hdd_cache_sta_info *stainfo;
1657 struct sk_buff *skb = NULL;
1658 uint32_t nl_buf_len;
1659 uint8_t cw;
1660 ptSapContext sap_ctx;
1661 v_CONTEXT_t vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
1662
1663 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
1664 if(sap_ctx == NULL){
1665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1666 FL("psapCtx is NULL"));
1667 return -ENOENT;
1668 }
1669
1670 stainfo = hdd_get_cache_stainfo(sap_ctx->cache_sta_info,
1671 mac_addr.bytes);
1672 if (!stainfo) {
1673 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1674 "peer " MAC_ADDRESS_STR " not found",
1675 MAC_ADDR_ARRAY(mac_addr.bytes));
1676 return -EINVAL;
1677 }
1678 if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE) {
1679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1680 "peer " MAC_ADDRESS_STR " is in connected state",
1681 MAC_ADDR_ARRAY(mac_addr.bytes));
1682 return -EINVAL;
1683 }
1684
1685
1686 nl_buf_len = NLMSG_HDRLEN + hdd_add_link_standard_info_sap_get_len() +
1687 hdd_add_ap_standard_info_sap_get_len(stainfo) +
1688 (sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
1689 (sizeof(cw) + NLA_HDRLEN) +
1690 (sizeof(stainfo->rx_rate) + NLA_HDRLEN);
1691
1692 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1693 if (!skb) {
1694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "cfg80211_vendor_cmd_alloc_reply_skb failed");
1695 return -ENOMEM;
1696 }
1697
1698 if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
1699 LINK_INFO_STANDARD_NL80211_ATTR)) {
1700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "link standard put fail");
1701 goto fail;
1702 }
1703
1704 if (hdd_add_ap_standard_info_sap(skb, stainfo,
1705 AP_INFO_STANDARD_NL80211_ATTR)) {
1706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ap standard put fail");
1707 goto fail;
1708 }
1709
1710 /* upper layer expects decoded channel BW */
1711 cw = hdd_decode_ch_width(stainfo->ch_width);
1712 if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE, stainfo->dot11_mode) ||
1713 nla_put_u8(skb, REMOTE_CH_WIDTH, cw)) {
1714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "remote ch put fail");
1715 goto fail;
1716 }
Hanumanth Reddy Pothula504fe152018-01-02 20:41:03 +05301717 if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, (stainfo->rx_rate * 100))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "rx rate put fail");
1719 goto fail;
1720 }
1721
1722 vos_mem_zero(stainfo, sizeof(*stainfo));
1723
1724 return cfg80211_vendor_cmd_reply(skb);
1725fail:
1726 if (skb)
1727 kfree_skb(skb);
1728
1729 return -EINVAL;
1730}
1731
1732/**
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301733 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1734 * @wiphy: corestack handler
1735 * @wdev: wireless device
1736 * @data: data
1737 * @data_len: data length
1738 *
1739 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1740 * Validate cmd attributes and send the station info to upper layers.
1741 *
1742 * Return: Success(0) or reason code for failure
1743 */
1744static int32_t
1745__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1746 struct wireless_dev *wdev,
1747 const void *data,
1748 int data_len)
1749{
1750 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1751 struct net_device *dev = wdev->netdev;
1752 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1753 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1754 int32_t status;
1755
1756 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1757 if (VOS_FTM_MODE == hdd_get_conparam()) {
1758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1759 status = -EPERM;
1760 goto out;
1761 }
1762
1763 status = wlan_hdd_validate_context(hdd_ctx);
1764 if (0 != status)
1765 goto out;
1766
1767
1768 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1769 data, data_len, NULL);
1770 if (status) {
1771 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1772 goto out;
1773 }
1774
1775 /* Parse and fetch Command Type*/
1776 if (tb[STATION_INFO]) {
1777 status = hdd_get_station_info(hdd_ctx, adapter);
1778 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1779 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301780 } else if (tb[STATION_REMOTE]) {
1781 v_MACADDR_t mac_addr;
1782
1783 if (adapter->device_mode != WLAN_HDD_SOFTAP &&
1784 adapter->device_mode != WLAN_HDD_P2P_GO) {
1785 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"invalid device_mode:%d",
1786 adapter->device_mode);
1787 status = -EINVAL;
1788 goto out;
1789 }
1790
1791 nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
1792 VOS_MAC_ADDRESS_LEN);
1793
1794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "STATION_REMOTE "MAC_ADDRESS_STR"",
1795 MAC_ADDR_ARRAY(mac_addr.bytes));
1796
1797 status = hdd_get_cached_station_remote(hdd_ctx, adapter,
1798 mac_addr);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301799 } else {
1800 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1801 status = -EINVAL;
1802 goto out;
1803 }
1804 EXIT();
1805out:
1806 return status;
1807}
1808
1809/**
1810 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1811 * @wiphy: corestack handler
1812 * @wdev: wireless device
1813 * @data: data
1814 * @data_len: data length
1815 *
1816 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1817 * Validate cmd attributes and send the station info to upper layers.
1818 *
1819 * Return: Success(0) or reason code for failure
1820 */
1821static int32_t
1822hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1823 struct wireless_dev *wdev,
1824 const void *data,
1825 int data_len)
1826{
1827 int ret;
1828
1829 vos_ssr_protect(__func__);
1830 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1831 vos_ssr_unprotect(__func__);
1832
1833 return ret;
1834}
1835
1836/*
1837 * undef short names defined for get station command
1838 * used by __wlan_hdd_cfg80211_get_station_cmd()
1839 */
1840#undef STATION_INVALID
1841#undef STATION_INFO
1842#undef STATION_ASSOC_FAIL_REASON
1843#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301844
Sunil Duttc69bccb2014-05-26 21:30:20 +05301845#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1846
1847static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1848 struct sk_buff *vendor_event)
1849{
1850 if (nla_put_u8(vendor_event,
1851 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1852 stats->rate.preamble) ||
1853 nla_put_u8(vendor_event,
1854 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1855 stats->rate.nss) ||
1856 nla_put_u8(vendor_event,
1857 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1858 stats->rate.bw) ||
1859 nla_put_u8(vendor_event,
1860 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1861 stats->rate.rateMcsIdx) ||
1862 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1863 stats->rate.bitrate ) ||
1864 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1865 stats->txMpdu ) ||
1866 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1867 stats->rxMpdu ) ||
1868 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1869 stats->mpduLost ) ||
1870 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1871 stats->retries) ||
1872 nla_put_u32(vendor_event,
1873 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1874 stats->retriesShort ) ||
1875 nla_put_u32(vendor_event,
1876 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1877 stats->retriesLong))
1878 {
1879 hddLog(VOS_TRACE_LEVEL_ERROR,
1880 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1881 return FALSE;
1882 }
1883 return TRUE;
1884}
1885
1886static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1887 struct sk_buff *vendor_event)
1888{
1889 u32 i = 0;
1890 struct nlattr *rateInfo;
1891 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1892 stats->type) ||
1893 nla_put(vendor_event,
1894 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1895 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1896 nla_put_u32(vendor_event,
1897 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1898 stats->capabilities) ||
1899 nla_put_u32(vendor_event,
1900 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1901 stats->numRate))
1902 {
1903 hddLog(VOS_TRACE_LEVEL_ERROR,
1904 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1905 goto error;
1906 }
1907
1908 rateInfo = nla_nest_start(vendor_event,
1909 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301910 if(!rateInfo)
1911 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301912 for (i = 0; i < stats->numRate; i++)
1913 {
1914 struct nlattr *rates;
1915 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1916 stats->rateStats +
1917 (i * sizeof(tSirWifiRateStat)));
1918 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301919 if(!rates)
1920 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301921
1922 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1923 {
1924 hddLog(VOS_TRACE_LEVEL_ERROR,
1925 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1926 return FALSE;
1927 }
1928 nla_nest_end(vendor_event, rates);
1929 }
1930 nla_nest_end(vendor_event, rateInfo);
1931
1932 return TRUE;
1933error:
1934 return FALSE;
1935}
1936
1937static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1938 struct sk_buff *vendor_event)
1939{
1940 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1941 stats->ac ) ||
1942 nla_put_u32(vendor_event,
1943 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1944 stats->txMpdu ) ||
1945 nla_put_u32(vendor_event,
1946 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1947 stats->rxMpdu ) ||
1948 nla_put_u32(vendor_event,
1949 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1950 stats->txMcast ) ||
1951 nla_put_u32(vendor_event,
1952 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1953 stats->rxMcast ) ||
1954 nla_put_u32(vendor_event,
1955 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1956 stats->rxAmpdu ) ||
1957 nla_put_u32(vendor_event,
1958 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1959 stats->txAmpdu ) ||
1960 nla_put_u32(vendor_event,
1961 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1962 stats->mpduLost )||
1963 nla_put_u32(vendor_event,
1964 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1965 stats->retries ) ||
1966 nla_put_u32(vendor_event,
1967 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1968 stats->retriesShort ) ||
1969 nla_put_u32(vendor_event,
1970 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1971 stats->retriesLong ) ||
1972 nla_put_u32(vendor_event,
1973 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1974 stats->contentionTimeMin ) ||
1975 nla_put_u32(vendor_event,
1976 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1977 stats->contentionTimeMax ) ||
1978 nla_put_u32(vendor_event,
1979 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1980 stats->contentionTimeAvg ) ||
1981 nla_put_u32(vendor_event,
1982 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1983 stats->contentionNumSamples ))
1984 {
1985 hddLog(VOS_TRACE_LEVEL_ERROR,
1986 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1987 return FALSE;
1988 }
1989 return TRUE;
1990}
1991
1992static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1993 struct sk_buff *vendor_event)
1994{
Dino Myclec8f3f332014-07-21 16:48:27 +05301995 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301996 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1997 nla_put(vendor_event,
1998 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
1999 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
2000 nla_put_u32(vendor_event,
2001 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
2002 stats->state ) ||
2003 nla_put_u32(vendor_event,
2004 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
2005 stats->roaming ) ||
2006 nla_put_u32(vendor_event,
2007 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
2008 stats->capabilities ) ||
2009 nla_put(vendor_event,
2010 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
2011 strlen(stats->ssid), stats->ssid) ||
2012 nla_put(vendor_event,
2013 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
2014 WNI_CFG_BSSID_LEN, stats->bssid) ||
2015 nla_put(vendor_event,
2016 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
2017 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
2018 nla_put(vendor_event,
2019 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
2020 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
2021 )
2022 {
2023 hddLog(VOS_TRACE_LEVEL_ERROR,
2024 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2025 return FALSE;
2026 }
2027 return TRUE;
2028}
2029
Dino Mycle3b9536d2014-07-09 22:05:24 +05302030static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
2031 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302032 struct sk_buff *vendor_event)
2033{
2034 int i = 0;
2035 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302036 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2037 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302038 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302039
Sunil Duttc69bccb2014-05-26 21:30:20 +05302040 if (FALSE == put_wifi_interface_info(
2041 &pWifiIfaceStat->info,
2042 vendor_event))
2043 {
2044 hddLog(VOS_TRACE_LEVEL_ERROR,
2045 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2046 return FALSE;
2047
2048 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05302049 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
2050 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
2051 if (NULL == pWifiIfaceStatTL)
2052 {
2053 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2054 return FALSE;
2055 }
2056
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302057 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
2058 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
2059 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
2060 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
2061
2062 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
2063 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
2064 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
2065 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302066
2067 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
2068 {
2069 if (VOS_STATUS_SUCCESS ==
2070 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2071 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
2072 {
2073 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
2074 * obtained from TL structure
2075 */
2076
2077 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
2078 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302079 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
2080
Srinivas Dasari98947432014-11-07 19:41:24 +05302081 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
2082 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
2083 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
2084 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
2085 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
2086 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
2087 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
2088 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302089
Srinivas Dasari98947432014-11-07 19:41:24 +05302090 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
2091 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
2092 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
2093 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
2094 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
2095 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
2096 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
2097 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302098
Srinivas Dasari98947432014-11-07 19:41:24 +05302099 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
2100 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
2101 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
2102 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
2103 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
2104 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
2105 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
2106 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302107 }
2108 else
2109 {
2110 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
2111 }
2112
Dino Mycle3b9536d2014-07-09 22:05:24 +05302113 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
2114 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
2115 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
2116 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
2117 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
2118 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
2119 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
2120 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
2121 }
2122 else
2123 {
2124 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
2125 }
2126
2127
Sunil Duttc69bccb2014-05-26 21:30:20 +05302128
2129 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302130 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2131 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
2132 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302133 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
2134 pWifiIfaceStat->beaconRx) ||
2135 nla_put_u32(vendor_event,
2136 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
2137 pWifiIfaceStat->mgmtRx) ||
2138 nla_put_u32(vendor_event,
2139 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
2140 pWifiIfaceStat->mgmtActionRx) ||
2141 nla_put_u32(vendor_event,
2142 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
2143 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302144 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302145 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
2146 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302147 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302148 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
2149 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302150 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302151 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
2152 pWifiIfaceStat->rssiAck))
2153 {
2154 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302155 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2156 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302157 return FALSE;
2158 }
2159
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302160#ifdef FEATURE_EXT_LL_STAT
2161 /*
2162 * Ensure when EXT_LL_STAT is supported by both host and fwr,
2163 * then host should send Leaky AP stats to upper layer,
2164 * otherwise no need to send these stats.
2165 */
2166 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
2167 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
2168 )
2169 {
2170 hddLog(VOS_TRACE_LEVEL_INFO,
2171 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
2172 pWifiIfaceStat->leakyApStat.is_leaky_ap,
2173 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
2174 pWifiIfaceStat->leakyApStat.rx_leak_window,
2175 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
2176 if (nla_put_u32(vendor_event,
2177 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
2178 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
2179 nla_put_u32(vendor_event,
2180 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
2181 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
2182 nla_put_u32(vendor_event,
2183 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
2184 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05302185 hdd_wlan_nla_put_u64(vendor_event,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302186 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
2187 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
2188 {
2189 hddLog(VOS_TRACE_LEVEL_ERROR,
2190 FL("EXT_LL_STAT put fail"));
2191 vos_mem_free(pWifiIfaceStatTL);
2192 return FALSE;
2193 }
2194 }
2195#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05302196 wmmInfo = nla_nest_start(vendor_event,
2197 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302198 if(!wmmInfo)
2199 {
2200 vos_mem_free(pWifiIfaceStatTL);
2201 return FALSE;
2202 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302203 for (i = 0; i < WIFI_AC_MAX; i++)
2204 {
2205 struct nlattr *wmmStats;
2206 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302207 if(!wmmStats)
2208 {
2209 vos_mem_free(pWifiIfaceStatTL);
2210 return FALSE;
2211 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302212 if (FALSE == put_wifi_wmm_ac_stat(
2213 &pWifiIfaceStat->AccessclassStats[i],
2214 vendor_event))
2215 {
2216 hddLog(VOS_TRACE_LEVEL_ERROR,
2217 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05302218 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302219 return FALSE;
2220 }
2221
2222 nla_nest_end(vendor_event, wmmStats);
2223 }
2224 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05302225 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302226 return TRUE;
2227}
2228
2229static tSirWifiInterfaceMode
2230 hdd_map_device_to_ll_iface_mode ( int deviceMode )
2231{
2232 switch (deviceMode)
2233 {
2234 case WLAN_HDD_INFRA_STATION:
2235 return WIFI_INTERFACE_STA;
2236 case WLAN_HDD_SOFTAP:
2237 return WIFI_INTERFACE_SOFTAP;
2238 case WLAN_HDD_P2P_CLIENT:
2239 return WIFI_INTERFACE_P2P_CLIENT;
2240 case WLAN_HDD_P2P_GO:
2241 return WIFI_INTERFACE_P2P_GO;
2242 case WLAN_HDD_IBSS:
2243 return WIFI_INTERFACE_IBSS;
2244 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05302245 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302246 }
2247}
2248
2249static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
2250 tpSirWifiInterfaceInfo pInfo)
2251{
2252 v_U8_t *staMac = NULL;
2253 hdd_station_ctx_t *pHddStaCtx;
2254 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2255 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
2256
2257 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
2258
2259 vos_mem_copy(pInfo->macAddr,
2260 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
2261
2262 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2263 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
2264 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
2265 {
2266 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2267 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
2268 {
2269 pInfo->state = WIFI_DISCONNECTED;
2270 }
2271 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
2272 {
2273 hddLog(VOS_TRACE_LEVEL_ERROR,
2274 "%s: Session ID %d, Connection is in progress", __func__,
2275 pAdapter->sessionId);
2276 pInfo->state = WIFI_ASSOCIATING;
2277 }
2278 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
2279 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
2280 {
2281 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
2282 hddLog(VOS_TRACE_LEVEL_ERROR,
2283 "%s: client " MAC_ADDRESS_STR
2284 " is in the middle of WPS/EAPOL exchange.", __func__,
2285 MAC_ADDR_ARRAY(staMac));
2286 pInfo->state = WIFI_AUTHENTICATING;
2287 }
2288 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
2289 {
2290 pInfo->state = WIFI_ASSOCIATED;
2291 vos_mem_copy(pInfo->bssid,
2292 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
2293 vos_mem_copy(pInfo->ssid,
2294 pHddStaCtx->conn_info.SSID.SSID.ssId,
2295 pHddStaCtx->conn_info.SSID.SSID.length);
2296 //NULL Terminate the string.
2297 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
2298 }
2299 }
2300 vos_mem_copy(pInfo->countryStr,
2301 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2302
2303 vos_mem_copy(pInfo->apCountryStr,
2304 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2305
2306 return TRUE;
2307}
2308
2309/*
2310 * hdd_link_layer_process_peer_stats () - This function is called after
2311 * receiving Link Layer Peer statistics from FW.This function converts
2312 * the firmware data to the NL data and sends the same to the kernel/upper
2313 * layers.
2314 */
2315static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
2316 v_VOID_t *pData)
2317{
2318 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302319 tpSirWifiPeerStat pWifiPeerStat;
2320 tpSirWifiPeerInfo pWifiPeerInfo;
2321 struct nlattr *peerInfo;
2322 struct sk_buff *vendor_event;
2323 int status, i;
2324
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302325 ENTER();
2326
Sunil Duttc69bccb2014-05-26 21:30:20 +05302327 status = wlan_hdd_validate_context(pHddCtx);
2328 if (0 != status)
2329 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302330 return;
2331 }
2332
2333 pWifiPeerStat = (tpSirWifiPeerStat) pData;
2334
2335 hddLog(VOS_TRACE_LEVEL_INFO,
2336 "LL_STATS_PEER_ALL : numPeers %u",
2337 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302338 /*
2339 * Allocate a size of 4096 for the peer stats comprising
2340 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
2341 * sizeof (tSirWifiRateStat).Each field is put with an
2342 * NL attribute.The size of 4096 is considered assuming
2343 * that number of rates shall not exceed beyond 50 with
2344 * the sizeof (tSirWifiRateStat) being 32.
2345 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302346 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2347 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302348 if (!vendor_event)
2349 {
2350 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302351 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05302352 __func__);
2353 return;
2354 }
2355 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302356 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2357 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
2358 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302359 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
2360 pWifiPeerStat->numPeers))
2361 {
2362 hddLog(VOS_TRACE_LEVEL_ERROR,
2363 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
2364 kfree_skb(vendor_event);
2365 return;
2366 }
2367
2368 peerInfo = nla_nest_start(vendor_event,
2369 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302370 if(!peerInfo)
2371 {
2372 hddLog(VOS_TRACE_LEVEL_ERROR,
2373 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
2374 __func__);
2375 kfree_skb(vendor_event);
2376 return;
2377 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302378
2379 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2380 pWifiPeerStat->peerInfo);
2381
2382 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
2383 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302384 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302385 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302386
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302387 if(!peers)
2388 {
2389 hddLog(VOS_TRACE_LEVEL_ERROR,
2390 "%s: peer stats put fail",
2391 __func__);
2392 kfree_skb(vendor_event);
2393 return;
2394 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302395 if (FALSE == put_wifi_peer_info(
2396 pWifiPeerInfo, vendor_event))
2397 {
2398 hddLog(VOS_TRACE_LEVEL_ERROR,
2399 "%s: put_wifi_peer_info put fail", __func__);
2400 kfree_skb(vendor_event);
2401 return;
2402 }
2403
2404 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2405 pWifiPeerStat->peerInfo +
2406 (i * sizeof(tSirWifiPeerInfo)) +
2407 (numRate * sizeof (tSirWifiRateStat)));
2408 nla_nest_end(vendor_event, peers);
2409 }
2410 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302411 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302412 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302413}
2414
2415/*
2416 * hdd_link_layer_process_iface_stats () - This function is called after
2417 * receiving Link Layer Interface statistics from FW.This function converts
2418 * the firmware data to the NL data and sends the same to the kernel/upper
2419 * layers.
2420 */
2421static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
2422 v_VOID_t *pData)
2423{
2424 tpSirWifiIfaceStat pWifiIfaceStat;
2425 struct sk_buff *vendor_event;
2426 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2427 int status;
2428
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302429 ENTER();
2430
Sunil Duttc69bccb2014-05-26 21:30:20 +05302431 status = wlan_hdd_validate_context(pHddCtx);
2432 if (0 != status)
2433 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302434 return;
2435 }
2436 /*
2437 * Allocate a size of 4096 for the interface stats comprising
2438 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
2439 * assuming that all these fit with in the limit.Please take
2440 * a call on the limit based on the data requirements on
2441 * interface statistics.
2442 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302443 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2444 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302445 if (!vendor_event)
2446 {
2447 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302448 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302449 return;
2450 }
2451
2452 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
2453
Dino Mycle3b9536d2014-07-09 22:05:24 +05302454
2455 if (FALSE == hdd_get_interface_info( pAdapter,
2456 &pWifiIfaceStat->info))
2457 {
2458 hddLog(VOS_TRACE_LEVEL_ERROR,
2459 FL("hdd_get_interface_info get fail") );
2460 kfree_skb(vendor_event);
2461 return;
2462 }
2463
2464 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
2465 vendor_event))
2466 {
2467 hddLog(VOS_TRACE_LEVEL_ERROR,
2468 FL("put_wifi_iface_stats fail") );
2469 kfree_skb(vendor_event);
2470 return;
2471 }
2472
Sunil Duttc69bccb2014-05-26 21:30:20 +05302473 hddLog(VOS_TRACE_LEVEL_INFO,
2474 "WMI_LINK_STATS_IFACE Data");
2475
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302476 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302477
2478 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302479}
2480
2481/*
2482 * hdd_link_layer_process_radio_stats () - This function is called after
2483 * receiving Link Layer Radio statistics from FW.This function converts
2484 * the firmware data to the NL data and sends the same to the kernel/upper
2485 * layers.
2486 */
2487static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
2488 v_VOID_t *pData)
2489{
2490 int status, i;
2491 tpSirWifiRadioStat pWifiRadioStat;
2492 tpSirWifiChannelStats pWifiChannelStats;
2493 struct sk_buff *vendor_event;
2494 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2495 struct nlattr *chList;
2496
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302497 ENTER();
2498
Sunil Duttc69bccb2014-05-26 21:30:20 +05302499 status = wlan_hdd_validate_context(pHddCtx);
2500 if (0 != status)
2501 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302502 return;
2503 }
2504 pWifiRadioStat = (tpSirWifiRadioStat) pData;
2505
2506 hddLog(VOS_TRACE_LEVEL_INFO,
2507 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302508 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05302509 " radio is %d onTime is %u "
2510 " txTime is %u rxTime is %u "
2511 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05302512 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05302513 " onTimePnoScan is %u onTimeHs20 is %u "
2514 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302515 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302516 pWifiRadioStat->radio, pWifiRadioStat->onTime,
2517 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
2518 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302519 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302520 pWifiRadioStat->onTimeRoamScan,
2521 pWifiRadioStat->onTimePnoScan,
2522 pWifiRadioStat->onTimeHs20,
2523 pWifiRadioStat->numChannels);
2524 /*
2525 * Allocate a size of 4096 for the Radio stats comprising
2526 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
2527 * (tSirWifiChannelStats).Each channel data is put with an
2528 * NL attribute.The size of 4096 is considered assuming that
2529 * number of channels shall not exceed beyond 60 with the
2530 * sizeof (tSirWifiChannelStats) being 24 bytes.
2531 */
2532
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302533 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2534 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302535 if (!vendor_event)
2536 {
2537 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302538 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302539 return;
2540 }
2541
2542 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302543 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2544 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2545 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302546 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2547 pWifiRadioStat->radio) ||
2548 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302549 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2550 NUM_RADIOS) ||
2551 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302552 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2553 pWifiRadioStat->onTime) ||
2554 nla_put_u32(vendor_event,
2555 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2556 pWifiRadioStat->txTime) ||
2557 nla_put_u32(vendor_event,
2558 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2559 pWifiRadioStat->rxTime) ||
2560 nla_put_u32(vendor_event,
2561 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2562 pWifiRadioStat->onTimeScan) ||
2563 nla_put_u32(vendor_event,
2564 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2565 pWifiRadioStat->onTimeNbd) ||
2566 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302567 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2568 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302569 nla_put_u32(vendor_event,
2570 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2571 pWifiRadioStat->onTimeRoamScan) ||
2572 nla_put_u32(vendor_event,
2573 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2574 pWifiRadioStat->onTimePnoScan) ||
2575 nla_put_u32(vendor_event,
2576 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2577 pWifiRadioStat->onTimeHs20) ||
2578 nla_put_u32(vendor_event,
2579 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2580 pWifiRadioStat->numChannels))
2581 {
2582 hddLog(VOS_TRACE_LEVEL_ERROR,
2583 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2584 kfree_skb(vendor_event);
2585 return ;
2586 }
2587
2588 chList = nla_nest_start(vendor_event,
2589 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302590 if(!chList)
2591 {
2592 hddLog(VOS_TRACE_LEVEL_ERROR,
2593 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2594 __func__);
2595 kfree_skb(vendor_event);
2596 return;
2597 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302598 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2599 {
2600 struct nlattr *chInfo;
2601
2602 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2603 pWifiRadioStat->channels +
2604 (i * sizeof(tSirWifiChannelStats)));
2605
Sunil Duttc69bccb2014-05-26 21:30:20 +05302606 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302607 if(!chInfo)
2608 {
2609 hddLog(VOS_TRACE_LEVEL_ERROR,
2610 "%s: failed to put chInfo",
2611 __func__);
2612 kfree_skb(vendor_event);
2613 return;
2614 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302615
2616 if (nla_put_u32(vendor_event,
2617 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2618 pWifiChannelStats->channel.width) ||
2619 nla_put_u32(vendor_event,
2620 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2621 pWifiChannelStats->channel.centerFreq) ||
2622 nla_put_u32(vendor_event,
2623 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2624 pWifiChannelStats->channel.centerFreq0) ||
2625 nla_put_u32(vendor_event,
2626 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2627 pWifiChannelStats->channel.centerFreq1) ||
2628 nla_put_u32(vendor_event,
2629 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2630 pWifiChannelStats->onTime) ||
2631 nla_put_u32(vendor_event,
2632 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2633 pWifiChannelStats->ccaBusyTime))
2634 {
2635 hddLog(VOS_TRACE_LEVEL_ERROR,
2636 FL("cfg80211_vendor_event_alloc failed") );
2637 kfree_skb(vendor_event);
2638 return ;
2639 }
2640 nla_nest_end(vendor_event, chInfo);
2641 }
2642 nla_nest_end(vendor_event, chList);
2643
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302644 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302645
2646 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302647 return;
2648}
2649
2650/*
2651 * hdd_link_layer_stats_ind_callback () - This function is called after
2652 * receiving Link Layer indications from FW.This callback converts the firmware
2653 * data to the NL data and send the same to the kernel/upper layers.
2654 */
2655static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2656 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302657 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302658{
Dino Mycled3d50022014-07-07 12:58:25 +05302659 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2660 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302661 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302662 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302663 int status;
2664
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302665 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302666
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302667 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302668 if (0 != status)
2669 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302670 return;
2671 }
2672
Dino Mycled3d50022014-07-07 12:58:25 +05302673 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2674 if (NULL == pAdapter)
2675 {
2676 hddLog(VOS_TRACE_LEVEL_ERROR,
2677 FL(" MAC address %pM does not exist with host"),
2678 macAddr);
2679 return;
2680 }
2681
Sunil Duttc69bccb2014-05-26 21:30:20 +05302682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302683 "%s: Interface: %s LLStats indType: %d", __func__,
2684 pAdapter->dev->name, indType);
2685
Sunil Duttc69bccb2014-05-26 21:30:20 +05302686 switch (indType)
2687 {
2688 case SIR_HAL_LL_STATS_RESULTS_RSP:
2689 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302690 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302691 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2692 "respId = %u, moreResultToFollow = %u",
2693 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2694 macAddr, linkLayerStatsResults->respId,
2695 linkLayerStatsResults->moreResultToFollow);
2696
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302697 spin_lock(&hdd_context_lock);
2698 context = &pHddCtx->ll_stats_context;
2699 /* validate response received from target */
2700 if ((context->request_id != linkLayerStatsResults->respId) ||
2701 !(context->request_bitmap & linkLayerStatsResults->paramId))
2702 {
2703 spin_unlock(&hdd_context_lock);
2704 hddLog(LOGE,
2705 FL("Error : Request id %d response id %d request bitmap 0x%x"
2706 "response bitmap 0x%x"),
2707 context->request_id, linkLayerStatsResults->respId,
2708 context->request_bitmap, linkLayerStatsResults->paramId);
2709 return;
2710 }
2711 spin_unlock(&hdd_context_lock);
2712
Sunil Duttc69bccb2014-05-26 21:30:20 +05302713 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2714 {
2715 hdd_link_layer_process_radio_stats(pAdapter,
2716 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302717 spin_lock(&hdd_context_lock);
2718 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2719 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302720 }
2721 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2722 {
2723 hdd_link_layer_process_iface_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_IFACE);
2727 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302728 }
2729 else if ( linkLayerStatsResults->paramId &
2730 WMI_LINK_STATS_ALL_PEER )
2731 {
2732 hdd_link_layer_process_peer_stats(pAdapter,
2733 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302734 spin_lock(&hdd_context_lock);
2735 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2736 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302737 } /* WMI_LINK_STATS_ALL_PEER */
2738 else
2739 {
2740 hddLog(VOS_TRACE_LEVEL_ERROR,
2741 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2742 }
2743
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302744 spin_lock(&hdd_context_lock);
2745 /* complete response event if all requests are completed */
2746 if (0 == context->request_bitmap)
2747 complete(&context->response_event);
2748 spin_unlock(&hdd_context_lock);
2749
Sunil Duttc69bccb2014-05-26 21:30:20 +05302750 break;
2751 }
2752 default:
2753 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2754 break;
2755 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302756
2757 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302758 return;
2759}
2760
2761const struct
2762nla_policy
2763qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2764{
2765 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2766 { .type = NLA_U32 },
2767 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2768 { .type = NLA_U32 },
2769};
2770
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302771static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2772 struct wireless_dev *wdev,
2773 const void *data,
2774 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302775{
2776 int status;
2777 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302778 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302779 struct net_device *dev = wdev->netdev;
2780 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2781 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2782
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302783 ENTER();
2784
Sunil Duttc69bccb2014-05-26 21:30:20 +05302785 status = wlan_hdd_validate_context(pHddCtx);
2786 if (0 != status)
2787 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302788 return -EINVAL;
2789 }
2790
2791 if (NULL == pAdapter)
2792 {
2793 hddLog(VOS_TRACE_LEVEL_ERROR,
2794 FL("HDD adapter is Null"));
2795 return -ENODEV;
2796 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302797 /* check the LLStats Capability */
2798 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2799 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2800 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302801 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302802 FL("Link Layer Statistics not supported by Firmware"));
2803 return -EINVAL;
2804 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302805
2806 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2807 (struct nlattr *)data,
2808 data_len, qca_wlan_vendor_ll_set_policy))
2809 {
2810 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2811 return -EINVAL;
2812 }
2813 if (!tb_vendor
2814 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2815 {
2816 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2817 return -EINVAL;
2818 }
2819 if (!tb_vendor[
2820 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2821 {
2822 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2823 return -EINVAL;
2824 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302825 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302826 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302827
Dino Mycledf0a5d92014-07-04 09:41:55 +05302828 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302829 nla_get_u32(
2830 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2831
Dino Mycledf0a5d92014-07-04 09:41:55 +05302832 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302833 nla_get_u32(
2834 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2835
Dino Mycled3d50022014-07-07 12:58:25 +05302836 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2837 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302838
2839
2840 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302841 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2842 "Statistics Gathering = %d ",
2843 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2844 linkLayerStatsSetReq.mpduSizeThreshold,
2845 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302846
2847 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2848 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302849 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302850 {
2851 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2852 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302853 return -EINVAL;
2854
2855 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302856
Sunil Duttc69bccb2014-05-26 21:30:20 +05302857 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302858 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302859 {
2860 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2861 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302862 return -EINVAL;
2863 }
2864
2865 pAdapter->isLinkLayerStatsSet = 1;
2866
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302867 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302868 return 0;
2869}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302870static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2871 struct wireless_dev *wdev,
2872 const void *data,
2873 int data_len)
2874{
2875 int ret = 0;
2876
2877 vos_ssr_protect(__func__);
2878 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2879 vos_ssr_unprotect(__func__);
2880
2881 return ret;
2882}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302883
2884const struct
2885nla_policy
2886qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2887{
2888 /* Unsigned 32bit value provided by the caller issuing the GET stats
2889 * command. When reporting
2890 * the stats results, the driver uses the same value to indicate
2891 * which GET request the results
2892 * correspond to.
2893 */
2894 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2895
2896 /* Unsigned 32bit value . bit mask to identify what statistics are
2897 requested for retrieval */
2898 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2899};
2900
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302901static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2902 struct wireless_dev *wdev,
2903 const void *data,
2904 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302905{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302906 unsigned long rc;
2907 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302908 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2909 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302910 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302911 struct net_device *dev = wdev->netdev;
2912 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302913 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302914 int status;
2915
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302916 ENTER();
2917
Sunil Duttc69bccb2014-05-26 21:30:20 +05302918 status = wlan_hdd_validate_context(pHddCtx);
2919 if (0 != status)
2920 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302921 return -EINVAL ;
2922 }
2923
2924 if (NULL == pAdapter)
2925 {
2926 hddLog(VOS_TRACE_LEVEL_FATAL,
2927 "%s: HDD adapter is Null", __func__);
2928 return -ENODEV;
2929 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302930
2931 if (pHddStaCtx == NULL)
2932 {
2933 hddLog(VOS_TRACE_LEVEL_FATAL,
2934 "%s: HddStaCtx is Null", __func__);
2935 return -ENODEV;
2936 }
2937
Dino Mycledf0a5d92014-07-04 09:41:55 +05302938 /* check the LLStats Capability */
2939 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2940 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2941 {
2942 hddLog(VOS_TRACE_LEVEL_ERROR,
2943 FL("Link Layer Statistics not supported by Firmware"));
2944 return -EINVAL;
2945 }
2946
Sunil Duttc69bccb2014-05-26 21:30:20 +05302947
2948 if (!pAdapter->isLinkLayerStatsSet)
2949 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302950 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302951 "%s: isLinkLayerStatsSet : %d",
2952 __func__, pAdapter->isLinkLayerStatsSet);
2953 return -EINVAL;
2954 }
2955
Mukul Sharma10313ba2015-07-29 19:14:39 +05302956 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2957 {
2958 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2959 "%s: Roaming in progress, so unable to proceed this request", __func__);
2960 return -EBUSY;
2961 }
2962
Sunil Duttc69bccb2014-05-26 21:30:20 +05302963 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2964 (struct nlattr *)data,
2965 data_len, qca_wlan_vendor_ll_get_policy))
2966 {
2967 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2968 return -EINVAL;
2969 }
2970
2971 if (!tb_vendor
2972 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2973 {
2974 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2975 return -EINVAL;
2976 }
2977
2978 if (!tb_vendor
2979 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2980 {
2981 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2982 return -EINVAL;
2983 }
2984
Sunil Duttc69bccb2014-05-26 21:30:20 +05302985
Dino Mycledf0a5d92014-07-04 09:41:55 +05302986 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302987 nla_get_u32( tb_vendor[
2988 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302989 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302990 nla_get_u32( tb_vendor[
2991 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2992
Dino Mycled3d50022014-07-07 12:58:25 +05302993 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2994 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302995
2996 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302997 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
2998 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302999 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303000
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303001 spin_lock(&hdd_context_lock);
3002 context = &pHddCtx->ll_stats_context;
3003 context->request_id = linkLayerStatsGetReq.reqId;
3004 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
3005 INIT_COMPLETION(context->response_event);
3006 spin_unlock(&hdd_context_lock);
3007
Sunil Duttc69bccb2014-05-26 21:30:20 +05303008 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303009 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303010 {
3011 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3012 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303013 return -EINVAL;
3014 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303015
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303016 rc = wait_for_completion_timeout(&context->response_event,
3017 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
3018 if (!rc)
3019 {
3020 hddLog(LOGE,
3021 FL("Target response timed out request id %d request bitmap 0x%x"),
3022 context->request_id, context->request_bitmap);
3023 return -ETIMEDOUT;
3024 }
3025
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303026 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303027 return 0;
3028}
3029
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303030static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
3031 struct wireless_dev *wdev,
3032 const void *data,
3033 int data_len)
3034{
3035 int ret = 0;
3036
3037 vos_ssr_protect(__func__);
3038 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
3039 vos_ssr_unprotect(__func__);
3040
3041 return ret;
3042}
3043
Sunil Duttc69bccb2014-05-26 21:30:20 +05303044const struct
3045nla_policy
3046qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
3047{
3048 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
3049 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
3050 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
3051 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
3052};
3053
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303054static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3055 struct wireless_dev *wdev,
3056 const void *data,
3057 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303058{
3059 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3060 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05303061 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303062 struct net_device *dev = wdev->netdev;
3063 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3064 u32 statsClearReqMask;
3065 u8 stopReq;
3066 int status;
3067
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303068 ENTER();
3069
Sunil Duttc69bccb2014-05-26 21:30:20 +05303070 status = wlan_hdd_validate_context(pHddCtx);
3071 if (0 != status)
3072 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303073 return -EINVAL;
3074 }
3075
3076 if (NULL == pAdapter)
3077 {
3078 hddLog(VOS_TRACE_LEVEL_FATAL,
3079 "%s: HDD adapter is Null", __func__);
3080 return -ENODEV;
3081 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05303082 /* check the LLStats Capability */
3083 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
3084 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
3085 {
3086 hddLog(VOS_TRACE_LEVEL_ERROR,
3087 FL("Enable LLStats Capability"));
3088 return -EINVAL;
3089 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05303090
3091 if (!pAdapter->isLinkLayerStatsSet)
3092 {
3093 hddLog(VOS_TRACE_LEVEL_FATAL,
3094 "%s: isLinkLayerStatsSet : %d",
3095 __func__, pAdapter->isLinkLayerStatsSet);
3096 return -EINVAL;
3097 }
3098
3099 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
3100 (struct nlattr *)data,
3101 data_len, qca_wlan_vendor_ll_clr_policy))
3102 {
3103 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
3104 return -EINVAL;
3105 }
3106
3107 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
3108
3109 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
3110 {
3111 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
3112 return -EINVAL;
3113
3114 }
3115
Sunil Duttc69bccb2014-05-26 21:30:20 +05303116
Dino Mycledf0a5d92014-07-04 09:41:55 +05303117 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303118 nla_get_u32(
3119 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
3120
Dino Mycledf0a5d92014-07-04 09:41:55 +05303121 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303122 nla_get_u8(
3123 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
3124
3125 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05303126 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303127
Dino Mycled3d50022014-07-07 12:58:25 +05303128 vos_mem_copy(linkLayerStatsClearReq.macAddr,
3129 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05303130
3131 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05303132 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
3133 "statsClearReqMask = 0x%X, stopReq = %d",
3134 linkLayerStatsClearReq.reqId,
3135 linkLayerStatsClearReq.macAddr,
3136 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303137 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303138
3139 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303140 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303141 {
3142 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05303143 hdd_station_ctx_t *pHddStaCtx;
3144
3145 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3146 if (VOS_STATUS_SUCCESS !=
3147 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
3148 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
3149 {
3150 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3151 "WLANTL_ClearInterfaceStats Failed", __func__);
3152 return -EINVAL;
3153 }
3154 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
3155 (statsClearReqMask & WIFI_STATS_IFACE)) {
3156 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
3157 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
3158 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
3159 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
3160 }
3161
Sunil Duttc69bccb2014-05-26 21:30:20 +05303162 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
3163 2 * sizeof(u32) +
3164 NLMSG_HDRLEN);
3165
3166 if (temp_skbuff != NULL)
3167 {
3168
3169 if (nla_put_u32(temp_skbuff,
3170 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
3171 statsClearReqMask) ||
3172 nla_put_u32(temp_skbuff,
3173 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
3174 stopReq))
3175 {
3176 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
3177 kfree_skb(temp_skbuff);
3178 return -EINVAL;
3179 }
3180 /* If the ask is to stop the stats collection as part of clear
3181 * (stopReq = 1) , ensure that no further requests of get
3182 * go to the firmware by having isLinkLayerStatsSet set to 0.
3183 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303184 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05303185 * case the firmware is just asked to clear the statistics.
3186 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05303187 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303188 pAdapter->isLinkLayerStatsSet = 0;
3189 return cfg80211_vendor_cmd_reply(temp_skbuff);
3190 }
3191 return -ENOMEM;
3192 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303193
3194 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303195 return -EINVAL;
3196}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303197static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3198 struct wireless_dev *wdev,
3199 const void *data,
3200 int data_len)
3201{
3202 int ret = 0;
3203
3204 vos_ssr_protect(__func__);
3205 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
3206 vos_ssr_unprotect(__func__);
3207
3208 return ret;
3209
3210
3211}
Sunil Duttc69bccb2014-05-26 21:30:20 +05303212#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
3213
Dino Mycle6fb96c12014-06-10 11:52:40 +05303214#ifdef WLAN_FEATURE_EXTSCAN
3215static const struct nla_policy
3216wlan_hdd_extscan_config_policy
3217 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
3218{
3219 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
3220 { .type = NLA_U32 },
3221 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
3222 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05303223 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
3224 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303225 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
3226 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
3227 { .type = NLA_U32 },
3228 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
3229 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
3230
3231 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
3232 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
3233 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
3234 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
3235 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303236 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
3237 { .type = NLA_U32 },
3238 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
3239 { .type = NLA_U32 },
3240 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
3241 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303242 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
3243 { .type = NLA_U32 },
3244 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
3245 { .type = NLA_U32 },
3246 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
3247 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303248 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
3249 { .type = NLA_U8 },
3250 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303251 { .type = NLA_U8 },
3252 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
3253 { .type = NLA_U8 },
3254 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
3255 { .type = NLA_U8 },
3256
3257 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
3258 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05303259 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
3260 .type = NLA_UNSPEC,
3261 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05303262 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
3263 { .type = NLA_S32 },
3264 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
3265 { .type = NLA_S32 },
3266 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
3267 { .type = NLA_U32 },
3268 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
3269 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303270 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
3271 { .type = NLA_U32 },
3272 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
3273 { .type = NLA_BINARY,
3274 .len = IEEE80211_MAX_SSID_LEN + 1 },
3275 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303276 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303277 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
3278 { .type = NLA_U32 },
3279 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
3280 { .type = NLA_U8 },
3281 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
3282 { .type = NLA_S32 },
3283 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
3284 { .type = NLA_S32 },
3285 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
3286 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303287};
3288
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303289/**
3290 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
3291 * @ctx: hdd global context
3292 * @data: capabilities data
3293 *
3294 * Return: none
3295 */
3296static void
3297wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303298{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303299 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303300 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303301 tSirEXTScanCapabilitiesEvent *data =
3302 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303303
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303304 ENTER();
3305
3306 if (wlan_hdd_validate_context(pHddCtx))
3307 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303308 return;
3309 }
3310
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303311 if (!pMsg)
3312 {
3313 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3314 return;
3315 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303316
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303317 vos_spin_lock_acquire(&hdd_context_lock);
3318
3319 context = &pHddCtx->ext_scan_context;
3320 /* validate response received from target*/
3321 if (context->request_id != data->requestId)
3322 {
3323 vos_spin_lock_release(&hdd_context_lock);
3324 hddLog(LOGE,
3325 FL("Target response id did not match: request_id %d resposne_id %d"),
3326 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303327 return;
3328 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303329 else
3330 {
3331 context->capability_response = *data;
3332 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303333 }
3334
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303335 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303336
Dino Mycle6fb96c12014-06-10 11:52:40 +05303337 return;
3338}
3339
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303340/*
3341 * define short names for the global vendor params
3342 * used by wlan_hdd_send_ext_scan_capability()
3343 */
3344#define PARAM_REQUEST_ID \
3345 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3346#define PARAM_STATUS \
3347 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
3348#define MAX_SCAN_CACHE_SIZE \
3349 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
3350#define MAX_SCAN_BUCKETS \
3351 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
3352#define MAX_AP_CACHE_PER_SCAN \
3353 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
3354#define MAX_RSSI_SAMPLE_SIZE \
3355 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
3356#define MAX_SCAN_RPT_THRHOLD \
3357 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
3358#define MAX_HOTLIST_BSSIDS \
3359 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
3360#define MAX_BSSID_HISTORY_ENTRIES \
3361 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
3362#define MAX_HOTLIST_SSIDS \
3363 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303364#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
3365 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303366
3367static int wlan_hdd_send_ext_scan_capability(void *ctx)
3368{
3369 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3370 struct sk_buff *skb = NULL;
3371 int ret;
3372 tSirEXTScanCapabilitiesEvent *data;
3373 tANI_U32 nl_buf_len;
3374
3375 ret = wlan_hdd_validate_context(pHddCtx);
3376 if (0 != ret)
3377 {
3378 return ret;
3379 }
3380
3381 data = &(pHddCtx->ext_scan_context.capability_response);
3382
3383 nl_buf_len = NLMSG_HDRLEN;
3384 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
3385 (sizeof(data->status) + NLA_HDRLEN) +
3386 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
3387 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
3388 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
3389 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
3390 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
3391 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
3392 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
3393 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
3394
3395 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
3396
3397 if (!skb)
3398 {
3399 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
3400 return -ENOMEM;
3401 }
3402
3403 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
3404 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
3405 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
3406 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
3407 data->maxRssiSampleSize, data->maxScanReportingThreshold);
3408 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
3409 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
3410 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
3411
3412 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
3413 nla_put_u32(skb, PARAM_STATUS, data->status) ||
3414 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
3415 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
3416 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
3417 data->maxApPerScan) ||
3418 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
3419 data->maxRssiSampleSize) ||
3420 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
3421 data->maxScanReportingThreshold) ||
3422 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
3423 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
3424 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303425 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
3426 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303427 {
3428 hddLog(LOGE, FL("nla put fail"));
3429 goto nla_put_failure;
3430 }
3431
3432 cfg80211_vendor_cmd_reply(skb);
3433 return 0;
3434
3435nla_put_failure:
3436 kfree_skb(skb);
3437 return -EINVAL;;
3438}
3439
3440/*
3441 * done with short names for the global vendor params
3442 * used by wlan_hdd_send_ext_scan_capability()
3443 */
3444#undef PARAM_REQUEST_ID
3445#undef PARAM_STATUS
3446#undef MAX_SCAN_CACHE_SIZE
3447#undef MAX_SCAN_BUCKETS
3448#undef MAX_AP_CACHE_PER_SCAN
3449#undef MAX_RSSI_SAMPLE_SIZE
3450#undef MAX_SCAN_RPT_THRHOLD
3451#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303452#undef MAX_BSSID_HISTORY_ENTRIES
3453#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05303454
3455static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
3456{
3457 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
3458 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303459 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303460 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303461
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303462 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303463
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303464 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303465 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303466
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303467 if (!pMsg)
3468 {
3469 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303470 return;
3471 }
3472
Dino Mycle6fb96c12014-06-10 11:52:40 +05303473 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3474 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
3475
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303476 context = &pHddCtx->ext_scan_context;
3477 spin_lock(&hdd_context_lock);
3478 if (context->request_id == pData->requestId) {
3479 context->response_status = pData->status ? -EINVAL : 0;
3480 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303481 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303482 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303483
3484 /*
3485 * Store the Request ID for comparing with the requestID obtained
3486 * in other requests.HDD shall return a failure is the extscan_stop
3487 * request is issued with a different requestId as that of the
3488 * extscan_start request. Also, This requestId shall be used while
3489 * indicating the full scan results to the upper layers.
3490 * The requestId is stored with the assumption that the firmware
3491 * shall return the ext scan start request's requestId in ext scan
3492 * start response.
3493 */
3494 if (pData->status == 0)
3495 pMac->sme.extScanStartReqId = pData->requestId;
3496
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303497 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303498 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303499}
3500
3501
3502static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
3503{
3504 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
3505 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303506 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303507
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303508 ENTER();
3509
3510 if (wlan_hdd_validate_context(pHddCtx)){
3511 return;
3512 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303513
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303514 if (!pMsg)
3515 {
3516 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303517 return;
3518 }
3519
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303520 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3521 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303522
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303523 context = &pHddCtx->ext_scan_context;
3524 spin_lock(&hdd_context_lock);
3525 if (context->request_id == pData->requestId) {
3526 context->response_status = pData->status ? -EINVAL : 0;
3527 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303528 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303529 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303530
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303531 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303532 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303533}
3534
Dino Mycle6fb96c12014-06-10 11:52:40 +05303535static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3536 void *pMsg)
3537{
3538 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303539 tpSirEXTScanSetBssidHotListRspParams pData =
3540 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303541 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303542
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303543 ENTER();
3544
3545 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303546 return;
3547 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303548
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303549 if (!pMsg)
3550 {
3551 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3552 return;
3553 }
3554
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303555 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3556 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303557
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303558 context = &pHddCtx->ext_scan_context;
3559 spin_lock(&hdd_context_lock);
3560 if (context->request_id == pData->requestId) {
3561 context->response_status = pData->status ? -EINVAL : 0;
3562 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303563 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303564 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303565
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303566 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303567 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303568}
3569
3570static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3571 void *pMsg)
3572{
3573 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303574 tpSirEXTScanResetBssidHotlistRspParams pData =
3575 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303576 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303577
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303578 ENTER();
3579
3580 if (wlan_hdd_validate_context(pHddCtx)) {
3581 return;
3582 }
3583 if (!pMsg)
3584 {
3585 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303586 return;
3587 }
3588
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303589 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3590 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303591
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303592 context = &pHddCtx->ext_scan_context;
3593 spin_lock(&hdd_context_lock);
3594 if (context->request_id == pData->requestId) {
3595 context->response_status = pData->status ? -EINVAL : 0;
3596 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303597 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303598 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303599
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303600 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303601 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303602}
3603
Dino Mycle6fb96c12014-06-10 11:52:40 +05303604static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3605 void *pMsg)
3606{
3607 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3608 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303609 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303610 tANI_S32 totalResults;
3611 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303612 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3613 struct hdd_ext_scan_context *context;
3614 bool ignore_cached_results = false;
3615 tExtscanCachedScanResult *result;
3616 struct nlattr *nla_results;
3617 tANI_U16 ieLength= 0;
3618 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303619
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303620 ENTER();
3621
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303622 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303623 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303624
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303625 if (!pMsg)
3626 {
3627 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3628 return;
3629 }
3630
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303631 spin_lock(&hdd_context_lock);
3632 context = &pHddCtx->ext_scan_context;
3633 ignore_cached_results = context->ignore_cached_results;
3634 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303635
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303636 if (ignore_cached_results) {
3637 hddLog(LOGE,
3638 FL("Ignore the cached results received after timeout"));
3639 return;
3640 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303641
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303642 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3643 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303644
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303645 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303646
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303647 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3648 scan_id_index++) {
3649 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303650
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303651 totalResults = result->num_results;
3652 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3653 result->scan_id, result->flags, totalResults);
3654 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303655
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303656 do{
3657 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3658 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3659 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303660
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303661 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3662 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3663
3664 if (!skb) {
3665 hddLog(VOS_TRACE_LEVEL_ERROR,
3666 FL("cfg80211_vendor_event_alloc failed"));
3667 return;
3668 }
3669
3670 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3671
3672 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3673 pData->requestId) ||
3674 nla_put_u32(skb,
3675 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3676 resultsPerEvent)) {
3677 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3678 goto fail;
3679 }
3680 if (nla_put_u8(skb,
3681 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3682 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303683 {
3684 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3685 goto fail;
3686 }
3687
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303688 if (nla_put_u32(skb,
3689 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3690 result->scan_id)) {
3691 hddLog(LOGE, FL("put fail"));
3692 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303693 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303694
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303695 nla_results = nla_nest_start(skb,
3696 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3697 if (!nla_results)
3698 goto fail;
3699
3700 if (resultsPerEvent) {
3701 struct nlattr *aps;
3702 struct nlattr *nla_result;
3703
3704 nla_result = nla_nest_start(skb, scan_id_index);
3705 if(!nla_result)
3706 goto fail;
3707
3708 if (nla_put_u32(skb,
3709 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3710 result->scan_id) ||
3711 nla_put_u32(skb,
3712 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3713 result->flags) ||
3714 nla_put_u32(skb,
3715 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3716 totalResults)) {
3717 hddLog(LOGE, FL("put fail"));
3718 goto fail;
3719 }
3720
3721 aps = nla_nest_start(skb,
3722 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3723 if (!aps)
3724 {
3725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3726 goto fail;
3727 }
3728
3729 head_ptr = (tpSirWifiScanResult) &(result->ap);
3730
3731 for (j = 0; j < resultsPerEvent; j++, i++) {
3732 struct nlattr *ap;
3733 pSirWifiScanResult = head_ptr + i;
3734
3735 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303736 * Firmware returns timestamp from extscan_start till
3737 * BSSID was cached (in micro seconds). Add this with
3738 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303739 * to derive the time since boot when the
3740 * BSSID was cached.
3741 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303742 pSirWifiScanResult->ts +=
3743 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303744 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3745 "Ssid (%s)"
3746 "Bssid: %pM "
3747 "Channel (%u)"
3748 "Rssi (%d)"
3749 "RTT (%u)"
3750 "RTT_SD (%u)"
3751 "Beacon Period %u"
3752 "Capability 0x%x "
3753 "Ie length %d",
3754 i,
3755 pSirWifiScanResult->ts,
3756 pSirWifiScanResult->ssid,
3757 pSirWifiScanResult->bssid,
3758 pSirWifiScanResult->channel,
3759 pSirWifiScanResult->rssi,
3760 pSirWifiScanResult->rtt,
3761 pSirWifiScanResult->rtt_sd,
3762 pSirWifiScanResult->beaconPeriod,
3763 pSirWifiScanResult->capability,
3764 ieLength);
3765
3766 ap = nla_nest_start(skb, j + 1);
3767 if (!ap)
3768 {
3769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3770 goto fail;
3771 }
3772
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303773 if (hdd_wlan_nla_put_u64(skb,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303774 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3775 pSirWifiScanResult->ts) )
3776 {
3777 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3778 goto fail;
3779 }
3780 if (nla_put(skb,
3781 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3782 sizeof(pSirWifiScanResult->ssid),
3783 pSirWifiScanResult->ssid) )
3784 {
3785 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3786 goto fail;
3787 }
3788 if (nla_put(skb,
3789 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3790 sizeof(pSirWifiScanResult->bssid),
3791 pSirWifiScanResult->bssid) )
3792 {
3793 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3794 goto fail;
3795 }
3796 if (nla_put_u32(skb,
3797 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3798 pSirWifiScanResult->channel) )
3799 {
3800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3801 goto fail;
3802 }
3803 if (nla_put_s32(skb,
3804 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3805 pSirWifiScanResult->rssi) )
3806 {
3807 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3808 goto fail;
3809 }
3810 if (nla_put_u32(skb,
3811 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3812 pSirWifiScanResult->rtt) )
3813 {
3814 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3815 goto fail;
3816 }
3817 if (nla_put_u32(skb,
3818 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3819 pSirWifiScanResult->rtt_sd))
3820 {
3821 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3822 goto fail;
3823 }
3824 if (nla_put_u32(skb,
3825 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3826 pSirWifiScanResult->beaconPeriod))
3827 {
3828 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3829 goto fail;
3830 }
3831 if (nla_put_u32(skb,
3832 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3833 pSirWifiScanResult->capability))
3834 {
3835 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3836 goto fail;
3837 }
3838 if (nla_put_u32(skb,
3839 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3840 ieLength))
3841 {
3842 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3843 goto fail;
3844 }
3845
3846 if (ieLength)
3847 if (nla_put(skb,
3848 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3849 ieLength, ie)) {
3850 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3851 goto fail;
3852 }
3853
3854 nla_nest_end(skb, ap);
3855 }
3856 nla_nest_end(skb, aps);
3857 nla_nest_end(skb, nla_result);
3858 }
3859
3860 nla_nest_end(skb, nla_results);
3861
3862 cfg80211_vendor_cmd_reply(skb);
3863
3864 } while (totalResults > 0);
3865 }
3866
3867 if (!pData->moreData) {
3868 spin_lock(&hdd_context_lock);
3869 context->response_status = 0;
3870 complete(&context->response_event);
3871 spin_unlock(&hdd_context_lock);
3872 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303873
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303874 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303875 return;
3876fail:
3877 kfree_skb(skb);
3878 return;
3879}
3880
3881static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3882 void *pMsg)
3883{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303884 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303885 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3886 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303887 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303888
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303889 ENTER();
3890
3891 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303892 hddLog(LOGE,
3893 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303894 return;
3895 }
3896 if (!pMsg)
3897 {
3898 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303899 return;
3900 }
3901
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303902 if (pData->bss_found)
3903 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3904 else
3905 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3906
Dino Mycle6fb96c12014-06-10 11:52:40 +05303907 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303908#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3909 NULL,
3910#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303911 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303912 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303913
3914 if (!skb) {
3915 hddLog(VOS_TRACE_LEVEL_ERROR,
3916 FL("cfg80211_vendor_event_alloc failed"));
3917 return;
3918 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303919
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303920 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3921 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3922 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3923 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3924
3925 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303926 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3927 "Ssid (%s) "
3928 "Bssid (" MAC_ADDRESS_STR ") "
3929 "Channel (%u) "
3930 "Rssi (%d) "
3931 "RTT (%u) "
3932 "RTT_SD (%u) ",
3933 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303934 pData->bssHotlist[i].ts,
3935 pData->bssHotlist[i].ssid,
3936 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3937 pData->bssHotlist[i].channel,
3938 pData->bssHotlist[i].rssi,
3939 pData->bssHotlist[i].rtt,
3940 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303941 }
3942
3943 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3944 pData->requestId) ||
3945 nla_put_u32(skb,
3946 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303947 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303948 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3949 goto fail;
3950 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303951 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303952 struct nlattr *aps;
3953
3954 aps = nla_nest_start(skb,
3955 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3956 if (!aps)
3957 goto fail;
3958
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303959 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303960 struct nlattr *ap;
3961
3962 ap = nla_nest_start(skb, i + 1);
3963 if (!ap)
3964 goto fail;
3965
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303966 if (hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303967 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303968 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303969 nla_put(skb,
3970 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303971 sizeof(pData->bssHotlist[i].ssid),
3972 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303973 nla_put(skb,
3974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303975 sizeof(pData->bssHotlist[i].bssid),
3976 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303977 nla_put_u32(skb,
3978 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303979 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303980 nla_put_s32(skb,
3981 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303982 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303983 nla_put_u32(skb,
3984 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303985 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303986 nla_put_u32(skb,
3987 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303988 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303989 goto fail;
3990
3991 nla_nest_end(skb, ap);
3992 }
3993 nla_nest_end(skb, aps);
3994
3995 if (nla_put_u8(skb,
3996 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3997 pData->moreData))
3998 goto fail;
3999 }
4000
4001 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304002 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304003 return;
4004
4005fail:
4006 kfree_skb(skb);
4007 return;
4008
4009}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304010
4011static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
4012 void *pMsg)
4013{
4014 struct sk_buff *skb;
4015 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4016 tpSirWifiFullScanResultEvent pData =
4017 (tpSirWifiFullScanResultEvent) (pMsg);
4018
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304019 ENTER();
4020
4021 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304022 hddLog(LOGE,
4023 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304024 return;
4025 }
4026 if (!pMsg)
4027 {
4028 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304029 return;
4030 }
4031
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304032 /*
4033 * If the full scan result including IE data exceeds NL 4K size
4034 * limitation, drop that beacon/probe rsp frame.
4035 */
4036 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
4037 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
4038 return;
4039 }
4040
Dino Mycle6fb96c12014-06-10 11:52:40 +05304041 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304042#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4043 NULL,
4044#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304045 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4046 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
4047 GFP_KERNEL);
4048
4049 if (!skb) {
4050 hddLog(VOS_TRACE_LEVEL_ERROR,
4051 FL("cfg80211_vendor_event_alloc failed"));
4052 return;
4053 }
4054
Dino Mycle6fb96c12014-06-10 11:52:40 +05304055 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
4056 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
4057 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
4058 "Ssid (%s)"
4059 "Bssid (" MAC_ADDRESS_STR ")"
4060 "Channel (%u)"
4061 "Rssi (%d)"
4062 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304063 "RTT_SD (%u)"
4064 "Bcn Period %d"
4065 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05304066 pData->ap.ts,
4067 pData->ap.ssid,
4068 MAC_ADDR_ARRAY(pData->ap.bssid),
4069 pData->ap.channel,
4070 pData->ap.rssi,
4071 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304072 pData->ap.rtt_sd,
4073 pData->ap.beaconPeriod,
4074 pData->ap.capability);
4075
Dino Mycle6fb96c12014-06-10 11:52:40 +05304076 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
4077 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4078 pData->requestId) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304079 hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304080 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
4081 pData->ap.ts) ||
4082 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
4083 sizeof(pData->ap.ssid),
4084 pData->ap.ssid) ||
4085 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
4086 WNI_CFG_BSSID_LEN,
4087 pData->ap.bssid) ||
4088 nla_put_u32(skb,
4089 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
4090 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05304091 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304092 pData->ap.rssi) ||
4093 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
4094 pData->ap.rtt) ||
4095 nla_put_u32(skb,
4096 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
4097 pData->ap.rtt_sd) ||
4098 nla_put_u16(skb,
4099 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
4100 pData->ap.beaconPeriod) ||
4101 nla_put_u16(skb,
4102 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
4103 pData->ap.capability) ||
4104 nla_put_u32(skb,
4105 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304106 pData->ieLength) ||
4107 nla_put_u8(skb,
4108 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
4109 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304110 {
4111 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4112 goto nla_put_failure;
4113 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304114
4115 if (pData->ieLength) {
4116 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
4117 pData->ieLength,
4118 pData->ie))
4119 {
4120 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4121 goto nla_put_failure;
4122 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304123 }
4124
4125 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304126 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304127 return;
4128
4129nla_put_failure:
4130 kfree_skb(skb);
4131 return;
4132}
4133
4134static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
4135 void *pMsg)
4136{
4137 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4138 struct sk_buff *skb = NULL;
4139 tpSirEXTScanResultsAvailableIndParams pData =
4140 (tpSirEXTScanResultsAvailableIndParams) pMsg;
4141
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304142 ENTER();
4143
4144 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304145 hddLog(LOGE,
4146 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304147 return;
4148 }
4149 if (!pMsg)
4150 {
4151 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304152 return;
4153 }
4154
4155 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304156#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4157 NULL,
4158#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304159 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4160 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
4161 GFP_KERNEL);
4162
4163 if (!skb) {
4164 hddLog(VOS_TRACE_LEVEL_ERROR,
4165 FL("cfg80211_vendor_event_alloc failed"));
4166 return;
4167 }
4168
Dino Mycle6fb96c12014-06-10 11:52:40 +05304169 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
4170 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
4171 pData->numResultsAvailable);
4172 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4173 pData->requestId) ||
4174 nla_put_u32(skb,
4175 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
4176 pData->numResultsAvailable)) {
4177 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4178 goto nla_put_failure;
4179 }
4180
4181 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304182 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304183 return;
4184
4185nla_put_failure:
4186 kfree_skb(skb);
4187 return;
4188}
4189
4190static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
4191{
4192 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4193 struct sk_buff *skb = NULL;
4194 tpSirEXTScanProgressIndParams pData =
4195 (tpSirEXTScanProgressIndParams) pMsg;
4196
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304197 ENTER();
4198
4199 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304200 hddLog(LOGE,
4201 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304202 return;
4203 }
4204 if (!pMsg)
4205 {
4206 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304207 return;
4208 }
4209
4210 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304211#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4212 NULL,
4213#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304214 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4215 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
4216 GFP_KERNEL);
4217
4218 if (!skb) {
4219 hddLog(VOS_TRACE_LEVEL_ERROR,
4220 FL("cfg80211_vendor_event_alloc failed"));
4221 return;
4222 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304223 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304224 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
4225 pData->extScanEventType);
4226 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
4227 pData->status);
4228
4229 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
4230 pData->extScanEventType) ||
4231 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05304232 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4233 pData->requestId) ||
4234 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304235 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
4236 pData->status)) {
4237 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4238 goto nla_put_failure;
4239 }
4240
4241 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304242 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304243 return;
4244
4245nla_put_failure:
4246 kfree_skb(skb);
4247 return;
4248}
4249
4250void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
4251 void *pMsg)
4252{
4253 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4254
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304255 ENTER();
4256
Dino Mycle6fb96c12014-06-10 11:52:40 +05304257 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304258 return;
4259 }
4260
4261 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
4262
4263
4264 switch(evType) {
4265 case SIR_HAL_EXTSCAN_START_RSP:
4266 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
4267 break;
4268
4269 case SIR_HAL_EXTSCAN_STOP_RSP:
4270 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
4271 break;
4272 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
4273 /* There is no need to send this response to upper layer
4274 Just log the message */
4275 hddLog(VOS_TRACE_LEVEL_INFO,
4276 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
4277 break;
4278 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
4279 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
4280 break;
4281
4282 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
4283 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
4284 break;
4285
Dino Mycle6fb96c12014-06-10 11:52:40 +05304286 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304287 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304288 break;
4289 case SIR_HAL_EXTSCAN_PROGRESS_IND:
4290 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
4291 break;
4292 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
4293 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
4294 break;
4295 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
4296 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
4297 break;
4298 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
4299 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
4300 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304301 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
4302 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
4303 break;
4304 default:
4305 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
4306 break;
4307 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304308 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304309}
4310
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304311static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4312 struct wireless_dev *wdev,
4313 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304314{
Dino Myclee8843b32014-07-04 14:21:45 +05304315 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304316 struct net_device *dev = wdev->netdev;
4317 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4318 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4319 struct nlattr
4320 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4321 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304322 struct hdd_ext_scan_context *context;
4323 unsigned long rc;
4324 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304325
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304326 ENTER();
4327
Dino Mycle6fb96c12014-06-10 11:52:40 +05304328 status = wlan_hdd_validate_context(pHddCtx);
4329 if (0 != status)
4330 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304331 return -EINVAL;
4332 }
Dino Myclee8843b32014-07-04 14:21:45 +05304333 /* check the EXTScan Capability */
4334 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304335 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4336 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304337 {
4338 hddLog(VOS_TRACE_LEVEL_ERROR,
4339 FL("EXTScan not enabled/supported by Firmware"));
4340 return -EINVAL;
4341 }
4342
Dino Mycle6fb96c12014-06-10 11:52:40 +05304343 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4344 data, dataLen,
4345 wlan_hdd_extscan_config_policy)) {
4346 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4347 return -EINVAL;
4348 }
4349
4350 /* Parse and fetch request Id */
4351 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4352 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4353 return -EINVAL;
4354 }
4355
Dino Myclee8843b32014-07-04 14:21:45 +05304356 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304357 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304358 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304359
Dino Myclee8843b32014-07-04 14:21:45 +05304360 reqMsg.sessionId = pAdapter->sessionId;
4361 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304362
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304363 vos_spin_lock_acquire(&hdd_context_lock);
4364 context = &pHddCtx->ext_scan_context;
4365 context->request_id = reqMsg.requestId;
4366 INIT_COMPLETION(context->response_event);
4367 vos_spin_lock_release(&hdd_context_lock);
4368
Dino Myclee8843b32014-07-04 14:21:45 +05304369 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304370 if (!HAL_STATUS_SUCCESS(status)) {
4371 hddLog(VOS_TRACE_LEVEL_ERROR,
4372 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304373 return -EINVAL;
4374 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304375
4376 rc = wait_for_completion_timeout(&context->response_event,
4377 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4378 if (!rc) {
4379 hddLog(LOGE, FL("Target response timed out"));
4380 return -ETIMEDOUT;
4381 }
4382
4383 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
4384 if (ret)
4385 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
4386
4387 return ret;
4388
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304389 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304390 return 0;
4391}
4392
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304393static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4394 struct wireless_dev *wdev,
4395 const void *data, int dataLen)
4396{
4397 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304398
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304399 vos_ssr_protect(__func__);
4400 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
4401 vos_ssr_unprotect(__func__);
4402
4403 return ret;
4404}
4405
4406static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4407 struct wireless_dev *wdev,
4408 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304409{
Dino Myclee8843b32014-07-04 14:21:45 +05304410 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304411 struct net_device *dev = wdev->netdev;
4412 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4413 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4414 struct nlattr
4415 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4416 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304417 struct hdd_ext_scan_context *context;
4418 unsigned long rc;
4419 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304420
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304421 ENTER();
4422
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304423 if (VOS_FTM_MODE == hdd_get_conparam()) {
4424 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4425 return -EINVAL;
4426 }
4427
Dino Mycle6fb96c12014-06-10 11:52:40 +05304428 status = wlan_hdd_validate_context(pHddCtx);
4429 if (0 != status)
4430 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304431 return -EINVAL;
4432 }
Dino Myclee8843b32014-07-04 14:21:45 +05304433 /* check the EXTScan Capability */
4434 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304435 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4436 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304437 {
4438 hddLog(VOS_TRACE_LEVEL_ERROR,
4439 FL("EXTScan not enabled/supported by Firmware"));
4440 return -EINVAL;
4441 }
4442
Dino Mycle6fb96c12014-06-10 11:52:40 +05304443 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4444 data, dataLen,
4445 wlan_hdd_extscan_config_policy)) {
4446 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4447 return -EINVAL;
4448 }
4449 /* Parse and fetch request Id */
4450 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4451 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4452 return -EINVAL;
4453 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304454
Dino Myclee8843b32014-07-04 14:21:45 +05304455 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304456 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4457
Dino Myclee8843b32014-07-04 14:21:45 +05304458 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304459
Dino Myclee8843b32014-07-04 14:21:45 +05304460 reqMsg.sessionId = pAdapter->sessionId;
4461 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304462
4463 /* Parse and fetch flush parameter */
4464 if (!tb
4465 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
4466 {
4467 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
4468 goto failed;
4469 }
Dino Myclee8843b32014-07-04 14:21:45 +05304470 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304471 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
4472
Dino Myclee8843b32014-07-04 14:21:45 +05304473 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304474
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304475 spin_lock(&hdd_context_lock);
4476 context = &pHddCtx->ext_scan_context;
4477 context->request_id = reqMsg.requestId;
4478 context->ignore_cached_results = false;
4479 INIT_COMPLETION(context->response_event);
4480 spin_unlock(&hdd_context_lock);
4481
Dino Myclee8843b32014-07-04 14:21:45 +05304482 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304483 if (!HAL_STATUS_SUCCESS(status)) {
4484 hddLog(VOS_TRACE_LEVEL_ERROR,
4485 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304486 return -EINVAL;
4487 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304488
4489 rc = wait_for_completion_timeout(&context->response_event,
4490 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4491 if (!rc) {
4492 hddLog(LOGE, FL("Target response timed out"));
4493 retval = -ETIMEDOUT;
4494 spin_lock(&hdd_context_lock);
4495 context->ignore_cached_results = true;
4496 spin_unlock(&hdd_context_lock);
4497 } else {
4498 spin_lock(&hdd_context_lock);
4499 retval = context->response_status;
4500 spin_unlock(&hdd_context_lock);
4501 }
4502
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304503 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304504 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304505
4506failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05304507 return -EINVAL;
4508}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304509static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4510 struct wireless_dev *wdev,
4511 const void *data, int dataLen)
4512{
4513 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304514
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304515 vos_ssr_protect(__func__);
4516 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
4517 vos_ssr_unprotect(__func__);
4518
4519 return ret;
4520}
4521
4522static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304523 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05304524 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304525{
4526 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
4527 struct net_device *dev = wdev->netdev;
4528 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4529 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4530 struct nlattr
4531 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4532 struct nlattr
4533 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4534 struct nlattr *apTh;
4535 eHalStatus status;
4536 tANI_U8 i = 0;
4537 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304538 struct hdd_ext_scan_context *context;
4539 tANI_U32 request_id;
4540 unsigned long rc;
4541 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304542
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304543 ENTER();
4544
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304545 if (VOS_FTM_MODE == hdd_get_conparam()) {
4546 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4547 return -EINVAL;
4548 }
4549
Dino Mycle6fb96c12014-06-10 11:52:40 +05304550 status = wlan_hdd_validate_context(pHddCtx);
4551 if (0 != status)
4552 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304553 return -EINVAL;
4554 }
Dino Myclee8843b32014-07-04 14:21:45 +05304555 /* check the EXTScan Capability */
4556 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304557 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4558 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304559 {
4560 hddLog(VOS_TRACE_LEVEL_ERROR,
4561 FL("EXTScan not enabled/supported by Firmware"));
4562 return -EINVAL;
4563 }
4564
Dino Mycle6fb96c12014-06-10 11:52:40 +05304565 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4566 data, dataLen,
4567 wlan_hdd_extscan_config_policy)) {
4568 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4569 return -EINVAL;
4570 }
4571
4572 /* Parse and fetch request Id */
4573 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4574 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4575 return -EINVAL;
4576 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304577 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4578 vos_mem_malloc(sizeof(*pReqMsg));
4579 if (!pReqMsg) {
4580 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4581 return -ENOMEM;
4582 }
4583
Dino Myclee8843b32014-07-04 14:21:45 +05304584
Dino Mycle6fb96c12014-06-10 11:52:40 +05304585 pReqMsg->requestId = nla_get_u32(
4586 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4587 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4588
4589 /* Parse and fetch number of APs */
4590 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4591 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4592 goto fail;
4593 }
4594
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304595 /* Parse and fetch lost ap sample size */
4596 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4597 hddLog(LOGE, FL("attr lost ap sample size failed"));
4598 goto fail;
4599 }
4600
4601 pReqMsg->lostBssidSampleSize = nla_get_u32(
4602 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4603 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4604
Dino Mycle6fb96c12014-06-10 11:52:40 +05304605 pReqMsg->sessionId = pAdapter->sessionId;
4606 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4607
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304608 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304609 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304610 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4611 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4612 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4613 goto fail;
4614 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304615 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304616
4617 nla_for_each_nested(apTh,
4618 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304619 if (i == pReqMsg->numBssid) {
4620 hddLog(LOGW, FL("Ignoring excess AP"));
4621 break;
4622 }
4623
Dino Mycle6fb96c12014-06-10 11:52:40 +05304624 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4625 nla_data(apTh), nla_len(apTh),
4626 NULL)) {
4627 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4628 goto fail;
4629 }
4630
4631 /* Parse and fetch MAC address */
4632 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4633 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4634 goto fail;
4635 }
4636 memcpy(pReqMsg->ap[i].bssid, nla_data(
4637 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4638 sizeof(tSirMacAddr));
4639 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4640
4641 /* Parse and fetch low RSSI */
4642 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4643 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4644 goto fail;
4645 }
4646 pReqMsg->ap[i].low = nla_get_s32(
4647 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4648 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4649
4650 /* Parse and fetch high RSSI */
4651 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4652 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4653 goto fail;
4654 }
4655 pReqMsg->ap[i].high = nla_get_s32(
4656 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4657 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4658 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304659 i++;
4660 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304661
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304662 if (i < pReqMsg->numBssid) {
4663 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4664 i, pReqMsg->numBssid);
4665 pReqMsg->numBssid = i;
4666 }
4667
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304668 context = &pHddCtx->ext_scan_context;
4669 spin_lock(&hdd_context_lock);
4670 INIT_COMPLETION(context->response_event);
4671 context->request_id = request_id = pReqMsg->requestId;
4672 spin_unlock(&hdd_context_lock);
4673
Dino Mycle6fb96c12014-06-10 11:52:40 +05304674 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4675 if (!HAL_STATUS_SUCCESS(status)) {
4676 hddLog(VOS_TRACE_LEVEL_ERROR,
4677 FL("sme_SetBssHotlist failed(err=%d)"), status);
4678 vos_mem_free(pReqMsg);
4679 return -EINVAL;
4680 }
4681
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304682 /* request was sent -- wait for the response */
4683 rc = wait_for_completion_timeout(&context->response_event,
4684 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4685
4686 if (!rc) {
4687 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4688 retval = -ETIMEDOUT;
4689 } else {
4690 spin_lock(&hdd_context_lock);
4691 if (context->request_id == request_id)
4692 retval = context->response_status;
4693 else
4694 retval = -EINVAL;
4695 spin_unlock(&hdd_context_lock);
4696 }
4697
Dino Myclee8843b32014-07-04 14:21:45 +05304698 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304699 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304700 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304701
4702fail:
4703 vos_mem_free(pReqMsg);
4704 return -EINVAL;
4705}
4706
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304707static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4708 struct wireless_dev *wdev,
4709 const void *data, int dataLen)
4710{
4711 int ret = 0;
4712
4713 vos_ssr_protect(__func__);
4714 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4715 dataLen);
4716 vos_ssr_unprotect(__func__);
4717
4718 return ret;
4719}
4720
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304721static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304722 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304723 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304724{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304725 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4726 struct net_device *dev = wdev->netdev;
4727 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4728 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4729 uint8_t num_channels = 0;
4730 uint8_t num_chan_new = 0;
4731 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304732 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304733 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304734 tWifiBand wifiBand;
4735 eHalStatus status;
4736 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304737 tANI_U8 i,j,k;
4738 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304739
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304740 ENTER();
4741
Dino Mycle6fb96c12014-06-10 11:52:40 +05304742 status = wlan_hdd_validate_context(pHddCtx);
4743 if (0 != status)
4744 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304745 return -EINVAL;
4746 }
Dino Myclee8843b32014-07-04 14:21:45 +05304747
Dino Mycle6fb96c12014-06-10 11:52:40 +05304748 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4749 data, dataLen,
4750 wlan_hdd_extscan_config_policy)) {
4751 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4752 return -EINVAL;
4753 }
4754
4755 /* Parse and fetch request Id */
4756 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4757 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4758 return -EINVAL;
4759 }
4760 requestId = nla_get_u32(
4761 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4762 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4763
4764 /* Parse and fetch wifi band */
4765 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4766 {
4767 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4768 return -EINVAL;
4769 }
4770 wifiBand = nla_get_u32(
4771 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4772 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4773
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304774 /* Parse and fetch max channels */
4775 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4776 {
4777 hddLog(LOGE, FL("attr max channels failed"));
4778 return -EINVAL;
4779 }
4780 maxChannels = nla_get_u32(
4781 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4782 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4783
Dino Mycle6fb96c12014-06-10 11:52:40 +05304784 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304785 wifiBand, chan_list,
4786 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304787 if (eHAL_STATUS_SUCCESS != status) {
4788 hddLog(VOS_TRACE_LEVEL_ERROR,
4789 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4790 return -EINVAL;
4791 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304792
Agrawal Ashish16abf782016-08-18 22:42:59 +05304793 num_channels = VOS_MIN(num_channels, maxChannels);
4794 num_chan_new = num_channels;
4795 /* remove the indoor only channels if iface is SAP */
4796 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4797 {
4798 num_chan_new = 0;
4799 for (i = 0; i < num_channels; i++)
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304800 for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) {
Agrawal Ashish16abf782016-08-18 22:42:59 +05304801 if (wiphy->bands[j] == NULL)
4802 continue;
4803 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4804 if ((chan_list[i] ==
4805 wiphy->bands[j]->channels[k].center_freq) &&
4806 (!(wiphy->bands[j]->channels[k].flags &
4807 IEEE80211_CHAN_INDOOR_ONLY))) {
4808 chan_list[num_chan_new] = chan_list[i];
4809 num_chan_new++;
4810 }
4811 }
4812 }
4813 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304814
Agrawal Ashish16abf782016-08-18 22:42:59 +05304815 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4816 for (i = 0; i < num_chan_new; i++)
4817 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4818 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304819
4820 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304821 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304822 NLMSG_HDRLEN);
4823
4824 if (!replySkb) {
4825 hddLog(VOS_TRACE_LEVEL_ERROR,
4826 FL("valid channels: buffer alloc fail"));
4827 return -EINVAL;
4828 }
4829 if (nla_put_u32(replySkb,
4830 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304831 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304832 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304833 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304834
4835 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4836 kfree_skb(replySkb);
4837 return -EINVAL;
4838 }
4839
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304840 ret = cfg80211_vendor_cmd_reply(replySkb);
4841
4842 EXIT();
4843 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304844}
4845
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304846static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4847 struct wireless_dev *wdev,
4848 const void *data, int dataLen)
4849{
4850 int ret = 0;
4851
4852 vos_ssr_protect(__func__);
4853 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4854 dataLen);
4855 vos_ssr_unprotect(__func__);
4856
4857 return ret;
4858}
4859
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304860static int hdd_extscan_start_fill_bucket_channel_spec(
4861 hdd_context_t *pHddCtx,
4862 tpSirEXTScanStartReqParams pReqMsg,
4863 struct nlattr **tb)
4864{
4865 struct nlattr *bucket[
4866 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4867 struct nlattr *channel[
4868 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4869 struct nlattr *buckets;
4870 struct nlattr *channels;
4871 int rem1, rem2;
4872 eHalStatus status;
4873 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304874 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304875 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4876 tANI_U32 passive_max_chn_time, active_max_chn_time;
4877
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304878 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304879 bktIndex = 0;
4880
4881 nla_for_each_nested(buckets,
4882 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304883 if (bktIndex >= expected_buckets) {
4884 hddLog(LOGW, FL("ignoring excess buckets"));
4885 break;
4886 }
4887
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304888 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304889 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4890 nla_data(buckets), nla_len(buckets),
4891 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304892 hddLog(LOGE, FL("nla_parse failed"));
4893 return -EINVAL;
4894 }
4895
4896 /* Parse and fetch bucket spec */
4897 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4898 hddLog(LOGE, FL("attr bucket index failed"));
4899 return -EINVAL;
4900 }
4901 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4902 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4903 hddLog(LOG1, FL("Bucket spec Index %d"),
4904 pReqMsg->buckets[bktIndex].bucket);
4905
4906 /* Parse and fetch wifi band */
4907 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4908 hddLog(LOGE, FL("attr wifi band failed"));
4909 return -EINVAL;
4910 }
4911 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4912 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4913 hddLog(LOG1, FL("Wifi band %d"),
4914 pReqMsg->buckets[bktIndex].band);
4915
4916 /* Parse and fetch period */
4917 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4918 hddLog(LOGE, FL("attr period failed"));
4919 return -EINVAL;
4920 }
4921 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4922 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4923 hddLog(LOG1, FL("period %d"),
4924 pReqMsg->buckets[bktIndex].period);
4925
4926 /* Parse and fetch report events */
4927 if (!bucket[
4928 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4929 hddLog(LOGE, FL("attr report events failed"));
4930 return -EINVAL;
4931 }
4932 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4933 bucket[
4934 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4935 hddLog(LOG1, FL("report events %d"),
4936 pReqMsg->buckets[bktIndex].reportEvents);
4937
4938 /* Parse and fetch max period */
4939 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4940 hddLog(LOGE, FL("attr max period failed"));
4941 return -EINVAL;
4942 }
4943 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4944 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4945 hddLog(LOG1, FL("max period %u"),
4946 pReqMsg->buckets[bktIndex].max_period);
4947
4948 /* Parse and fetch exponent */
4949 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4950 hddLog(LOGE, FL("attr exponent failed"));
4951 return -EINVAL;
4952 }
4953 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4954 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4955 hddLog(LOG1, FL("exponent %u"),
4956 pReqMsg->buckets[bktIndex].exponent);
4957
4958 /* Parse and fetch step count */
4959 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4960 hddLog(LOGE, FL("attr step count failed"));
4961 return -EINVAL;
4962 }
4963 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4964 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4965 hddLog(LOG1, FL("Step count %u"),
4966 pReqMsg->buckets[bktIndex].step_count);
4967
4968 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4969 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4970
4971 /* Framework shall pass the channel list if the input WiFi band is
4972 * WIFI_BAND_UNSPECIFIED.
4973 * If the input WiFi band is specified (any value other than
4974 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4975 */
4976 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4977 numChannels = 0;
4978 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4979 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4980 pReqMsg->buckets[bktIndex].band,
4981 chanList, &numChannels);
4982 if (!HAL_STATUS_SUCCESS(status)) {
4983 hddLog(LOGE,
4984 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4985 status);
4986 return -EINVAL;
4987 }
4988
4989 pReqMsg->buckets[bktIndex].numChannels =
4990 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4991 hddLog(LOG1, FL("Num channels %d"),
4992 pReqMsg->buckets[bktIndex].numChannels);
4993
4994 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4995 j++) {
4996 pReqMsg->buckets[bktIndex].channels[j].channel =
4997 chanList[j];
4998 pReqMsg->buckets[bktIndex].channels[j].
4999 chnlClass = 0;
5000 if (CSR_IS_CHANNEL_DFS(
5001 vos_freq_to_chan(chanList[j]))) {
5002 pReqMsg->buckets[bktIndex].channels[j].
5003 passive = 1;
5004 pReqMsg->buckets[bktIndex].channels[j].
5005 dwellTimeMs = passive_max_chn_time;
5006 } else {
5007 pReqMsg->buckets[bktIndex].channels[j].
5008 passive = 0;
5009 pReqMsg->buckets[bktIndex].channels[j].
5010 dwellTimeMs = active_max_chn_time;
5011 }
5012
5013 hddLog(LOG1,
5014 "Channel %u Passive %u Dwell time %u ms",
5015 pReqMsg->buckets[bktIndex].channels[j].channel,
5016 pReqMsg->buckets[bktIndex].channels[j].passive,
5017 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5018 }
5019
5020 bktIndex++;
5021 continue;
5022 }
5023
5024 /* Parse and fetch number of channels */
5025 if (!bucket[
5026 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
5027 hddLog(LOGE, FL("attr num channels failed"));
5028 return -EINVAL;
5029 }
5030
5031 pReqMsg->buckets[bktIndex].numChannels =
5032 nla_get_u32(bucket[
5033 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
5034 hddLog(LOG1, FL("num channels %d"),
5035 pReqMsg->buckets[bktIndex].numChannels);
5036
5037 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
5038 hddLog(LOGE, FL("attr channel spec failed"));
5039 return -EINVAL;
5040 }
5041
5042 j = 0;
5043 nla_for_each_nested(channels,
5044 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
5045 if (nla_parse(channel,
5046 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5047 nla_data(channels), nla_len(channels),
5048 wlan_hdd_extscan_config_policy)) {
5049 hddLog(LOGE, FL("nla_parse failed"));
5050 return -EINVAL;
5051 }
5052
5053 /* Parse and fetch channel */
5054 if (!channel[
5055 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
5056 hddLog(LOGE, FL("attr channel failed"));
5057 return -EINVAL;
5058 }
5059 pReqMsg->buckets[bktIndex].channels[j].channel =
5060 nla_get_u32(channel[
5061 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
5062 hddLog(LOG1, FL("channel %u"),
5063 pReqMsg->buckets[bktIndex].channels[j].channel);
5064
5065 /* Parse and fetch dwell time */
5066 if (!channel[
5067 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
5068 hddLog(LOGE, FL("attr dwelltime failed"));
5069 return -EINVAL;
5070 }
5071 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
5072 nla_get_u32(channel[
5073 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
5074
5075 hddLog(LOG1, FL("Dwell time (%u ms)"),
5076 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5077
5078
5079 /* Parse and fetch channel spec passive */
5080 if (!channel[
5081 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
5082 hddLog(LOGE,
5083 FL("attr channel spec passive failed"));
5084 return -EINVAL;
5085 }
5086 pReqMsg->buckets[bktIndex].channels[j].passive =
5087 nla_get_u8(channel[
5088 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
5089 hddLog(LOG1, FL("Chnl spec passive %u"),
5090 pReqMsg->buckets[bktIndex].channels[j].passive);
5091
5092 j++;
5093 }
5094
5095 bktIndex++;
5096 }
5097
5098 return 0;
5099}
5100
5101
5102/*
5103 * define short names for the global vendor params
5104 * used by wlan_hdd_cfg80211_extscan_start()
5105 */
5106#define PARAM_MAX \
5107QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
5108#define PARAM_REQUEST_ID \
5109QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
5110#define PARAM_BASE_PERIOD \
5111QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
5112#define PARAM_MAX_AP_PER_SCAN \
5113QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
5114#define PARAM_RPT_THRHLD_PERCENT \
5115QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
5116#define PARAM_RPT_THRHLD_NUM_SCANS \
5117QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
5118#define PARAM_NUM_BUCKETS \
5119QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
5120
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305121static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305122 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305123 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305124{
Dino Myclee8843b32014-07-04 14:21:45 +05305125 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305126 struct net_device *dev = wdev->netdev;
5127 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5128 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5129 struct nlattr *tb[PARAM_MAX + 1];
5130 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305131 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305132 tANI_U32 request_id;
5133 struct hdd_ext_scan_context *context;
5134 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305135
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305136 ENTER();
5137
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305138 if (VOS_FTM_MODE == hdd_get_conparam()) {
5139 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5140 return -EINVAL;
5141 }
5142
Dino Mycle6fb96c12014-06-10 11:52:40 +05305143 status = wlan_hdd_validate_context(pHddCtx);
5144 if (0 != status)
5145 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305146 return -EINVAL;
5147 }
Dino Myclee8843b32014-07-04 14:21:45 +05305148 /* check the EXTScan Capability */
5149 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305150 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5151 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305152 {
5153 hddLog(VOS_TRACE_LEVEL_ERROR,
5154 FL("EXTScan not enabled/supported by Firmware"));
5155 return -EINVAL;
5156 }
5157
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305158 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305159 data, dataLen,
5160 wlan_hdd_extscan_config_policy)) {
5161 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5162 return -EINVAL;
5163 }
5164
5165 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305166 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305167 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5168 return -EINVAL;
5169 }
5170
Dino Myclee8843b32014-07-04 14:21:45 +05305171 pReqMsg = (tpSirEXTScanStartReqParams)
5172 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305173 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305174 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5175 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305176 }
5177
5178 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305179 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305180 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5181
5182 pReqMsg->sessionId = pAdapter->sessionId;
5183 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5184
5185 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305186 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305187 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5188 goto fail;
5189 }
5190 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305191 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305192 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5193 pReqMsg->basePeriod);
5194
5195 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305196 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305197 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5198 goto fail;
5199 }
5200 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305201 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305202 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5203 pReqMsg->maxAPperScan);
5204
5205 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305206 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305207 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5208 goto fail;
5209 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305210 pReqMsg->reportThresholdPercent = nla_get_u8(
5211 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305212 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305213 pReqMsg->reportThresholdPercent);
5214
5215 /* Parse and fetch report threshold num scans */
5216 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5217 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5218 goto fail;
5219 }
5220 pReqMsg->reportThresholdNumScans = nla_get_u8(
5221 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5222 hddLog(LOG1, FL("Report Threshold num scans %d"),
5223 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305224
5225 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305226 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305227 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5228 goto fail;
5229 }
5230 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305231 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305232 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5233 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5234 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5235 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5236 }
5237 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5238 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305239
Dino Mycle6fb96c12014-06-10 11:52:40 +05305240 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5241 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5242 goto fail;
5243 }
5244
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305245 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305246
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305247 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5248 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305249
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305250 context = &pHddCtx->ext_scan_context;
5251 spin_lock(&hdd_context_lock);
5252 INIT_COMPLETION(context->response_event);
5253 context->request_id = request_id = pReqMsg->requestId;
5254 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305255
Dino Mycle6fb96c12014-06-10 11:52:40 +05305256 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5257 if (!HAL_STATUS_SUCCESS(status)) {
5258 hddLog(VOS_TRACE_LEVEL_ERROR,
5259 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305260 goto fail;
5261 }
5262
Srinivas Dasari91727c12016-03-23 17:59:06 +05305263 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5264
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305265 /* request was sent -- wait for the response */
5266 rc = wait_for_completion_timeout(&context->response_event,
5267 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5268
5269 if (!rc) {
5270 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5271 retval = -ETIMEDOUT;
5272 } else {
5273 spin_lock(&hdd_context_lock);
5274 if (context->request_id == request_id)
5275 retval = context->response_status;
5276 else
5277 retval = -EINVAL;
5278 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305279 }
5280
Dino Myclee8843b32014-07-04 14:21:45 +05305281 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305282 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305283 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305284
5285fail:
5286 vos_mem_free(pReqMsg);
5287 return -EINVAL;
5288}
5289
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305290/*
5291 * done with short names for the global vendor params
5292 * used by wlan_hdd_cfg80211_extscan_start()
5293 */
5294#undef PARAM_MAX
5295#undef PARAM_REQUEST_ID
5296#undef PARAM_BASE_PERIOD
5297#undef PARAMS_MAX_AP_PER_SCAN
5298#undef PARAMS_RPT_THRHLD_PERCENT
5299#undef PARAMS_RPT_THRHLD_NUM_SCANS
5300#undef PARAMS_NUM_BUCKETS
5301
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305302static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5303 struct wireless_dev *wdev,
5304 const void *data, int dataLen)
5305{
5306 int ret = 0;
5307
5308 vos_ssr_protect(__func__);
5309 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5310 vos_ssr_unprotect(__func__);
5311
5312 return ret;
5313}
5314
5315static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305316 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305317 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305318{
Dino Myclee8843b32014-07-04 14:21:45 +05305319 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305320 struct net_device *dev = wdev->netdev;
5321 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5322 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5323 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5324 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305325 int retval;
5326 unsigned long rc;
5327 struct hdd_ext_scan_context *context;
5328 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305329
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305330 ENTER();
5331
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305332 if (VOS_FTM_MODE == hdd_get_conparam()) {
5333 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5334 return -EINVAL;
5335 }
5336
Dino Mycle6fb96c12014-06-10 11:52:40 +05305337 status = wlan_hdd_validate_context(pHddCtx);
5338 if (0 != status)
5339 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305340 return -EINVAL;
5341 }
Dino Myclee8843b32014-07-04 14:21:45 +05305342 /* check the EXTScan Capability */
5343 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305344 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5345 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305346 {
5347 hddLog(VOS_TRACE_LEVEL_ERROR,
5348 FL("EXTScan not enabled/supported by Firmware"));
5349 return -EINVAL;
5350 }
5351
Dino Mycle6fb96c12014-06-10 11:52:40 +05305352 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5353 data, dataLen,
5354 wlan_hdd_extscan_config_policy)) {
5355 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5356 return -EINVAL;
5357 }
5358
5359 /* Parse and fetch request Id */
5360 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5361 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5362 return -EINVAL;
5363 }
5364
Dino Myclee8843b32014-07-04 14:21:45 +05305365 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305366 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305367 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305368
Dino Myclee8843b32014-07-04 14:21:45 +05305369 reqMsg.sessionId = pAdapter->sessionId;
5370 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305371
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305372 context = &pHddCtx->ext_scan_context;
5373 spin_lock(&hdd_context_lock);
5374 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305375 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305376 spin_unlock(&hdd_context_lock);
5377
Dino Myclee8843b32014-07-04 14:21:45 +05305378 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305379 if (!HAL_STATUS_SUCCESS(status)) {
5380 hddLog(VOS_TRACE_LEVEL_ERROR,
5381 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305382 return -EINVAL;
5383 }
5384
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305385 /* request was sent -- wait for the response */
5386 rc = wait_for_completion_timeout(&context->response_event,
5387 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5388
5389 if (!rc) {
5390 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5391 retval = -ETIMEDOUT;
5392 } else {
5393 spin_lock(&hdd_context_lock);
5394 if (context->request_id == request_id)
5395 retval = context->response_status;
5396 else
5397 retval = -EINVAL;
5398 spin_unlock(&hdd_context_lock);
5399 }
5400
5401 return retval;
5402
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305403 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305404 return 0;
5405}
5406
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305407static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5408 struct wireless_dev *wdev,
5409 const void *data, int dataLen)
5410{
5411 int ret = 0;
5412
5413 vos_ssr_protect(__func__);
5414 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5415 vos_ssr_unprotect(__func__);
5416
5417 return ret;
5418}
5419
5420static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305421 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305422 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305423{
Dino Myclee8843b32014-07-04 14:21:45 +05305424 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305425 struct net_device *dev = wdev->netdev;
5426 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5427 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5428 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5429 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305430 struct hdd_ext_scan_context *context;
5431 tANI_U32 request_id;
5432 unsigned long rc;
5433 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305434
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305435 ENTER();
5436
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305437 if (VOS_FTM_MODE == hdd_get_conparam()) {
5438 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5439 return -EINVAL;
5440 }
5441
Dino Mycle6fb96c12014-06-10 11:52:40 +05305442 status = wlan_hdd_validate_context(pHddCtx);
5443 if (0 != status)
5444 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305445 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305446 return -EINVAL;
5447 }
Dino Myclee8843b32014-07-04 14:21:45 +05305448 /* check the EXTScan Capability */
5449 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305450 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5451 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305452 {
5453 hddLog(VOS_TRACE_LEVEL_ERROR,
5454 FL("EXTScan not enabled/supported by Firmware"));
5455 return -EINVAL;
5456 }
5457
Dino Mycle6fb96c12014-06-10 11:52:40 +05305458 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5459 data, dataLen,
5460 wlan_hdd_extscan_config_policy)) {
5461 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5462 return -EINVAL;
5463 }
5464
5465 /* Parse and fetch request Id */
5466 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5467 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5468 return -EINVAL;
5469 }
5470
Dino Myclee8843b32014-07-04 14:21:45 +05305471 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305472 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305473 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305474
Dino Myclee8843b32014-07-04 14:21:45 +05305475 reqMsg.sessionId = pAdapter->sessionId;
5476 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305477
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305478 context = &pHddCtx->ext_scan_context;
5479 spin_lock(&hdd_context_lock);
5480 INIT_COMPLETION(context->response_event);
5481 context->request_id = request_id = reqMsg.requestId;
5482 spin_unlock(&hdd_context_lock);
5483
Dino Myclee8843b32014-07-04 14:21:45 +05305484 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305485 if (!HAL_STATUS_SUCCESS(status)) {
5486 hddLog(VOS_TRACE_LEVEL_ERROR,
5487 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305488 return -EINVAL;
5489 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305490
5491 /* request was sent -- wait for the response */
5492 rc = wait_for_completion_timeout(&context->response_event,
5493 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5494 if (!rc) {
5495 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5496 retval = -ETIMEDOUT;
5497 } else {
5498 spin_lock(&hdd_context_lock);
5499 if (context->request_id == request_id)
5500 retval = context->response_status;
5501 else
5502 retval = -EINVAL;
5503 spin_unlock(&hdd_context_lock);
5504 }
5505
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305506 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305507 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305508}
5509
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305510static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5511 struct wireless_dev *wdev,
5512 const void *data, int dataLen)
5513{
5514 int ret = 0;
5515
5516 vos_ssr_protect(__func__);
5517 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5518 vos_ssr_unprotect(__func__);
5519
5520 return ret;
5521}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305522#endif /* WLAN_FEATURE_EXTSCAN */
5523
Atul Mittal115287b2014-07-08 13:26:33 +05305524/*EXT TDLS*/
5525static const struct nla_policy
5526wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5527{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305528 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5529 .type = NLA_UNSPEC,
5530 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305531 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5532 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5533 {.type = NLA_S32 },
5534 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5535 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5536
5537};
5538
5539static const struct nla_policy
5540wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5541{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305542 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5543 .type = NLA_UNSPEC,
5544 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305545
5546};
5547
5548static const struct nla_policy
5549wlan_hdd_tdls_config_state_change_policy[
5550 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5551{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305552 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5553 .type = NLA_UNSPEC,
5554 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305555 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5556 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305557 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5558 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5559 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305560
5561};
5562
5563static const struct nla_policy
5564wlan_hdd_tdls_config_get_status_policy[
5565 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5566{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305567 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5568 .type = NLA_UNSPEC,
5569 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305570 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5571 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305572 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5573 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5574 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305575
5576};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305577
5578static const struct nla_policy
5579wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5580{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305581 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5582 .type = NLA_UNSPEC,
5583 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305584};
5585
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305586static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305587 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305588 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305589 int data_len)
5590{
5591
5592 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5593 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5594
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305595 ENTER();
5596
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305597 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305598 return -EINVAL;
5599 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305600 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305601 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305602 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305603 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305604 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305605 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305606 return -ENOTSUPP;
5607 }
5608
5609 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5610 data, data_len, wlan_hdd_mac_config)) {
5611 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5612 return -EINVAL;
5613 }
5614
5615 /* Parse and fetch mac address */
5616 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5618 return -EINVAL;
5619 }
5620
5621 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5622 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5623 VOS_MAC_ADDR_LAST_3_BYTES);
5624
Siddharth Bhal76972212014-10-15 16:22:51 +05305625 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5626
5627 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305628 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5629 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305630 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5631 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5632 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5633 {
5634 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5635 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5636 VOS_MAC_ADDRESS_LEN);
5637 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305638 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305639
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305640 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5641 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305642
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305643 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305644 return 0;
5645}
5646
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305647static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5648 struct wireless_dev *wdev,
5649 const void *data,
5650 int data_len)
5651{
5652 int ret = 0;
5653
5654 vos_ssr_protect(__func__);
5655 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5656 vos_ssr_unprotect(__func__);
5657
5658 return ret;
5659}
5660
5661static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305662 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305663 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305664 int data_len)
5665{
5666 u8 peer[6] = {0};
5667 struct net_device *dev = wdev->netdev;
5668 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5669 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5670 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5671 eHalStatus ret;
5672 tANI_S32 state;
5673 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305674 tANI_S32 global_operating_class = 0;
5675 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305676 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305677 int retVal;
5678
5679 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305680
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305681 if (!pAdapter) {
5682 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5683 return -EINVAL;
5684 }
5685
Atul Mittal115287b2014-07-08 13:26:33 +05305686 ret = wlan_hdd_validate_context(pHddCtx);
5687 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305688 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305689 return -EINVAL;
5690 }
5691 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305692 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305693 return -ENOTSUPP;
5694 }
5695 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5696 data, data_len,
5697 wlan_hdd_tdls_config_get_status_policy)) {
5698 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5699 return -EINVAL;
5700 }
5701
5702 /* Parse and fetch mac address */
5703 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5704 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5705 return -EINVAL;
5706 }
5707
5708 memcpy(peer, nla_data(
5709 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5710 sizeof(peer));
5711 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5712
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305713 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305714
Atul Mittal115287b2014-07-08 13:26:33 +05305715 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305716 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305717 NLMSG_HDRLEN);
5718
5719 if (!skb) {
5720 hddLog(VOS_TRACE_LEVEL_ERROR,
5721 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5722 return -EINVAL;
5723 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305724 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 +05305725 reason,
5726 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305727 global_operating_class,
5728 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305729 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305730 if (nla_put_s32(skb,
5731 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5732 state) ||
5733 nla_put_s32(skb,
5734 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5735 reason) ||
5736 nla_put_s32(skb,
5737 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5738 global_operating_class) ||
5739 nla_put_s32(skb,
5740 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5741 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305742
5743 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5744 goto nla_put_failure;
5745 }
5746
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305747 retVal = cfg80211_vendor_cmd_reply(skb);
5748 EXIT();
5749 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305750
5751nla_put_failure:
5752 kfree_skb(skb);
5753 return -EINVAL;
5754}
5755
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305756static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5757 struct wireless_dev *wdev,
5758 const void *data,
5759 int data_len)
5760{
5761 int ret = 0;
5762
5763 vos_ssr_protect(__func__);
5764 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5765 vos_ssr_unprotect(__func__);
5766
5767 return ret;
5768}
5769
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305770static int wlan_hdd_cfg80211_exttdls_callback(
5771#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5772 const tANI_U8* mac,
5773#else
5774 tANI_U8* mac,
5775#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305776 tANI_S32 state,
5777 tANI_S32 reason,
5778 void *ctx)
5779{
5780 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305781 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305782 tANI_S32 global_operating_class = 0;
5783 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305784 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305785
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305786 ENTER();
5787
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305788 if (!pAdapter) {
5789 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5790 return -EINVAL;
5791 }
5792
5793 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305794 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305795 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305796 return -EINVAL;
5797 }
5798
5799 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305801 return -ENOTSUPP;
5802 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305803 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5804#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5805 NULL,
5806#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305807 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5808 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5809 GFP_KERNEL);
5810
5811 if (!skb) {
5812 hddLog(VOS_TRACE_LEVEL_ERROR,
5813 FL("cfg80211_vendor_event_alloc failed"));
5814 return -EINVAL;
5815 }
5816 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305817 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5818 reason,
5819 state,
5820 global_operating_class,
5821 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305822 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5823 MAC_ADDR_ARRAY(mac));
5824
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305825 if (nla_put(skb,
5826 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5827 VOS_MAC_ADDR_SIZE, mac) ||
5828 nla_put_s32(skb,
5829 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5830 state) ||
5831 nla_put_s32(skb,
5832 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5833 reason) ||
5834 nla_put_s32(skb,
5835 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5836 channel) ||
5837 nla_put_s32(skb,
5838 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5839 global_operating_class)
5840 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305841 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5842 goto nla_put_failure;
5843 }
5844
5845 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305846 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305847 return (0);
5848
5849nla_put_failure:
5850 kfree_skb(skb);
5851 return -EINVAL;
5852}
5853
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305854static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305855 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305856 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305857 int data_len)
5858{
5859 u8 peer[6] = {0};
5860 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305861 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5862 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5863 eHalStatus status;
5864 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305865 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305866 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305867
5868 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305869
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305870 if (!dev) {
5871 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5872 return -EINVAL;
5873 }
5874
5875 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5876 if (!pAdapter) {
5877 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5878 return -EINVAL;
5879 }
5880
Atul Mittal115287b2014-07-08 13:26:33 +05305881 status = wlan_hdd_validate_context(pHddCtx);
5882 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305884 return -EINVAL;
5885 }
5886 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305888 return -ENOTSUPP;
5889 }
5890 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5891 data, data_len,
5892 wlan_hdd_tdls_config_enable_policy)) {
5893 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5894 return -EINVAL;
5895 }
5896
5897 /* Parse and fetch mac address */
5898 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5899 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5900 return -EINVAL;
5901 }
5902
5903 memcpy(peer, nla_data(
5904 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5905 sizeof(peer));
5906 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5907
5908 /* Parse and fetch channel */
5909 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5910 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5911 return -EINVAL;
5912 }
5913 pReqMsg.channel = nla_get_s32(
5914 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5915 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5916
5917 /* Parse and fetch global operating class */
5918 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5919 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5920 return -EINVAL;
5921 }
5922 pReqMsg.global_operating_class = nla_get_s32(
5923 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5924 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5925 pReqMsg.global_operating_class);
5926
5927 /* Parse and fetch latency ms */
5928 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5929 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5930 return -EINVAL;
5931 }
5932 pReqMsg.max_latency_ms = nla_get_s32(
5933 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5934 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5935 pReqMsg.max_latency_ms);
5936
5937 /* Parse and fetch required bandwidth kbps */
5938 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5939 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5940 return -EINVAL;
5941 }
5942
5943 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5944 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5945 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5946 pReqMsg.min_bandwidth_kbps);
5947
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305948 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305949 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305950 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305951 wlan_hdd_cfg80211_exttdls_callback);
5952
5953 EXIT();
5954 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305955}
5956
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305957static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5958 struct wireless_dev *wdev,
5959 const void *data,
5960 int data_len)
5961{
5962 int ret = 0;
5963
5964 vos_ssr_protect(__func__);
5965 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5966 vos_ssr_unprotect(__func__);
5967
5968 return ret;
5969}
5970
5971static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305972 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305973 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305974 int data_len)
5975{
5976 u8 peer[6] = {0};
5977 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305978 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5979 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5980 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305981 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305982 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305983
5984 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305985
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305986 if (!dev) {
5987 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5988 return -EINVAL;
5989 }
5990
5991 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5992 if (!pAdapter) {
5993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5994 return -EINVAL;
5995 }
5996
Atul Mittal115287b2014-07-08 13:26:33 +05305997 status = wlan_hdd_validate_context(pHddCtx);
5998 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305999 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05306000 return -EINVAL;
6001 }
6002 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05306003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05306004 return -ENOTSUPP;
6005 }
6006 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
6007 data, data_len,
6008 wlan_hdd_tdls_config_disable_policy)) {
6009 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6010 return -EINVAL;
6011 }
6012 /* Parse and fetch mac address */
6013 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
6014 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
6015 return -EINVAL;
6016 }
6017
6018 memcpy(peer, nla_data(
6019 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
6020 sizeof(peer));
6021 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
6022
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306023 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
6024
6025 EXIT();
6026 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05306027}
6028
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306029static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
6030 struct wireless_dev *wdev,
6031 const void *data,
6032 int data_len)
6033{
6034 int ret = 0;
6035
6036 vos_ssr_protect(__func__);
6037 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
6038 vos_ssr_unprotect(__func__);
6039
6040 return ret;
6041}
6042
Dasari Srinivas7875a302014-09-26 17:50:57 +05306043static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306044__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05306045 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306046 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05306047{
6048 struct net_device *dev = wdev->netdev;
6049 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6050 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6051 struct sk_buff *skb = NULL;
6052 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306053 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306054
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306055 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306056
6057 ret = wlan_hdd_validate_context(pHddCtx);
6058 if (0 != ret)
6059 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306060 return ret;
6061 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306062 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
6063 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
6064 fset |= WIFI_FEATURE_INFRA;
6065 }
6066
6067 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
6068 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
6069 fset |= WIFI_FEATURE_INFRA_5G;
6070 }
6071
6072#ifdef WLAN_FEATURE_P2P
6073 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
6074 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
6075 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
6076 fset |= WIFI_FEATURE_P2P;
6077 }
6078#endif
6079
6080 /* Soft-AP is supported currently by default */
6081 fset |= WIFI_FEATURE_SOFT_AP;
6082
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05306083 /* HOTSPOT is a supplicant feature, enable it by default */
6084 fset |= WIFI_FEATURE_HOTSPOT;
6085
Dasari Srinivas7875a302014-09-26 17:50:57 +05306086#ifdef WLAN_FEATURE_EXTSCAN
6087 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05306088 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
6089 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
6090 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306091 fset |= WIFI_FEATURE_EXTSCAN;
6092 }
6093#endif
6094
Dasari Srinivas7875a302014-09-26 17:50:57 +05306095 if (sme_IsFeatureSupportedByFW(NAN)) {
6096 hddLog(LOG1, FL("NAN is supported by firmware"));
6097 fset |= WIFI_FEATURE_NAN;
6098 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306099
6100 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05306101 if (sme_IsFeatureSupportedByFW(RTT) &&
6102 pHddCtx->cfg_ini->enable_rtt_support) {
6103 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306104 fset |= WIFI_FEATURE_D2AP_RTT;
6105 }
6106
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05306107 if (sme_IsFeatureSupportedByFW(RTT3)) {
6108 hddLog(LOG1, FL("RTT3 is supported by firmware"));
6109 fset |= WIFI_FEATURE_RTT3;
6110 }
6111
Dasari Srinivas7875a302014-09-26 17:50:57 +05306112#ifdef FEATURE_WLAN_BATCH_SCAN
6113 if (fset & WIFI_FEATURE_EXTSCAN) {
6114 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
6115 fset &= ~WIFI_FEATURE_BATCH_SCAN;
6116 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
6117 hddLog(LOG1, FL("Batch scan is supported by firmware"));
6118 fset |= WIFI_FEATURE_BATCH_SCAN;
6119 }
6120#endif
6121
6122#ifdef FEATURE_WLAN_SCAN_PNO
6123 if (pHddCtx->cfg_ini->configPNOScanSupport &&
6124 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
6125 hddLog(LOG1, FL("PNO is supported by firmware"));
6126 fset |= WIFI_FEATURE_PNO;
6127 }
6128#endif
6129
6130 /* STA+STA is supported currently by default */
6131 fset |= WIFI_FEATURE_ADDITIONAL_STA;
6132
6133#ifdef FEATURE_WLAN_TDLS
6134 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6135 sme_IsFeatureSupportedByFW(TDLS)) {
6136 hddLog(LOG1, FL("TDLS is supported by firmware"));
6137 fset |= WIFI_FEATURE_TDLS;
6138 }
6139
6140 /* TDLS_OFFCHANNEL is not supported currently by default */
6141#endif
6142
6143#ifdef WLAN_AP_STA_CONCURRENCY
6144 /* AP+STA concurrency is supported currently by default */
6145 fset |= WIFI_FEATURE_AP_STA;
6146#endif
6147
Mukul Sharma5add0532015-08-17 15:57:47 +05306148#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306149 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6150 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306151 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6152 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306153 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306154#endif
6155
Dasari Srinivas7875a302014-09-26 17:50:57 +05306156 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6157 NLMSG_HDRLEN);
6158
6159 if (!skb) {
6160 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6161 return -EINVAL;
6162 }
6163 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6164
6165 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6166 hddLog(LOGE, FL("nla put fail"));
6167 goto nla_put_failure;
6168 }
6169
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306170 ret = cfg80211_vendor_cmd_reply(skb);
6171 EXIT();
6172 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306173
6174nla_put_failure:
6175 kfree_skb(skb);
6176 return -EINVAL;
6177}
6178
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306179static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306180wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6181 struct wireless_dev *wdev,
6182 const void *data, int data_len)
6183{
6184 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306185 vos_ssr_protect(__func__);
6186 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6187 vos_ssr_unprotect(__func__);
6188
6189 return ret;
6190}
6191
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306192
6193static const struct
6194nla_policy
6195qca_wlan_vendor_wifi_logger_get_ring_data_policy
6196[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6197 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6198 = {.type = NLA_U32 },
6199};
6200
6201static int
6202 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6203 struct wireless_dev *wdev,
6204 const void *data,
6205 int data_len)
6206{
6207 int ret;
6208 VOS_STATUS status;
6209 uint32_t ring_id;
6210 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6211 struct nlattr *tb
6212 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6213
6214 ENTER();
6215
6216 ret = wlan_hdd_validate_context(hdd_ctx);
6217 if (0 != ret) {
6218 return ret;
6219 }
6220
6221 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6222 data, data_len,
6223 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6224 hddLog(LOGE, FL("Invalid attribute"));
6225 return -EINVAL;
6226 }
6227
6228 /* Parse and fetch ring id */
6229 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6230 hddLog(LOGE, FL("attr ATTR failed"));
6231 return -EINVAL;
6232 }
6233
6234 ring_id = nla_get_u32(
6235 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6236
6237 hddLog(LOG1, FL("Bug report triggered by framework"));
6238
6239 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6240 WLAN_LOG_INDICATOR_FRAMEWORK,
6241 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306242 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306243 );
6244 if (VOS_STATUS_SUCCESS != status) {
6245 hddLog(LOGE, FL("Failed to trigger bug report"));
6246
6247 return -EINVAL;
6248 }
6249
6250 return 0;
6251
6252
6253}
6254
6255
6256static int
6257 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6258 struct wireless_dev *wdev,
6259 const void *data,
6260 int data_len)
6261{
6262 int ret = 0;
6263
6264 vos_ssr_protect(__func__);
6265 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6266 wdev, data, data_len);
6267 vos_ssr_unprotect(__func__);
6268
6269 return ret;
6270
6271}
6272
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306273#define MAX_CONCURRENT_MATRIX \
6274 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6275#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6276 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6277static const struct nla_policy
6278wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6279 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6280};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306281
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306282static int
6283__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306284 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306285 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306286{
6287 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6288 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306289 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306290 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306291 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6292 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306293
6294 ENTER();
6295
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306296 ret = wlan_hdd_validate_context(pHddCtx);
6297 if (0 != ret)
6298 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306299 return ret;
6300 }
6301
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306302 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6303 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306304 hddLog(LOGE, FL("Invalid ATTR"));
6305 return -EINVAL;
6306 }
6307
6308 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306309 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306310 hddLog(LOGE, FL("Attr max feature set size failed"));
6311 return -EINVAL;
6312 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306313 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306314 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6315
6316 /* Fill feature combination matrix */
6317 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306318 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6319 WIFI_FEATURE_P2P;
6320
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306321 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6322 WIFI_FEATURE_SOFT_AP;
6323
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306324 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6325 WIFI_FEATURE_SOFT_AP;
6326
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306327 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6328 WIFI_FEATURE_SOFT_AP |
6329 WIFI_FEATURE_P2P;
6330
6331 /* Add more feature combinations here */
6332
6333 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6334 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6335 hddLog(LOG1, "Feature set matrix");
6336 for (i = 0; i < feature_sets; i++)
6337 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6338
6339 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6340 sizeof(u32) * feature_sets +
6341 NLMSG_HDRLEN);
6342
6343 if (reply_skb) {
6344 if (nla_put_u32(reply_skb,
6345 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6346 feature_sets) ||
6347 nla_put(reply_skb,
6348 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6349 sizeof(u32) * feature_sets, feature_set_matrix)) {
6350 hddLog(LOGE, FL("nla put fail"));
6351 kfree_skb(reply_skb);
6352 return -EINVAL;
6353 }
6354
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306355 ret = cfg80211_vendor_cmd_reply(reply_skb);
6356 EXIT();
6357 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306358 }
6359 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6360 return -ENOMEM;
6361
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306362}
6363
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306364#undef MAX_CONCURRENT_MATRIX
6365#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6366
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306367static int
6368wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6369 struct wireless_dev *wdev,
6370 const void *data, int data_len)
6371{
6372 int ret = 0;
6373
6374 vos_ssr_protect(__func__);
6375 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6376 data_len);
6377 vos_ssr_unprotect(__func__);
6378
6379 return ret;
6380}
6381
c_manjeecfd1efb2015-09-25 19:32:34 +05306382
6383static int
6384__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6385 struct wireless_dev *wdev,
6386 const void *data, int data_len)
6387{
6388 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6389 int ret;
6390 ENTER();
6391
6392 ret = wlan_hdd_validate_context(pHddCtx);
6393 if (0 != ret)
6394 {
6395 return ret;
6396 }
6397
6398 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6399 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6400 {
6401 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306402 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306403 }
6404 /*call common API for FW mem dump req*/
6405 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6406
Abhishek Singhc783fa72015-12-09 18:07:34 +05306407 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306408 {
6409 /*indicate to userspace the status of fw mem dump */
6410 wlan_indicate_mem_dump_complete(true);
6411 }
6412 else
6413 {
6414 /*else send failure to userspace */
6415 wlan_indicate_mem_dump_complete(false);
6416 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306417 EXIT();
6418 return ret;
6419}
6420
6421/**
6422 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6423 * @wiphy: pointer to wireless wiphy structure.
6424 * @wdev: pointer to wireless_dev structure.
6425 * @data: Pointer to the NL data.
6426 * @data_len:Length of @data
6427 *
6428 * This is called when wlan driver needs to get the firmware memory dump
6429 * via vendor specific command.
6430 *
6431 * Return: 0 on success, error number otherwise.
6432 */
6433
6434static int
6435wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6436 struct wireless_dev *wdev,
6437 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306438{
6439 int ret = 0;
6440 vos_ssr_protect(__func__);
6441 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6442 data_len);
6443 vos_ssr_unprotect(__func__);
6444 return ret;
6445}
c_manjeecfd1efb2015-09-25 19:32:34 +05306446
Sushant Kaushik8e644982015-09-23 12:18:54 +05306447static const struct
6448nla_policy
6449qca_wlan_vendor_wifi_logger_start_policy
6450[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6451 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6452 = {.type = NLA_U32 },
6453 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6454 = {.type = NLA_U32 },
6455 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6456 = {.type = NLA_U32 },
6457};
6458
6459/**
6460 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6461 * or disable the collection of packet statistics from the firmware
6462 * @wiphy: WIPHY structure pointer
6463 * @wdev: Wireless device structure pointer
6464 * @data: Pointer to the data received
6465 * @data_len: Length of the data received
6466 *
6467 * This function is used to enable or disable the collection of packet
6468 * statistics from the firmware
6469 *
6470 * Return: 0 on success and errno on failure
6471 */
6472static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6473 struct wireless_dev *wdev,
6474 const void *data,
6475 int data_len)
6476{
6477 eHalStatus status;
6478 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6479 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6480 tAniWifiStartLog start_log;
6481
6482 status = wlan_hdd_validate_context(hdd_ctx);
6483 if (0 != status) {
6484 return -EINVAL;
6485 }
6486
6487 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6488 data, data_len,
6489 qca_wlan_vendor_wifi_logger_start_policy)) {
6490 hddLog(LOGE, FL("Invalid attribute"));
6491 return -EINVAL;
6492 }
6493
6494 /* Parse and fetch ring id */
6495 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6496 hddLog(LOGE, FL("attr ATTR failed"));
6497 return -EINVAL;
6498 }
6499 start_log.ringId = nla_get_u32(
6500 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6501 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6502
6503 /* Parse and fetch verbose level */
6504 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6505 hddLog(LOGE, FL("attr verbose_level failed"));
6506 return -EINVAL;
6507 }
6508 start_log.verboseLevel = nla_get_u32(
6509 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6510 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6511
6512 /* Parse and fetch flag */
6513 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6514 hddLog(LOGE, FL("attr flag failed"));
6515 return -EINVAL;
6516 }
6517 start_log.flag = nla_get_u32(
6518 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6519 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6520
6521 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306522 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6523 !vos_isPktStatsEnabled()))
6524
Sushant Kaushik8e644982015-09-23 12:18:54 +05306525 {
6526 hddLog(LOGE, FL("per pkt stats not enabled"));
6527 return -EINVAL;
6528 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306529
Sushant Kaushik33200572015-08-05 16:46:20 +05306530 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306531 return 0;
6532}
6533
6534/**
6535 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6536 * or disable the collection of packet statistics from the firmware
6537 * @wiphy: WIPHY structure pointer
6538 * @wdev: Wireless device structure pointer
6539 * @data: Pointer to the data received
6540 * @data_len: Length of the data received
6541 *
6542 * This function is used to enable or disable the collection of packet
6543 * statistics from the firmware
6544 *
6545 * Return: 0 on success and errno on failure
6546 */
6547static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6548 struct wireless_dev *wdev,
6549 const void *data,
6550 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306551{
6552 int ret = 0;
6553
6554 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306555
6556 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6557 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306558 vos_ssr_unprotect(__func__);
6559
6560 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306561}
6562
6563
Agarwal Ashish738843c2014-09-25 12:27:56 +05306564static const struct nla_policy
6565wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6566 +1] =
6567{
6568 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6569};
6570
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306571static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306572 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306573 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306574 int data_len)
6575{
6576 struct net_device *dev = wdev->netdev;
6577 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6578 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6579 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6580 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6581 eHalStatus status;
6582 u32 dfsFlag = 0;
6583
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306584 ENTER();
6585
Agarwal Ashish738843c2014-09-25 12:27:56 +05306586 status = wlan_hdd_validate_context(pHddCtx);
6587 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306588 return -EINVAL;
6589 }
6590 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6591 data, data_len,
6592 wlan_hdd_set_no_dfs_flag_config_policy)) {
6593 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6594 return -EINVAL;
6595 }
6596
6597 /* Parse and fetch required bandwidth kbps */
6598 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6599 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6600 return -EINVAL;
6601 }
6602
6603 dfsFlag = nla_get_u32(
6604 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6605 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6606 dfsFlag);
6607
6608 pHddCtx->disable_dfs_flag = dfsFlag;
6609
6610 sme_disable_dfs_channel(hHal, dfsFlag);
6611 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306612
6613 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306614 return 0;
6615}
Atul Mittal115287b2014-07-08 13:26:33 +05306616
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306617static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6618 struct wireless_dev *wdev,
6619 const void *data,
6620 int data_len)
6621{
6622 int ret = 0;
6623
6624 vos_ssr_protect(__func__);
6625 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6626 vos_ssr_unprotect(__func__);
6627
6628 return ret;
6629
6630}
6631
Mukul Sharma2a271632014-10-13 14:59:01 +05306632const struct
6633nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6634{
6635 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306636 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6637 .type = NLA_UNSPEC,
6638 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306639};
6640
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306641static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306642 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306643{
6644
6645 u8 bssid[6] = {0};
6646 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6647 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6648 eHalStatus status = eHAL_STATUS_SUCCESS;
6649 v_U32_t isFwrRoamEnabled = FALSE;
6650 int ret;
6651
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306652 ENTER();
6653
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306654 ret = wlan_hdd_validate_context(pHddCtx);
6655 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306656 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306657 }
6658
6659 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6660 data, data_len,
6661 qca_wlan_vendor_attr);
6662 if (ret){
6663 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6664 return -EINVAL;
6665 }
6666
6667 /* Parse and fetch Enable flag */
6668 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6669 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6670 return -EINVAL;
6671 }
6672
6673 isFwrRoamEnabled = nla_get_u32(
6674 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6675
6676 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6677
6678 /* Parse and fetch bssid */
6679 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6680 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6681 return -EINVAL;
6682 }
6683
6684 memcpy(bssid, nla_data(
6685 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6686 sizeof(bssid));
6687 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6688
6689 //Update roaming
6690 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306691 if (!HAL_STATUS_SUCCESS(status)) {
6692 hddLog(LOGE,
6693 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6694 return -EINVAL;
6695 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306696 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306697 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306698}
6699
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306700static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6701 struct wireless_dev *wdev, const void *data, int data_len)
6702{
6703 int ret = 0;
6704
6705 vos_ssr_protect(__func__);
6706 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6707 vos_ssr_unprotect(__func__);
6708
6709 return ret;
6710}
6711
Sushant Kaushik847890c2015-09-28 16:05:17 +05306712static const struct
6713nla_policy
6714qca_wlan_vendor_get_wifi_info_policy[
6715 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6716 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6717 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6718};
6719
6720
6721/**
6722 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6723 * @wiphy: pointer to wireless wiphy structure.
6724 * @wdev: pointer to wireless_dev structure.
6725 * @data: Pointer to the data to be passed via vendor interface
6726 * @data_len:Length of the data to be passed
6727 *
6728 * This is called when wlan driver needs to send wifi driver related info
6729 * (driver/fw version) to the user space application upon request.
6730 *
6731 * Return: Return the Success or Failure code.
6732 */
6733static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6734 struct wireless_dev *wdev,
6735 const void *data, int data_len)
6736{
6737 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6738 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6739 tSirVersionString version;
6740 uint32 version_len;
6741 uint8 attr;
6742 int status;
6743 struct sk_buff *reply_skb = NULL;
6744
6745 if (VOS_FTM_MODE == hdd_get_conparam()) {
6746 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6747 return -EINVAL;
6748 }
6749
6750 status = wlan_hdd_validate_context(hdd_ctx);
6751 if (0 != status) {
6752 hddLog(LOGE, FL("HDD context is not valid"));
6753 return -EINVAL;
6754 }
6755
6756 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6757 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6758 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6759 return -EINVAL;
6760 }
6761
6762 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6763 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6764 QWLAN_VERSIONSTR);
6765 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6766 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6767 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6768 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6769 hdd_ctx->fw_Version);
6770 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6771 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6772 } else {
6773 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6774 return -EINVAL;
6775 }
6776
6777 version_len = strlen(version);
6778 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6779 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6780 if (!reply_skb) {
6781 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6782 return -ENOMEM;
6783 }
6784
6785 if (nla_put(reply_skb, attr, version_len, version)) {
6786 hddLog(LOGE, FL("nla put fail"));
6787 kfree_skb(reply_skb);
6788 return -EINVAL;
6789 }
6790
6791 return cfg80211_vendor_cmd_reply(reply_skb);
6792}
6793
6794/**
6795 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6796 * @wiphy: pointer to wireless wiphy structure.
6797 * @wdev: pointer to wireless_dev structure.
6798 * @data: Pointer to the data to be passed via vendor interface
6799 * @data_len:Length of the data to be passed
6800 * @data_len: Length of the data received
6801 *
6802 * This function is used to enable or disable the collection of packet
6803 * statistics from the firmware
6804 *
6805 * Return: 0 on success and errno on failure
6806 */
6807
6808static int
6809wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6810 struct wireless_dev *wdev,
6811 const void *data, int data_len)
6812
6813
6814{
6815 int ret = 0;
6816
6817 vos_ssr_protect(__func__);
6818 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6819 wdev, data, data_len);
6820 vos_ssr_unprotect(__func__);
6821
6822 return ret;
6823}
6824
6825
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306826/*
6827 * define short names for the global vendor params
6828 * used by __wlan_hdd_cfg80211_monitor_rssi()
6829 */
6830#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6831#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6832#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6833#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6834#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6835
6836/**---------------------------------------------------------------------------
6837
6838 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6839 monitor start is completed successfully.
6840
6841 \return - None
6842
6843 --------------------------------------------------------------------------*/
6844void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6845{
6846 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6847
6848 if (NULL == pHddCtx)
6849 {
6850 hddLog(VOS_TRACE_LEVEL_ERROR,
6851 "%s: HDD context is NULL",__func__);
6852 return;
6853 }
6854
6855 if (VOS_STATUS_SUCCESS == status)
6856 {
6857 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6858 }
6859 else
6860 {
6861 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6862 }
6863
6864 return;
6865}
6866
6867/**---------------------------------------------------------------------------
6868
6869 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6870 stop is completed successfully.
6871
6872 \return - None
6873
6874 --------------------------------------------------------------------------*/
6875void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6876{
6877 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6878
6879 if (NULL == pHddCtx)
6880 {
6881 hddLog(VOS_TRACE_LEVEL_ERROR,
6882 "%s: HDD context is NULL",__func__);
6883 return;
6884 }
6885
6886 if (VOS_STATUS_SUCCESS == status)
6887 {
6888 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6889 }
6890 else
6891 {
6892 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6893 }
6894
6895 return;
6896}
6897
6898/**
6899 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6900 * @wiphy: Pointer to wireless phy
6901 * @wdev: Pointer to wireless device
6902 * @data: Pointer to data
6903 * @data_len: Data length
6904 *
6905 * Return: 0 on success, negative errno on failure
6906 */
6907
6908static int
6909__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6910 struct wireless_dev *wdev,
6911 const void *data,
6912 int data_len)
6913{
6914 struct net_device *dev = wdev->netdev;
6915 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6916 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6917 hdd_station_ctx_t *pHddStaCtx;
6918 struct nlattr *tb[PARAM_MAX + 1];
6919 tpSirRssiMonitorReq pReq;
6920 eHalStatus status;
6921 int ret;
6922 uint32_t control;
6923 static const struct nla_policy policy[PARAM_MAX + 1] = {
6924 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6925 [PARAM_CONTROL] = { .type = NLA_U32 },
6926 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6927 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6928 };
6929
6930 ENTER();
6931
6932 ret = wlan_hdd_validate_context(hdd_ctx);
6933 if (0 != ret) {
6934 return -EINVAL;
6935 }
6936
6937 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6938 hddLog(LOGE, FL("Not in Connected state!"));
6939 return -ENOTSUPP;
6940 }
6941
6942 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6943 hddLog(LOGE, FL("Invalid ATTR"));
6944 return -EINVAL;
6945 }
6946
6947 if (!tb[PARAM_REQUEST_ID]) {
6948 hddLog(LOGE, FL("attr request id failed"));
6949 return -EINVAL;
6950 }
6951
6952 if (!tb[PARAM_CONTROL]) {
6953 hddLog(LOGE, FL("attr control failed"));
6954 return -EINVAL;
6955 }
6956
6957 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6958
6959 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6960 if(NULL == pReq)
6961 {
6962 hddLog(LOGE,
6963 FL("vos_mem_alloc failed "));
6964 return eHAL_STATUS_FAILED_ALLOC;
6965 }
6966 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6967
6968 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6969 pReq->sessionId = pAdapter->sessionId;
6970 pReq->rssiMonitorCbContext = hdd_ctx;
6971 control = nla_get_u32(tb[PARAM_CONTROL]);
6972 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6973
6974 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6975 pReq->requestId, pReq->sessionId, control);
6976
6977 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6978 if (!tb[PARAM_MIN_RSSI]) {
6979 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306980 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306981 }
6982
6983 if (!tb[PARAM_MAX_RSSI]) {
6984 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306985 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306986 }
6987
6988 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6989 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6990 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6991
6992 if (!(pReq->minRssi < pReq->maxRssi)) {
6993 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6994 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306995 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306996 }
6997 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6998 pReq->minRssi, pReq->maxRssi);
6999 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
7000
7001 }
7002 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
7003 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
7004 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
7005 }
7006 else {
7007 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307008 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307009 }
7010
7011 if (!HAL_STATUS_SUCCESS(status)) {
7012 hddLog(LOGE,
7013 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307014 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307015 }
7016
7017 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307018fail:
7019 vos_mem_free(pReq);
7020 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307021}
7022
7023/*
7024 * done with short names for the global vendor params
7025 * used by __wlan_hdd_cfg80211_monitor_rssi()
7026 */
7027#undef PARAM_MAX
7028#undef PARAM_CONTROL
7029#undef PARAM_REQUEST_ID
7030#undef PARAM_MAX_RSSI
7031#undef PARAM_MIN_RSSI
7032
7033/**
7034 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
7035 * @wiphy: wiphy structure pointer
7036 * @wdev: Wireless device structure pointer
7037 * @data: Pointer to the data received
7038 * @data_len: Length of @data
7039 *
7040 * Return: 0 on success; errno on failure
7041 */
7042static int
7043wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
7044 const void *data, int data_len)
7045{
7046 int ret;
7047
7048 vos_ssr_protect(__func__);
7049 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
7050 vos_ssr_unprotect(__func__);
7051
7052 return ret;
7053}
7054
7055/**
7056 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
7057 * @hddctx: HDD context
7058 * @data: rssi breached event data
7059 *
7060 * This function reads the rssi breached event %data and fill in the skb with
7061 * NL attributes and send up the NL event.
7062 * This callback execute in atomic context and must not invoke any
7063 * blocking calls.
7064 *
7065 * Return: none
7066 */
7067void hdd_rssi_threshold_breached_cb(void *hddctx,
7068 struct rssi_breach_event *data)
7069{
7070 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
7071 int status;
7072 struct sk_buff *skb;
7073
7074 ENTER();
7075 status = wlan_hdd_validate_context(pHddCtx);
7076
7077 if (0 != status) {
7078 return;
7079 }
7080
7081 if (!data) {
7082 hddLog(LOGE, FL("data is null"));
7083 return;
7084 }
7085
7086 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
7087#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7088 NULL,
7089#endif
7090 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
7091 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
7092 GFP_KERNEL);
7093
7094 if (!skb) {
7095 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
7096 return;
7097 }
7098
7099 hddLog(LOG1, "Req Id: %u Current rssi: %d",
7100 data->request_id, data->curr_rssi);
7101 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
7102 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
7103
7104 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
7105 data->request_id) ||
7106 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
7107 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
7108 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
7109 data->curr_rssi)) {
7110 hddLog(LOGE, FL("nla put fail"));
7111 goto fail;
7112 }
7113
7114 cfg80211_vendor_event(skb, GFP_KERNEL);
7115 return;
7116
7117fail:
7118 kfree_skb(skb);
7119 return;
7120}
7121
7122
7123
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307124/**
7125 * __wlan_hdd_cfg80211_setband() - set band
7126 * @wiphy: Pointer to wireless phy
7127 * @wdev: Pointer to wireless device
7128 * @data: Pointer to data
7129 * @data_len: Data length
7130 *
7131 * Return: 0 on success, negative errno on failure
7132 */
7133static int
7134__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7135 struct wireless_dev *wdev,
7136 const void *data,
7137 int data_len)
7138{
7139 struct net_device *dev = wdev->netdev;
7140 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7141 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7142 int ret;
7143 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7144 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7145
7146 ENTER();
7147
7148 ret = wlan_hdd_validate_context(hdd_ctx);
7149 if (0 != ret) {
7150 hddLog(LOGE, FL("HDD context is not valid"));
7151 return ret;
7152 }
7153
7154 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7155 policy)) {
7156 hddLog(LOGE, FL("Invalid ATTR"));
7157 return -EINVAL;
7158 }
7159
7160 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7161 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7162 return -EINVAL;
7163 }
7164
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307165 hdd_ctx->isSetBandByNL = TRUE;
7166 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307167 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307168 hdd_ctx->isSetBandByNL = FALSE;
7169
7170 EXIT();
7171 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307172}
7173
7174/**
7175 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7176 * @wiphy: wiphy structure pointer
7177 * @wdev: Wireless device structure pointer
7178 * @data: Pointer to the data received
7179 * @data_len: Length of @data
7180 *
7181 * Return: 0 on success; errno on failure
7182 */
7183static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7184 struct wireless_dev *wdev,
7185 const void *data,
7186 int data_len)
7187{
7188 int ret = 0;
7189
7190 vos_ssr_protect(__func__);
7191 ret = __wlan_hdd_cfg80211_setband(wiphy,
7192 wdev, data, data_len);
7193 vos_ssr_unprotect(__func__);
7194
7195 return ret;
7196}
7197
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307198#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7199/**
7200 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7201 * @hdd_ctx: HDD context
7202 * @request_id: [input] request id
7203 * @pattern_id: [output] pattern id
7204 *
7205 * This function loops through request id to pattern id array
7206 * if the slot is available, store the request id and return pattern id
7207 * if entry exists, return the pattern id
7208 *
7209 * Return: 0 on success and errno on failure
7210 */
7211static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7212 uint32_t request_id,
7213 uint8_t *pattern_id)
7214{
7215 uint32_t i;
7216
7217 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7218 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7219 {
7220 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7221 {
7222 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7223 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7224 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7225 return 0;
7226 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7227 request_id) {
7228 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7229 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7230 return 0;
7231 }
7232 }
7233 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7234 return -EINVAL;
7235}
7236
7237/**
7238 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7239 * @hdd_ctx: HDD context
7240 * @request_id: [input] request id
7241 * @pattern_id: [output] pattern id
7242 *
7243 * This function loops through request id to pattern id array
7244 * reset request id to 0 (slot available again) and
7245 * return pattern id
7246 *
7247 * Return: 0 on success and errno on failure
7248 */
7249static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7250 uint32_t request_id,
7251 uint8_t *pattern_id)
7252{
7253 uint32_t i;
7254
7255 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7256 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7257 {
7258 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7259 {
7260 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7261 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7262 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7263 return 0;
7264 }
7265 }
7266 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7267 return -EINVAL;
7268}
7269
7270
7271/*
7272 * define short names for the global vendor params
7273 * used by __wlan_hdd_cfg80211_offloaded_packets()
7274 */
7275#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7276#define PARAM_REQUEST_ID \
7277 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7278#define PARAM_CONTROL \
7279 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7280#define PARAM_IP_PACKET \
7281 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7282#define PARAM_SRC_MAC_ADDR \
7283 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7284#define PARAM_DST_MAC_ADDR \
7285 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7286#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7287
7288/**
7289 * wlan_hdd_add_tx_ptrn() - add tx pattern
7290 * @adapter: adapter pointer
7291 * @hdd_ctx: hdd context
7292 * @tb: nl attributes
7293 *
7294 * This function reads the NL attributes and forms a AddTxPtrn message
7295 * posts it to SME.
7296 *
7297 */
7298static int
7299wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7300 struct nlattr **tb)
7301{
7302 struct sSirAddPeriodicTxPtrn *add_req;
7303 eHalStatus status;
7304 uint32_t request_id, ret, len;
7305 uint8_t pattern_id = 0;
7306 v_MACADDR_t dst_addr;
7307 uint16_t eth_type = htons(ETH_P_IP);
7308
7309 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7310 {
7311 hddLog(LOGE, FL("Not in Connected state!"));
7312 return -ENOTSUPP;
7313 }
7314
7315 add_req = vos_mem_malloc(sizeof(*add_req));
7316 if (!add_req)
7317 {
7318 hddLog(LOGE, FL("memory allocation failed"));
7319 return -ENOMEM;
7320 }
7321
7322 /* Parse and fetch request Id */
7323 if (!tb[PARAM_REQUEST_ID])
7324 {
7325 hddLog(LOGE, FL("attr request id failed"));
7326 goto fail;
7327 }
7328
7329 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7330 hddLog(LOG1, FL("Request Id: %u"), request_id);
7331 if (request_id == 0)
7332 {
7333 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307334 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307335 }
7336
7337 if (!tb[PARAM_PERIOD])
7338 {
7339 hddLog(LOGE, FL("attr period failed"));
7340 goto fail;
7341 }
7342 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7343 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7344 if (add_req->usPtrnIntervalMs == 0)
7345 {
7346 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7347 goto fail;
7348 }
7349
7350 if (!tb[PARAM_SRC_MAC_ADDR])
7351 {
7352 hddLog(LOGE, FL("attr source mac address failed"));
7353 goto fail;
7354 }
7355 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7356 VOS_MAC_ADDR_SIZE);
7357 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7358 MAC_ADDR_ARRAY(add_req->macAddress));
7359
7360 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7361 VOS_MAC_ADDR_SIZE))
7362 {
7363 hddLog(LOGE,
7364 FL("input src mac address and connected ap bssid are different"));
7365 goto fail;
7366 }
7367
7368 if (!tb[PARAM_DST_MAC_ADDR])
7369 {
7370 hddLog(LOGE, FL("attr dst mac address failed"));
7371 goto fail;
7372 }
7373 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7374 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7375 MAC_ADDR_ARRAY(dst_addr.bytes));
7376
7377 if (!tb[PARAM_IP_PACKET])
7378 {
7379 hddLog(LOGE, FL("attr ip packet failed"));
7380 goto fail;
7381 }
7382 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7383 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7384
7385 if (add_req->ucPtrnSize < 0 ||
7386 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7387 HDD_ETH_HEADER_LEN))
7388 {
7389 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7390 add_req->ucPtrnSize);
7391 goto fail;
7392 }
7393
7394 len = 0;
7395 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7396 len += VOS_MAC_ADDR_SIZE;
7397 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7398 VOS_MAC_ADDR_SIZE);
7399 len += VOS_MAC_ADDR_SIZE;
7400 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7401 len += 2;
7402
7403 /*
7404 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7405 * ------------------------------------------------------------
7406 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7407 * ------------------------------------------------------------
7408 */
7409 vos_mem_copy(&add_req->ucPattern[len],
7410 nla_data(tb[PARAM_IP_PACKET]),
7411 add_req->ucPtrnSize);
7412 add_req->ucPtrnSize += len;
7413
7414 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7415 add_req->ucPattern, add_req->ucPtrnSize);
7416
7417 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7418 if (ret)
7419 {
7420 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7421 goto fail;
7422 }
7423 add_req->ucPtrnId = pattern_id;
7424 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7425
7426 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7427 if (!HAL_STATUS_SUCCESS(status))
7428 {
7429 hddLog(LOGE,
7430 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7431 goto fail;
7432 }
7433
7434 EXIT();
7435 vos_mem_free(add_req);
7436 return 0;
7437
7438fail:
7439 vos_mem_free(add_req);
7440 return -EINVAL;
7441}
7442
7443/**
7444 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7445 * @adapter: adapter pointer
7446 * @hdd_ctx: hdd context
7447 * @tb: nl attributes
7448 *
7449 * This function reads the NL attributes and forms a DelTxPtrn message
7450 * posts it to SME.
7451 *
7452 */
7453static int
7454wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7455 struct nlattr **tb)
7456{
7457 struct sSirDelPeriodicTxPtrn *del_req;
7458 eHalStatus status;
7459 uint32_t request_id, ret;
7460 uint8_t pattern_id = 0;
7461
7462 /* Parse and fetch request Id */
7463 if (!tb[PARAM_REQUEST_ID])
7464 {
7465 hddLog(LOGE, FL("attr request id failed"));
7466 return -EINVAL;
7467 }
7468 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7469 if (request_id == 0)
7470 {
7471 hddLog(LOGE, FL("request_id cannot be zero"));
7472 return -EINVAL;
7473 }
7474
7475 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7476 if (ret)
7477 {
7478 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7479 return -EINVAL;
7480 }
7481
7482 del_req = vos_mem_malloc(sizeof(*del_req));
7483 if (!del_req)
7484 {
7485 hddLog(LOGE, FL("memory allocation failed"));
7486 return -ENOMEM;
7487 }
7488
7489 vos_mem_set(del_req, sizeof(*del_req), 0);
7490 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7491 VOS_MAC_ADDR_SIZE);
7492 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7493 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7494 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7495 request_id, pattern_id, del_req->ucPatternIdBitmap);
7496
7497 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7498 if (!HAL_STATUS_SUCCESS(status))
7499 {
7500 hddLog(LOGE,
7501 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7502 goto fail;
7503 }
7504
7505 EXIT();
7506 vos_mem_free(del_req);
7507 return 0;
7508
7509fail:
7510 vos_mem_free(del_req);
7511 return -EINVAL;
7512}
7513
7514
7515/**
7516 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7517 * @wiphy: Pointer to wireless phy
7518 * @wdev: Pointer to wireless device
7519 * @data: Pointer to data
7520 * @data_len: Data length
7521 *
7522 * Return: 0 on success, negative errno on failure
7523 */
7524static int
7525__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7526 struct wireless_dev *wdev,
7527 const void *data,
7528 int data_len)
7529{
7530 struct net_device *dev = wdev->netdev;
7531 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7532 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7533 struct nlattr *tb[PARAM_MAX + 1];
7534 uint8_t control;
7535 int ret;
7536 static const struct nla_policy policy[PARAM_MAX + 1] =
7537 {
7538 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7539 [PARAM_CONTROL] = { .type = NLA_U32 },
7540 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7541 .len = VOS_MAC_ADDR_SIZE },
7542 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7543 .len = VOS_MAC_ADDR_SIZE },
7544 [PARAM_PERIOD] = { .type = NLA_U32 },
7545 };
7546
7547 ENTER();
7548
7549 ret = wlan_hdd_validate_context(hdd_ctx);
7550 if (0 != ret)
7551 {
7552 hddLog(LOGE, FL("HDD context is not valid"));
7553 return ret;
7554 }
7555
7556 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7557 {
7558 hddLog(LOGE,
7559 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7560 return -ENOTSUPP;
7561 }
7562
7563 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7564 {
7565 hddLog(LOGE, FL("Invalid ATTR"));
7566 return -EINVAL;
7567 }
7568
7569 if (!tb[PARAM_CONTROL])
7570 {
7571 hddLog(LOGE, FL("attr control failed"));
7572 return -EINVAL;
7573 }
7574 control = nla_get_u32(tb[PARAM_CONTROL]);
7575 hddLog(LOG1, FL("Control: %d"), control);
7576
7577 if (control == WLAN_START_OFFLOADED_PACKETS)
7578 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7579 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7580 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7581 else
7582 {
7583 hddLog(LOGE, FL("Invalid control: %d"), control);
7584 return -EINVAL;
7585 }
7586}
7587
7588/*
7589 * done with short names for the global vendor params
7590 * used by __wlan_hdd_cfg80211_offloaded_packets()
7591 */
7592#undef PARAM_MAX
7593#undef PARAM_REQUEST_ID
7594#undef PARAM_CONTROL
7595#undef PARAM_IP_PACKET
7596#undef PARAM_SRC_MAC_ADDR
7597#undef PARAM_DST_MAC_ADDR
7598#undef PARAM_PERIOD
7599
7600/**
7601 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7602 * @wiphy: wiphy structure pointer
7603 * @wdev: Wireless device structure pointer
7604 * @data: Pointer to the data received
7605 * @data_len: Length of @data
7606 *
7607 * Return: 0 on success; errno on failure
7608 */
7609static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7610 struct wireless_dev *wdev,
7611 const void *data,
7612 int data_len)
7613{
7614 int ret = 0;
7615
7616 vos_ssr_protect(__func__);
7617 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7618 wdev, data, data_len);
7619 vos_ssr_unprotect(__func__);
7620
7621 return ret;
7622}
7623#endif
7624
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307625static const struct
7626nla_policy
7627qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307628 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7629 .type = NLA_BINARY,
7630 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307631};
7632
7633/**
7634 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7635 * get link properties like nss, rate flags and operating frequency for
7636 * the connection with the given peer.
7637 * @wiphy: WIPHY structure pointer
7638 * @wdev: Wireless device structure pointer
7639 * @data: Pointer to the data received
7640 * @data_len: Length of the data received
7641 *
7642 * This function return the above link properties on success.
7643 *
7644 * Return: 0 on success and errno on failure
7645 */
7646static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7647 struct wireless_dev *wdev,
7648 const void *data,
7649 int data_len)
7650{
7651 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7652 struct net_device *dev = wdev->netdev;
7653 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7654 hdd_station_ctx_t *hdd_sta_ctx;
7655 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7656 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7657 uint32_t sta_id;
7658 struct sk_buff *reply_skb;
7659 uint32_t rate_flags = 0;
7660 uint8_t nss;
7661 uint8_t final_rate_flags = 0;
7662 uint32_t freq;
7663 v_CONTEXT_t pVosContext = NULL;
7664 ptSapContext pSapCtx = NULL;
7665
7666 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7668 return -EINVAL;
7669 }
7670
7671 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7672 qca_wlan_vendor_attr_policy)) {
7673 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7674 return -EINVAL;
7675 }
7676
7677 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7678 hddLog(VOS_TRACE_LEVEL_ERROR,
7679 FL("Attribute peerMac not provided for mode=%d"),
7680 adapter->device_mode);
7681 return -EINVAL;
7682 }
7683
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307684 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7685 hddLog(VOS_TRACE_LEVEL_ERROR,
7686 FL("Attribute peerMac is invalid=%d"),
7687 adapter->device_mode);
7688 return -EINVAL;
7689 }
7690
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307691 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7692 sizeof(peer_mac));
7693 hddLog(VOS_TRACE_LEVEL_INFO,
7694 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7695 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7696
7697 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7698 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7699 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7700 if ((hdd_sta_ctx->conn_info.connState !=
7701 eConnectionState_Associated) ||
7702 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7703 VOS_MAC_ADDRESS_LEN)) {
7704 hddLog(VOS_TRACE_LEVEL_ERROR,
7705 FL("Not Associated to mac "MAC_ADDRESS_STR),
7706 MAC_ADDR_ARRAY(peer_mac));
7707 return -EINVAL;
7708 }
7709
7710 nss = 1; //pronto supports only one spatial stream
7711 freq = vos_chan_to_freq(
7712 hdd_sta_ctx->conn_info.operationChannel);
7713 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7714
7715 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7716 adapter->device_mode == WLAN_HDD_SOFTAP) {
7717
7718 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7719 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7720 if(pSapCtx == NULL){
7721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7722 FL("psapCtx is NULL"));
7723 return -ENOENT;
7724 }
7725
7726
7727 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7728 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7729 !vos_is_macaddr_broadcast(
7730 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7731 vos_mem_compare(
7732 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7733 peer_mac, VOS_MAC_ADDRESS_LEN))
7734 break;
7735 }
7736
7737 if (WLAN_MAX_STA_COUNT == sta_id) {
7738 hddLog(VOS_TRACE_LEVEL_ERROR,
7739 FL("No active peer with mac="MAC_ADDRESS_STR),
7740 MAC_ADDR_ARRAY(peer_mac));
7741 return -EINVAL;
7742 }
7743
7744 nss = 1; //pronto supports only one spatial stream
7745 freq = vos_chan_to_freq(
7746 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7747 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7748 } else {
7749 hddLog(VOS_TRACE_LEVEL_ERROR,
7750 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7751 MAC_ADDR_ARRAY(peer_mac));
7752 return -EINVAL;
7753 }
7754
7755 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7756 if (rate_flags & eHAL_TX_RATE_VHT80) {
7757 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307758#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7759 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307760 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307761#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307762 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7763 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307764#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7765 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307766 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307767#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307768 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7769 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7770 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7771 final_rate_flags |= RATE_INFO_FLAGS_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307772#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7773 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307774 if (rate_flags & eHAL_TX_RATE_HT40)
7775 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307776#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307777 }
7778
7779 if (rate_flags & eHAL_TX_RATE_SGI) {
7780 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7781 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7782 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7783 }
7784 }
7785
7786 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7787 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7788
7789 if (NULL == reply_skb) {
7790 hddLog(VOS_TRACE_LEVEL_ERROR,
7791 FL("getLinkProperties: skb alloc failed"));
7792 return -EINVAL;
7793 }
7794
7795 if (nla_put_u8(reply_skb,
7796 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7797 nss) ||
7798 nla_put_u8(reply_skb,
7799 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7800 final_rate_flags) ||
7801 nla_put_u32(reply_skb,
7802 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7803 freq)) {
7804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7805 kfree_skb(reply_skb);
7806 return -EINVAL;
7807 }
7808
7809 return cfg80211_vendor_cmd_reply(reply_skb);
7810}
7811
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307812#define BEACON_MISS_THRESH_2_4 \
7813 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7814#define BEACON_MISS_THRESH_5_0 \
7815 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307816#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7817#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7818#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7819#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307820#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7821 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307822
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307823/*
7824 * hdd_set_qpower() - Process the qpower command and invoke the SME api
7825 * @hdd_ctx: hdd context
7826 * @enable: Value received in the command, 1 for disable and 2 for enable
7827 *
7828 * Return: void
7829 */
7830static void hdd_set_qpower(hdd_context_t *hdd_ctx, uint8_t enable)
7831{
7832 if (!hdd_ctx) {
7833 hddLog(LOGE, "hdd_ctx NULL");
7834 return;
7835 }
7836
7837 sme_set_qpower(hdd_ctx->hHal, enable);
7838}
7839
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307840/**
7841 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7842 * vendor command
7843 *
7844 * @wiphy: wiphy device pointer
7845 * @wdev: wireless device pointer
7846 * @data: Vendor command data buffer
7847 * @data_len: Buffer length
7848 *
7849 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7850 *
7851 * Return: EOK or other error codes.
7852 */
7853
7854static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7855 struct wireless_dev *wdev,
7856 const void *data,
7857 int data_len)
7858{
7859 struct net_device *dev = wdev->netdev;
7860 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7861 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7862 hdd_station_ctx_t *pHddStaCtx;
7863 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7864 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307865 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307866 eHalStatus status;
7867 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307868 uint8_t hb_thresh_val;
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307869 uint8_t qpower;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307870
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307871 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7872 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7873 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307874 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7875 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7876 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307877 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7878 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307879 };
7880
7881 ENTER();
7882
7883 if (VOS_FTM_MODE == hdd_get_conparam()) {
7884 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7885 return -EINVAL;
7886 }
7887
7888 ret_val = wlan_hdd_validate_context(pHddCtx);
7889 if (ret_val) {
7890 return ret_val;
7891 }
7892
7893 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7894
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307895 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7896 hddLog(LOGE, FL("Invalid ATTR"));
7897 return -EINVAL;
7898 }
7899
7900 /* check the Wifi Capability */
7901 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7902 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7903 {
7904 hddLog(VOS_TRACE_LEVEL_ERROR,
7905 FL("WIFICONFIG not supported by Firmware"));
7906 return -EINVAL;
7907 }
7908
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307909 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7910 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7911 modifyRoamParamsReq.value =
7912 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7913
7914 if (eHAL_STATUS_SUCCESS !=
7915 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7916 {
7917 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7918 ret_val = -EINVAL;
7919 }
7920 return ret_val;
7921 }
7922
7923 /* Moved this down in order to provide provision to set beacon
7924 * miss penalty count irrespective of connection state.
7925 */
7926 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7927 hddLog(LOGE, FL("Not in Connected state!"));
7928 return -ENOTSUPP;
7929 }
7930
7931 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307932
7933 if (!pReq) {
7934 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7935 "%s: Not able to allocate memory for tSetWifiConfigParams",
7936 __func__);
7937 return eHAL_STATUS_E_MALLOC_FAILED;
7938 }
7939
7940 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7941
7942 pReq->sessionId = pAdapter->sessionId;
7943 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7944
7945 if (tb[PARAM_MODULATED_DTIM]) {
7946 pReq->paramValue = nla_get_u32(
7947 tb[PARAM_MODULATED_DTIM]);
7948 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7949 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307950 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307951 hdd_set_pwrparams(pHddCtx);
7952 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7953 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7954
7955 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7956 iw_full_power_cbfn, pAdapter,
7957 eSME_FULL_PWR_NEEDED_BY_HDD);
7958 }
7959 else
7960 {
7961 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7962 }
7963 }
7964
7965 if (tb[PARAM_STATS_AVG_FACTOR]) {
7966 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7967 pReq->paramValue = nla_get_u16(
7968 tb[PARAM_STATS_AVG_FACTOR]);
7969 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7970 pReq->paramType, pReq->paramValue);
7971 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7972
7973 if (eHAL_STATUS_SUCCESS != status)
7974 {
7975 vos_mem_free(pReq);
7976 pReq = NULL;
7977 ret_val = -EPERM;
7978 return ret_val;
7979 }
7980 }
7981
7982
7983 if (tb[PARAM_GUARD_TIME]) {
7984 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7985 pReq->paramValue = nla_get_u32(
7986 tb[PARAM_GUARD_TIME]);
7987 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7988 pReq->paramType, pReq->paramValue);
7989 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7990
7991 if (eHAL_STATUS_SUCCESS != status)
7992 {
7993 vos_mem_free(pReq);
7994 pReq = NULL;
7995 ret_val = -EPERM;
7996 return ret_val;
7997 }
7998
7999 }
8000
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05308001 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
8002 hb_thresh_val = nla_get_u8(
8003 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
8004
8005 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
8006 hb_thresh_val);
8007 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
8008 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
8009 NULL, eANI_BOOLEAN_FALSE);
8010
8011 status = sme_update_hb_threshold(
8012 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
8013 WNI_CFG_HEART_BEAT_THRESHOLD,
8014 hb_thresh_val, eCSR_BAND_24);
8015 if (eHAL_STATUS_SUCCESS != status) {
8016 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
8017 vos_mem_free(pReq);
8018 pReq = NULL;
8019 return -EPERM;
8020 }
8021 }
8022
8023 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
8024 hb_thresh_val = nla_get_u8(
8025 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
8026
8027 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
8028 hb_thresh_val);
8029 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
8030 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
8031 NULL, eANI_BOOLEAN_FALSE);
8032
8033 status = sme_update_hb_threshold(
8034 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
8035 WNI_CFG_HEART_BEAT_THRESHOLD,
8036 hb_thresh_val, eCSR_BAND_5G);
8037 if (eHAL_STATUS_SUCCESS != status) {
8038 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
8039 vos_mem_free(pReq);
8040 pReq = NULL;
8041 return -EPERM;
8042 }
8043 }
8044
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05308045 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]) {
8046 qpower = nla_get_u8(
8047 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]);
8048
8049 if(qpower > 1) {
8050 hddLog(LOGE, "Invalid QPOWER value %d", qpower);
8051 vos_mem_free(pReq);
8052 pReq = NULL;
8053 return -EINVAL;
8054 }
8055 /* FW is expacting qpower as 1 for Disable and 2 for enable */
8056 qpower++;
8057 hdd_set_qpower(pHddCtx, qpower);
8058 }
8059
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308060 EXIT();
8061 return ret_val;
8062}
8063
8064/**
8065 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
8066 * vendor command
8067 *
8068 * @wiphy: wiphy device pointer
8069 * @wdev: wireless device pointer
8070 * @data: Vendor command data buffer
8071 * @data_len: Buffer length
8072 *
8073 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
8074 *
8075 * Return: EOK or other error codes.
8076 */
8077static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
8078 struct wireless_dev *wdev,
8079 const void *data,
8080 int data_len)
8081{
8082 int ret;
8083
8084 vos_ssr_protect(__func__);
8085 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
8086 data, data_len);
8087 vos_ssr_unprotect(__func__);
8088
8089 return ret;
8090}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308091
8092/*
8093 * define short names for the global vendor params
8094 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8095 */
8096#define STATS_SET_INVALID \
8097 QCA_ATTR_NUD_STATS_SET_INVALID
8098#define STATS_SET_START \
8099 QCA_ATTR_NUD_STATS_SET_START
8100#define STATS_GW_IPV4 \
8101 QCA_ATTR_NUD_STATS_GW_IPV4
8102#define STATS_SET_MAX \
8103 QCA_ATTR_NUD_STATS_SET_MAX
8104
8105const struct nla_policy
8106qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
8107{
8108 [STATS_SET_START] = {.type = NLA_FLAG },
8109 [STATS_GW_IPV4] = {.type = NLA_U32 },
8110};
8111
8112/**
8113 * hdd_set_nud_stats_cb() - hdd callback api to get status
8114 * @data: pointer to adapter
8115 * @rsp: status
8116 *
8117 * Return: None
8118 */
8119static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
8120{
8121
8122 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8123
8124 if (NULL == adapter)
8125 return;
8126
8127 if (VOS_STATUS_SUCCESS == rsp) {
8128 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8129 "%s success received STATS_SET_START", __func__);
8130 } else {
8131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8132 "%s STATS_SET_START Failed!!", __func__);
8133 }
8134 return;
8135}
8136
8137/**
8138 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8139 * @wiphy: pointer to wireless wiphy structure.
8140 * @wdev: pointer to wireless_dev structure.
8141 * @data: pointer to apfind configuration data.
8142 * @data_len: the length in byte of apfind data.
8143 *
8144 * This is called when wlan driver needs to send arp stats to
8145 * firmware.
8146 *
8147 * Return: An error code or 0 on success.
8148 */
8149static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8150 struct wireless_dev *wdev,
8151 const void *data, int data_len)
8152{
8153 struct nlattr *tb[STATS_SET_MAX + 1];
8154 struct net_device *dev = wdev->netdev;
8155 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8156 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308157 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308158 setArpStatsParams arp_stats_params;
8159 int err = 0;
8160
8161 ENTER();
8162
8163 err = wlan_hdd_validate_context(hdd_ctx);
8164 if (0 != err)
8165 return err;
8166
8167 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8169 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8170 return -EINVAL;
8171 }
8172
8173 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8174 qca_wlan_vendor_set_nud_stats);
8175 if (err)
8176 {
8177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8178 "%s STATS_SET_START ATTR", __func__);
8179 return err;
8180 }
8181
8182 if (tb[STATS_SET_START])
8183 {
8184 if (!tb[STATS_GW_IPV4]) {
8185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8186 "%s STATS_SET_START CMD", __func__);
8187 return -EINVAL;
8188 }
8189 arp_stats_params.flag = true;
8190 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8191 } else {
8192 arp_stats_params.flag = false;
8193 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308194 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8196 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308197 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8198 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308199
8200 arp_stats_params.pkt_type = 1; // ARP packet type
8201
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308202 if (arp_stats_params.flag) {
8203 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8204 WLANTL_SetARPFWDatapath(pVosContext, true);
8205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8206 "%s Set FW in data path for ARP with tgt IP :%d",
8207 __func__, hdd_ctx->track_arp_ip);
8208 }
8209 else {
8210 WLANTL_SetARPFWDatapath(pVosContext, false);
8211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8212 "%s Remove FW from data path", __func__);
8213 }
8214
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308215 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8216 arp_stats_params.data_ctx = adapter;
8217
8218 if (eHAL_STATUS_SUCCESS !=
8219 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8220 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8221 "%s STATS_SET_START CMD Failed!!", __func__);
8222 return -EINVAL;
8223 }
8224
8225 EXIT();
8226
8227 return err;
8228}
8229
8230/**
8231 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8232 * @wiphy: pointer to wireless wiphy structure.
8233 * @wdev: pointer to wireless_dev structure.
8234 * @data: pointer to apfind configuration data.
8235 * @data_len: the length in byte of apfind data.
8236 *
8237 * This is called when wlan driver needs to send arp stats to
8238 * firmware.
8239 *
8240 * Return: An error code or 0 on success.
8241 */
8242static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8243 struct wireless_dev *wdev,
8244 const void *data, int data_len)
8245{
8246 int ret;
8247
8248 vos_ssr_protect(__func__);
8249 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8250 vos_ssr_unprotect(__func__);
8251
8252 return ret;
8253}
8254#undef STATS_SET_INVALID
8255#undef STATS_SET_START
8256#undef STATS_GW_IPV4
8257#undef STATS_SET_MAX
8258
8259/*
8260 * define short names for the global vendor params
8261 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8262 */
8263#define STATS_GET_INVALID \
8264 QCA_ATTR_NUD_STATS_SET_INVALID
8265#define COUNT_FROM_NETDEV \
8266 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8267#define COUNT_TO_LOWER_MAC \
8268 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8269#define RX_COUNT_BY_LOWER_MAC \
8270 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8271#define COUNT_TX_SUCCESS \
8272 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8273#define RSP_RX_COUNT_BY_LOWER_MAC \
8274 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8275#define RSP_RX_COUNT_BY_UPPER_MAC \
8276 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8277#define RSP_COUNT_TO_NETDEV \
8278 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8279#define RSP_COUNT_OUT_OF_ORDER_DROP \
8280 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8281#define AP_LINK_ACTIVE \
8282 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8283#define AP_LINK_DAD \
8284 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8285#define STATS_GET_MAX \
8286 QCA_ATTR_NUD_STATS_GET_MAX
8287
8288const struct nla_policy
8289qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8290{
8291 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8292 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8293 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8294 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8295 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8296 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8297 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8298 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8299 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8300 [AP_LINK_DAD] = {.type = NLA_FLAG },
8301};
8302
8303static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8304{
8305
8306 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308307 hdd_context_t *hdd_ctx;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308308 struct hdd_nud_stats_context *context;
8309 int status;
8310
8311 ENTER();
8312
8313 if (NULL == adapter)
8314 return;
8315
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308316 if (!rsp) {
8317 hddLog(LOGE, FL("data is null"));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308318 return;
8319 }
8320
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308321 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8322 status = wlan_hdd_validate_context(hdd_ctx);
8323 if (0 != status) {
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308324 return;
8325 }
8326
8327 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8328 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8329 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8330 adapter->dad |= rsp->dad;
8331
8332 spin_lock(&hdd_context_lock);
8333 context = &hdd_ctx->nud_stats_context;
8334 complete(&context->response_event);
8335 spin_unlock(&hdd_context_lock);
8336
8337 return;
8338}
8339static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8340 struct wireless_dev *wdev,
8341 const void *data, int data_len)
8342{
8343 int err = 0;
8344 unsigned long rc;
8345 struct hdd_nud_stats_context *context;
8346 struct net_device *dev = wdev->netdev;
8347 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8348 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8349 getArpStatsParams arp_stats_params;
8350 struct sk_buff *skb;
8351
8352 ENTER();
8353
8354 err = wlan_hdd_validate_context(hdd_ctx);
8355 if (0 != err)
8356 return err;
8357
8358 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8359 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8360 arp_stats_params.data_ctx = adapter;
8361
8362 spin_lock(&hdd_context_lock);
8363 context = &hdd_ctx->nud_stats_context;
8364 INIT_COMPLETION(context->response_event);
8365 spin_unlock(&hdd_context_lock);
8366
8367 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8368 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8369 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8370 return -EINVAL;
8371 }
8372
8373 if (eHAL_STATUS_SUCCESS !=
8374 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8376 "%s STATS_SET_START CMD Failed!!", __func__);
8377 return -EINVAL;
8378 }
8379
8380 rc = wait_for_completion_timeout(&context->response_event,
8381 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8382 if (!rc)
8383 {
8384 hddLog(LOGE,
8385 FL("Target response timed out request "));
8386 return -ETIMEDOUT;
8387 }
8388
8389 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8390 WLAN_NUD_STATS_LEN);
8391 if (!skb)
8392 {
8393 hddLog(VOS_TRACE_LEVEL_ERROR,
8394 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8395 __func__);
8396 return -ENOMEM;
8397 }
8398
8399 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8400 adapter->hdd_stats.hddArpStats.txCount) ||
8401 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8402 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8403 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8404 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8405 nla_put_u16(skb, COUNT_TX_SUCCESS,
8406 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8407 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8408 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8409 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8410 adapter->hdd_stats.hddArpStats.rxCount) ||
8411 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8412 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8413 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8414 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8415 hddLog(LOGE, FL("nla put fail"));
8416 kfree_skb(skb);
8417 return -EINVAL;
8418 }
8419 if (adapter->con_status)
8420 nla_put_flag(skb, AP_LINK_ACTIVE);
8421 if (adapter->dad)
8422 nla_put_flag(skb, AP_LINK_DAD);
8423
8424 cfg80211_vendor_cmd_reply(skb);
8425 return err;
8426}
8427
8428static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8429 struct wireless_dev *wdev,
8430 const void *data, int data_len)
8431{
8432 int ret;
8433
8434 vos_ssr_protect(__func__);
8435 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8436 vos_ssr_unprotect(__func__);
8437
8438 return ret;
8439}
8440
8441#undef QCA_ATTR_NUD_STATS_SET_INVALID
8442#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8443#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8444#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8445#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8446#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8447#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8448#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8449#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8450#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8451#undef QCA_ATTR_NUD_STATS_GET_MAX
8452
8453
8454
Kapil Guptaee33bf12016-12-20 18:27:37 +05308455#ifdef WLAN_FEATURE_APFIND
8456/**
8457 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8458 * @wiphy: pointer to wireless wiphy structure.
8459 * @wdev: pointer to wireless_dev structure.
8460 * @data: pointer to apfind configuration data.
8461 * @data_len: the length in byte of apfind data.
8462 *
8463 * This is called when wlan driver needs to send APFIND configurations to
8464 * firmware.
8465 *
8466 * Return: An error code or 0 on success.
8467 */
8468static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8469 struct wireless_dev *wdev,
8470 const void *data, int data_len)
8471{
8472 struct sme_ap_find_request_req apfind_req;
8473 VOS_STATUS status;
8474 int ret_val;
8475 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8476
8477 ENTER();
8478
8479 ret_val = wlan_hdd_validate_context(hdd_ctx);
8480 if (ret_val)
8481 return ret_val;
8482
8483 if (VOS_FTM_MODE == hdd_get_conparam()) {
8484 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8485 return -EPERM;
8486 }
8487
8488 apfind_req.request_data_len = data_len;
8489 apfind_req.request_data = data;
8490
8491 status = sme_apfind_set_cmd(&apfind_req);
8492 if (VOS_STATUS_SUCCESS != status) {
8493 ret_val = -EIO;
8494 }
8495 return ret_val;
8496}
8497
8498/**
8499 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8500 * @wiphy: pointer to wireless wiphy structure.
8501 * @wdev: pointer to wireless_dev structure.
8502 * @data: pointer to apfind configuration data.
8503 * @data_len: the length in byte of apfind data.
8504 *
8505 * This is called when wlan driver needs to send APFIND configurations to
8506 * firmware.
8507 *
8508 * Return: An error code or 0 on success.
8509 */
8510static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8511 struct wireless_dev *wdev,
8512 const void *data, int data_len)
8513{
8514 int ret;
8515
8516 vos_ssr_protect(__func__);
8517 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8518 vos_ssr_unprotect(__func__);
8519
8520 return ret;
8521}
8522#endif /* WLAN_FEATURE_APFIND */
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308523
8524/**
8525 * __wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8526 * @wiphy: pointer to wireless wiphy structure.
8527 * @wdev: pointer to wireless_dev structure.
8528 * @data: Pointer to the data to be passed via vendor interface
8529 * @data_len:Length of the data to be passed
8530 *
8531 * This is called by userspace to know the supported logger features
8532 *
8533 * Return: Return the Success or Failure code.
8534 */
8535static int
8536__wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8537 struct wireless_dev *wdev,
8538 const void *data, int data_len)
8539{
8540 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8541 int status;
8542 uint32_t features;
8543 struct sk_buff *reply_skb = NULL;
8544
8545 if (VOS_FTM_MODE == hdd_get_conparam()) {
8546 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8547 return -EINVAL;
8548 }
8549
8550 status = wlan_hdd_validate_context(hdd_ctx);
8551 if (0 != status)
8552 return -EINVAL;
8553
8554 features = 0;
8555
8556 if (hdd_is_memdump_supported())
8557 features |= WIFI_LOGGER_MEMORY_DUMP_SUPPORTED;
8558
8559 if (hdd_ctx->cfg_ini->wlanLoggingEnable &&
8560 hdd_ctx->cfg_ini->enableFatalEvent &&
8561 hdd_ctx->is_fatal_event_log_sup) {
8562 features |= WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED;
8563 features |= WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
8564 }
8565
8566 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8567 sizeof(uint32_t) + NLA_HDRLEN + NLMSG_HDRLEN);
8568 if (!reply_skb) {
8569 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
8570 return -ENOMEM;
8571 }
8572
8573 hddLog(LOG1, FL("Supported logger features: 0x%0x"), features);
8574 if (nla_put_u32(reply_skb, QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED,
8575 features)) {
8576 hddLog(LOGE, FL("nla put fail"));
8577 kfree_skb(reply_skb);
8578 return -EINVAL;
8579 }
8580
8581 return cfg80211_vendor_cmd_reply(reply_skb);
8582}
8583
8584/**
8585 * wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8586 * @wiphy: pointer to wireless wiphy structure.
8587 * @wdev: pointer to wireless_dev structure.
8588 * @data: Pointer to the data to be passed via vendor interface
8589 * @data_len:Length of the data to be passed
8590 *
8591 * This is called by userspace to know the supported logger features
8592 *
8593 * Return: Return the Success or Failure code.
8594 */
8595static int
8596wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8597 struct wireless_dev *wdev,
8598 const void *data, int data_len)
8599{
8600 int ret;
8601
8602 vos_ssr_protect(__func__);
8603 ret = __wlan_hdd_cfg80211_get_logger_supp_feature(wiphy, wdev,
8604 data, data_len);
8605 vos_ssr_unprotect(__func__);
8606
8607 return ret;
8608}
8609
Sunil Duttc69bccb2014-05-26 21:30:20 +05308610const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8611{
Mukul Sharma2a271632014-10-13 14:59:01 +05308612 {
8613 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8614 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8615 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8616 WIPHY_VENDOR_CMD_NEED_NETDEV |
8617 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308618 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308619 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308620
8621 {
8622 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8623 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8624 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8625 WIPHY_VENDOR_CMD_NEED_NETDEV |
8626 WIPHY_VENDOR_CMD_NEED_RUNNING,
8627 .doit = wlan_hdd_cfg80211_nan_request
8628 },
8629
Sunil Duttc69bccb2014-05-26 21:30:20 +05308630#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8631 {
8632 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8633 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8634 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8635 WIPHY_VENDOR_CMD_NEED_NETDEV |
8636 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308637 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308638 },
8639
8640 {
8641 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8642 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8643 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8644 WIPHY_VENDOR_CMD_NEED_NETDEV |
8645 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308646 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308647 },
8648
8649 {
8650 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8651 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8652 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8653 WIPHY_VENDOR_CMD_NEED_NETDEV |
8654 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308655 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308656 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308657#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308658#ifdef WLAN_FEATURE_EXTSCAN
8659 {
8660 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8661 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8662 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8663 WIPHY_VENDOR_CMD_NEED_NETDEV |
8664 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308665 .doit = wlan_hdd_cfg80211_extscan_start
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_STOP,
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_stop
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_VALID_CHANNELS,
8678 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8679 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308680 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308681 },
8682 {
8683 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8684 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8685 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8686 WIPHY_VENDOR_CMD_NEED_NETDEV |
8687 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308688 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308689 },
8690 {
8691 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8692 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8693 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8694 WIPHY_VENDOR_CMD_NEED_NETDEV |
8695 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308696 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308697 },
8698 {
8699 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8700 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8701 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8702 WIPHY_VENDOR_CMD_NEED_NETDEV |
8703 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308704 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308705 },
8706 {
8707 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8708 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8709 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8710 WIPHY_VENDOR_CMD_NEED_NETDEV |
8711 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308712 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308713 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308714#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308715/*EXT TDLS*/
8716 {
8717 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8718 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8719 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8720 WIPHY_VENDOR_CMD_NEED_NETDEV |
8721 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308722 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308723 },
8724 {
8725 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8726 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8727 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8728 WIPHY_VENDOR_CMD_NEED_NETDEV |
8729 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308730 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308731 },
8732 {
8733 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8734 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8735 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8736 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308737 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308738 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308739 {
8740 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8741 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8742 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8743 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308744 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308745 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308746 {
8747 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8748 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8749 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8750 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308751 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308752 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308753 {
8754 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8755 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8756 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8757 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308758 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308759 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308760 {
8761 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8762 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8763 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8764 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308765 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308766 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308767 {
8768 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308769 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8770 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8771 WIPHY_VENDOR_CMD_NEED_NETDEV |
8772 WIPHY_VENDOR_CMD_NEED_RUNNING,
8773 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8774 },
8775 {
8776 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308777 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8778 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8779 WIPHY_VENDOR_CMD_NEED_NETDEV |
8780 WIPHY_VENDOR_CMD_NEED_RUNNING,
8781 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308782 },
8783 {
8784 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8785 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8786 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8787 WIPHY_VENDOR_CMD_NEED_NETDEV,
8788 .doit = wlan_hdd_cfg80211_wifi_logger_start
8789 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308790 {
8791 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8792 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8793 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8794 WIPHY_VENDOR_CMD_NEED_NETDEV|
8795 WIPHY_VENDOR_CMD_NEED_RUNNING,
8796 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308797 },
8798 {
8799 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8800 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8801 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8802 WIPHY_VENDOR_CMD_NEED_NETDEV |
8803 WIPHY_VENDOR_CMD_NEED_RUNNING,
8804 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308805 },
8806 {
8807 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8808 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8809 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8810 WIPHY_VENDOR_CMD_NEED_NETDEV |
8811 WIPHY_VENDOR_CMD_NEED_RUNNING,
8812 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308813 },
8814#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8815 {
8816 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8817 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8818 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8819 WIPHY_VENDOR_CMD_NEED_NETDEV |
8820 WIPHY_VENDOR_CMD_NEED_RUNNING,
8821 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308822 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308823#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308824 {
8825 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8826 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8827 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8828 WIPHY_VENDOR_CMD_NEED_NETDEV |
8829 WIPHY_VENDOR_CMD_NEED_RUNNING,
8830 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308831 },
8832 {
8833 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8834 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8835 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8836 WIPHY_VENDOR_CMD_NEED_NETDEV |
8837 WIPHY_VENDOR_CMD_NEED_RUNNING,
8838 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308839 },
8840#ifdef WLAN_FEATURE_APFIND
8841 {
8842 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8843 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8844 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8845 WIPHY_VENDOR_CMD_NEED_NETDEV,
8846 .doit = wlan_hdd_cfg80211_apfind_cmd
8847 },
8848#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308849 {
8850 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8851 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8852 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8853 WIPHY_VENDOR_CMD_NEED_NETDEV |
8854 WIPHY_VENDOR_CMD_NEED_RUNNING,
8855 .doit = wlan_hdd_cfg80211_set_nud_stats
8856 },
8857 {
8858 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8859 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8860 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8861 WIPHY_VENDOR_CMD_NEED_NETDEV |
8862 WIPHY_VENDOR_CMD_NEED_RUNNING,
8863 .doit = wlan_hdd_cfg80211_get_nud_stats
8864 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308865 {
8866 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8867 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8868 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8869 WIPHY_VENDOR_CMD_NEED_NETDEV |
8870 WIPHY_VENDOR_CMD_NEED_RUNNING,
8871 .doit = hdd_cfg80211_get_station_cmd
8872 },
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308873 {
8874 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8875 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET,
8876 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
Hanumanth Reddy Pothula07c95582018-05-23 12:41:22 +05308877 WIPHY_VENDOR_CMD_NEED_NETDEV,
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308878 .doit = wlan_hdd_cfg80211_get_logger_supp_feature
8879 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308880};
8881
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008882/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308883static const
8884struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008885{
8886#ifdef FEATURE_WLAN_CH_AVOID
8887 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308888 .vendor_id = QCA_NL80211_VENDOR_ID,
8889 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008890 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308891#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8892#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8893 {
8894 /* Index = 1*/
8895 .vendor_id = QCA_NL80211_VENDOR_ID,
8896 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8897 },
8898 {
8899 /* Index = 2*/
8900 .vendor_id = QCA_NL80211_VENDOR_ID,
8901 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8902 },
8903 {
8904 /* Index = 3*/
8905 .vendor_id = QCA_NL80211_VENDOR_ID,
8906 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8907 },
8908 {
8909 /* Index = 4*/
8910 .vendor_id = QCA_NL80211_VENDOR_ID,
8911 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8912 },
8913 {
8914 /* Index = 5*/
8915 .vendor_id = QCA_NL80211_VENDOR_ID,
8916 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8917 },
8918 {
8919 /* Index = 6*/
8920 .vendor_id = QCA_NL80211_VENDOR_ID,
8921 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8922 },
8923#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308924#ifdef WLAN_FEATURE_EXTSCAN
8925 {
8926 .vendor_id = QCA_NL80211_VENDOR_ID,
8927 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8928 },
8929 {
8930 .vendor_id = QCA_NL80211_VENDOR_ID,
8931 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8932 },
8933 {
8934 .vendor_id = QCA_NL80211_VENDOR_ID,
8935 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8936 },
8937 {
8938 .vendor_id = QCA_NL80211_VENDOR_ID,
8939 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8940 },
8941 {
8942 .vendor_id = QCA_NL80211_VENDOR_ID,
8943 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8944 },
8945 {
8946 .vendor_id = QCA_NL80211_VENDOR_ID,
8947 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8948 },
8949 {
8950 .vendor_id = QCA_NL80211_VENDOR_ID,
8951 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8952 },
8953 {
8954 .vendor_id = QCA_NL80211_VENDOR_ID,
8955 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8956 },
8957 {
8958 .vendor_id = QCA_NL80211_VENDOR_ID,
8959 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8960 },
8961 {
8962 .vendor_id = QCA_NL80211_VENDOR_ID,
8963 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8964 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308965#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308966/*EXT TDLS*/
8967 {
8968 .vendor_id = QCA_NL80211_VENDOR_ID,
8969 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8970 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308971 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8972 .vendor_id = QCA_NL80211_VENDOR_ID,
8973 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8974 },
8975
Srinivas Dasari030bad32015-02-18 23:23:54 +05308976
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308977 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308978 .vendor_id = QCA_NL80211_VENDOR_ID,
8979 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8980 },
8981
Sushant Kaushik084f6592015-09-10 13:11:56 +05308982 {
8983 .vendor_id = QCA_NL80211_VENDOR_ID,
8984 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308985 },
8986 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8987 .vendor_id = QCA_NL80211_VENDOR_ID,
8988 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8989 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308990 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8991 .vendor_id = QCA_NL80211_VENDOR_ID,
8992 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8993 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308994 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8995 .vendor_id = QCA_NL80211_VENDOR_ID,
8996 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8997 },
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05308998 [QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
8999 .vendor_id = QCA_NL80211_VENDOR_ID,
9000 .subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
9001 },
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +05309002 [QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX] = {
9003 .vendor_id = QCA_NL80211_VENDOR_ID,
9004 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
9005 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009006};
9007
Jeff Johnson295189b2012-06-20 16:38:30 -07009008/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309009 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309010 * This function is called by hdd_wlan_startup()
9011 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309012 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07009013 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309014struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07009015{
9016 struct wiphy *wiphy;
9017 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309018 /*
9019 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07009020 */
9021 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
9022
9023 if (!wiphy)
9024 {
9025 /* Print error and jump into err label and free the memory */
9026 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
9027 return NULL;
9028 }
9029
Sunil Duttc69bccb2014-05-26 21:30:20 +05309030
Jeff Johnson295189b2012-06-20 16:38:30 -07009031 return wiphy;
9032}
9033
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309034#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
9035 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
9036/**
9037 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
9038 * @wiphy: pointer to wiphy
9039 * @config: pointer to config
9040 *
9041 * Return: None
9042 */
9043static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
9044 hdd_config_t *config)
9045{
9046 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
9047 if (config->max_sched_scan_plan_interval)
9048 wiphy->max_sched_scan_plan_interval =
9049 config->max_sched_scan_plan_interval;
9050 if (config->max_sched_scan_plan_iterations)
9051 wiphy->max_sched_scan_plan_iterations =
9052 config->max_sched_scan_plan_iterations;
9053}
9054#else
9055static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
9056 hdd_config_t *config)
9057{
9058}
9059#endif
9060
Jeff Johnson295189b2012-06-20 16:38:30 -07009061/*
9062 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309063 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07009064 * private ioctl to change the band value
9065 */
9066int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
9067{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309068 int i, j;
9069 eNVChannelEnabledType channelEnabledState;
9070
Jeff Johnsone7245742012-09-05 17:12:55 -07009071 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309072
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309073 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009074 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309075
9076 if (NULL == wiphy->bands[i])
9077 {
9078 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
9079 __func__, i);
9080 continue;
9081 }
9082
9083 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9084 {
9085 struct ieee80211_supported_band *band = wiphy->bands[i];
9086
9087 channelEnabledState = vos_nv_getChannelEnabledState(
9088 band->channels[j].hw_value);
9089
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309090 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309091 {
Abhishek Singh678227a2014-11-04 10:52:38 +05309092 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309093 continue;
9094 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309095 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309096 {
9097 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9098 continue;
9099 }
9100
9101 if (NV_CHANNEL_DISABLE == channelEnabledState ||
9102 NV_CHANNEL_INVALID == channelEnabledState)
9103 {
9104 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9105 }
9106 else if (NV_CHANNEL_DFS == channelEnabledState)
9107 {
9108 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9109 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
9110 }
9111 else
9112 {
9113 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
9114 |IEEE80211_CHAN_RADAR);
9115 }
9116 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009117 }
9118 return 0;
9119}
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309120
9121/**
9122 * hdd_add_channel_switch_support()- Adds Channel Switch flag if supported
9123 * @wiphy: Pointer to the wiphy.
9124 *
9125 * This Function adds Channel Switch support flag, if channel switch is
9126 * supported by kernel.
9127 * Return: void.
9128 */
9129#ifdef CHANNEL_SWITCH_SUPPORTED
9130static inline
9131void hdd_add_channel_switch_support(struct wiphy *wiphy)
9132{
9133 wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
9134 wiphy->max_num_csa_counters = WLAN_HDD_MAX_NUM_CSA_COUNTERS;
9135}
9136#else
9137static inline
9138void hdd_add_channel_switch_support(struct wiphy *wiphy)
9139{
9140}
9141#endif
9142
Jeff Johnson295189b2012-06-20 16:38:30 -07009143/*
9144 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309145 * This function is called by hdd_wlan_startup()
9146 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07009147 * This function is used to initialize and register wiphy structure.
9148 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309149int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009150 struct wiphy *wiphy,
9151 hdd_config_t *pCfg
9152 )
9153{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309154 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309155 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9156
Jeff Johnsone7245742012-09-05 17:12:55 -07009157 ENTER();
9158
Jeff Johnson295189b2012-06-20 16:38:30 -07009159 /* Now bind the underlying wlan device with wiphy */
9160 set_wiphy_dev(wiphy, dev);
9161
9162 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009163
Kiet Lam6c583332013-10-14 05:37:09 +05309164#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009165 /* the flag for the other case would be initialzed in
9166 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05309167#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9168 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
9169#else
Amar Singhal0a402232013-10-11 20:57:16 -07009170 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05309171#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05309172#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009173
Amar Singhalfddc28c2013-09-05 13:03:40 -07009174 /* This will disable updating of NL channels from passive to
9175 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309176#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9177 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
9178#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07009179 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309180#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07009181
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309182#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
9183 wiphy->wowlan = &wowlan_support_cfg80211_init;
9184#else
Nachiket Kukade1e1b90e2018-05-10 15:26:13 +05309185 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
9186 WIPHY_WOWLAN_MAGIC_PKT;
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309187 wiphy->wowlan.n_patterns = WOWL_MAX_PTRNS_ALLOWED;
9188 wiphy->wowlan.pattern_min_len = 1;
9189 wiphy->wowlan.pattern_max_len = WOWL_PTRN_MAX_SIZE;
9190#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009191
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009192#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009193 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
9194 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
9195 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07009196 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309197#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05309198 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309199#else
9200 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
9201#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009202#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009203
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009204#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009205 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08009206#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009207 || pCfg->isFastRoamIniFeatureEnabled
9208#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009209#ifdef FEATURE_WLAN_ESE
9210 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009211#endif
9212 )
9213 {
9214 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
9215 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08009216#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009217#ifdef FEATURE_WLAN_TDLS
9218 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
9219 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
9220#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309221#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05309222 if (pCfg->configPNOScanSupport)
9223 {
9224 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
9225 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
9226 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
9227 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
9228 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309229#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009230
Abhishek Singh10d85972015-04-17 10:27:23 +05309231#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9232 wiphy->features |= NL80211_FEATURE_HT_IBSS;
9233#endif
9234
Amar Singhalfddc28c2013-09-05 13:03:40 -07009235#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009236 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
9237 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07009238 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009239 driver need to determine what to do with both
9240 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07009241
9242 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07009243#else
9244 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009245#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009246
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309247 wiphy->max_scan_ssids = MAX_SCAN_SSID;
9248
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05309249 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07009250
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309251 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
9252
Jeff Johnson295189b2012-06-20 16:38:30 -07009253 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05309254 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
9255 | BIT(NL80211_IFTYPE_ADHOC)
9256 | BIT(NL80211_IFTYPE_P2P_CLIENT)
9257 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309258 | BIT(NL80211_IFTYPE_AP)
9259 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07009260
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309261 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009262 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309263#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9264 if( pCfg->enableMCC )
9265 {
9266 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309267 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009268
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309269 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309270 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009271
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309272 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309273 wiphy->iface_combinations = wlan_hdd_iface_combination;
9274 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009275#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309276 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009277
Jeff Johnson295189b2012-06-20 16:38:30 -07009278 /* Before registering we need to update the ht capabilitied based
9279 * on ini values*/
9280 if( !pCfg->ShortGI20MhzEnable )
9281 {
9282 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
9283 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07009284 }
9285
9286 if( !pCfg->ShortGI40MhzEnable )
9287 {
9288 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9289 }
9290
9291 if( !pCfg->nChannelBondingMode5GHz )
9292 {
9293 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9294 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309295 /*
9296 * In case of static linked driver at the time of driver unload,
9297 * module exit doesn't happens. Module cleanup helps in cleaning
9298 * of static memory.
9299 * If driver load happens statically, at the time of driver unload,
9300 * wiphy flags don't get reset because of static memory.
9301 * It's better not to store channel in static memory.
9302 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309303 wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9304 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309305 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309306 if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309307 {
9308 hddLog(VOS_TRACE_LEVEL_ERROR,
9309 FL("Not enough memory to allocate channels"));
9310 return -ENOMEM;
9311 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309312 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309313 &hdd_channels_2_4_GHZ[0],
9314 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009315
Agrawal Ashish97dec502015-11-26 20:20:58 +05309316 if (true == hdd_is_5g_supported(pHddCtx))
9317 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309318 wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9319 wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309320 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309321 if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309322 {
9323 hddLog(VOS_TRACE_LEVEL_ERROR,
9324 FL("Not enough memory to allocate channels"));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309325 vos_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
9326 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
Agrawal Ashish97dec502015-11-26 20:20:58 +05309327 return -ENOMEM;
9328 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309329 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309330 &hdd_channels_5_GHZ[0],
9331 sizeof(hdd_channels_5_GHZ));
9332 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309333
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309334 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309335 {
9336
9337 if (NULL == wiphy->bands[i])
9338 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309339 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309340 __func__, i);
9341 continue;
9342 }
9343
9344 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9345 {
9346 struct ieee80211_supported_band *band = wiphy->bands[i];
9347
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309348 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309349 {
9350 // Enable social channels for P2P
9351 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9352 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9353 else
9354 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9355 continue;
9356 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309357 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309358 {
9359 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9360 continue;
9361 }
9362 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009363 }
9364 /*Initialise the supported cipher suite details*/
9365 wiphy->cipher_suites = hdd_cipher_suites;
9366 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9367
9368 /*signal strength in mBm (100*dBm) */
9369 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9370
9371#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309372 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009373#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009374
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309375 hdd_add_channel_switch_support(wiphy);
Sunil Duttc69bccb2014-05-26 21:30:20 +05309376 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9377 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009378 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9379 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9380
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309381 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
9382
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309383 EXIT();
9384 return 0;
9385}
9386
9387/* In this function we are registering wiphy. */
9388int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9389{
9390 ENTER();
9391 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009392 if (0 > wiphy_register(wiphy))
9393 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309394 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009395 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9396 return -EIO;
9397 }
9398
9399 EXIT();
9400 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309401}
Jeff Johnson295189b2012-06-20 16:38:30 -07009402
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309403/* In this function we are updating channel list when,
9404 regulatory domain is FCC and country code is US.
9405 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9406 As per FCC smart phone is not a indoor device.
9407 GO should not opeate on indoor channels */
9408void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9409{
9410 int j;
9411 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9412 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9413 //Default counrtycode from NV at the time of wiphy initialization.
9414 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9415 &defaultCountryCode[0]))
9416 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009417 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309418 }
9419 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9420 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309421 if (NULL == wiphy->bands[HDD_NL80211_BAND_5GHZ])
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309422 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309423 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[HDD_NL80211_BAND_5GHZ] is NULL",__func__ );
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309424 return;
9425 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309426 for (j = 0; j < wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels; j++)
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309427 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309428 struct ieee80211_supported_band *band = wiphy->bands[HDD_NL80211_BAND_5GHZ];
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309429 // Mark UNII -1 band channel as passive
9430 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9431 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9432 }
9433 }
9434}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309435/* This function registers for all frame which supplicant is interested in */
9436void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009437{
Jeff Johnson295189b2012-06-20 16:38:30 -07009438 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9439 /* Register for all P2P action, public action etc frames */
9440 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009441 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309442 /* Register frame indication call back */
9443 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009444 /* Right now we are registering these frame when driver is getting
9445 initialized. Once we will move to 2.6.37 kernel, in which we have
9446 frame register ops, we will move this code as a part of that */
9447 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309448 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009449 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9450
9451 /* GAS Initial Response */
9452 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9453 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309454
Jeff Johnson295189b2012-06-20 16:38:30 -07009455 /* GAS Comeback Request */
9456 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9457 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9458
9459 /* GAS Comeback Response */
9460 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9461 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9462
9463 /* P2P Public Action */
9464 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309465 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009466 P2P_PUBLIC_ACTION_FRAME_SIZE );
9467
9468 /* P2P Action */
9469 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9470 (v_U8_t*)P2P_ACTION_FRAME,
9471 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009472
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309473 /* WNM BSS Transition Request frame */
9474 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9475 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9476 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009477
9478 /* WNM-Notification */
9479 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9480 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9481 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009482}
9483
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309484void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009485{
Jeff Johnson295189b2012-06-20 16:38:30 -07009486 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9487 /* Register for all P2P action, public action etc frames */
9488 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9489
Jeff Johnsone7245742012-09-05 17:12:55 -07009490 ENTER();
9491
Jeff Johnson295189b2012-06-20 16:38:30 -07009492 /* Right now we are registering these frame when driver is getting
9493 initialized. Once we will move to 2.6.37 kernel, in which we have
9494 frame register ops, we will move this code as a part of that */
9495 /* GAS Initial Request */
9496
9497 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9498 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9499
9500 /* GAS Initial Response */
9501 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9502 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309503
Jeff Johnson295189b2012-06-20 16:38:30 -07009504 /* GAS Comeback Request */
9505 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9506 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9507
9508 /* GAS Comeback Response */
9509 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9510 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9511
9512 /* P2P Public Action */
9513 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309514 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009515 P2P_PUBLIC_ACTION_FRAME_SIZE );
9516
9517 /* P2P Action */
9518 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9519 (v_U8_t*)P2P_ACTION_FRAME,
9520 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009521 /* WNM-Notification */
9522 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9523 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9524 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009525}
9526
9527#ifdef FEATURE_WLAN_WAPI
9528void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309529 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009530{
9531 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9532 tCsrRoamSetKey setKey;
9533 v_BOOL_t isConnected = TRUE;
9534 int status = 0;
9535 v_U32_t roamId= 0xFF;
9536 tANI_U8 *pKeyPtr = NULL;
9537 int n = 0;
9538
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309539 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9540 __func__, hdd_device_modetoString(pAdapter->device_mode),
9541 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009542
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309543 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009544 setKey.keyId = key_index; // Store Key ID
9545 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9546 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9547 setKey.paeRole = 0 ; // the PAE role
9548 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9549 {
9550 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9551 }
9552 else
9553 {
9554 isConnected = hdd_connIsConnected(pHddStaCtx);
9555 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9556 }
9557 setKey.keyLength = key_Len;
9558 pKeyPtr = setKey.Key;
9559 memcpy( pKeyPtr, key, key_Len);
9560
Arif Hussain6d2a3322013-11-17 19:50:10 -08009561 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009562 __func__, key_Len);
9563 for (n = 0 ; n < key_Len; n++)
9564 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9565 __func__,n,setKey.Key[n]);
9566
9567 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9568 if ( isConnected )
9569 {
9570 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9571 pAdapter->sessionId, &setKey, &roamId );
9572 }
9573 if ( status != 0 )
9574 {
9575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9576 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9577 __LINE__, status );
9578 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9579 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309580 /* Need to clear any trace of key value in the memory.
9581 * Thus zero out the memory even though it is local
9582 * variable.
9583 */
9584 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009585}
9586#endif /* FEATURE_WLAN_WAPI*/
9587
9588#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309589int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009590 beacon_data_t **ppBeacon,
9591 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009592#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309593int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009594 beacon_data_t **ppBeacon,
9595 struct cfg80211_beacon_data *params,
9596 int dtim_period)
9597#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309598{
Jeff Johnson295189b2012-06-20 16:38:30 -07009599 int size;
9600 beacon_data_t *beacon = NULL;
9601 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309602 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9603 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009604
Jeff Johnsone7245742012-09-05 17:12:55 -07009605 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009606 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309607 {
9608 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9609 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009610 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309611 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009612
9613 old = pAdapter->sessionCtx.ap.beacon;
9614
9615 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309616 {
9617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9618 FL("session(%d) old and new heads points to NULL"),
9619 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009620 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309621 }
9622
9623 if (params->tail && !params->tail_len)
9624 {
9625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9626 FL("tail_len is zero but tail is not NULL"));
9627 return -EINVAL;
9628 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009629
Jeff Johnson295189b2012-06-20 16:38:30 -07009630#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9631 /* Kernel 3.0 is not updating dtim_period for set beacon */
9632 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309633 {
9634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9635 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009636 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309637 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009638#endif
9639
Kapil Gupta137ef892016-12-13 19:38:00 +05309640 if (params->head)
9641 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009642 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309643 head = params->head;
9644 } else
9645 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009646 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309647 head = old->head;
9648 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009649
Kapil Gupta137ef892016-12-13 19:38:00 +05309650 if (params->tail || !old)
9651 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009652 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309653 tail = params->tail;
9654 } else
9655 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009656 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309657 tail = old->tail;
9658 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009659
Kapil Gupta137ef892016-12-13 19:38:00 +05309660 if (params->proberesp_ies || !old)
9661 {
9662 proberesp_ies_len = params->proberesp_ies_len;
9663 proberesp_ies = params->proberesp_ies;
9664 } else
9665 {
9666 proberesp_ies_len = old->proberesp_ies_len;
9667 proberesp_ies = old->proberesp_ies;
9668 }
9669
9670 if (params->assocresp_ies || !old)
9671 {
9672 assocresp_ies_len = params->assocresp_ies_len;
9673 assocresp_ies = params->assocresp_ies;
9674 } else
9675 {
9676 assocresp_ies_len = old->assocresp_ies_len;
9677 assocresp_ies = old->assocresp_ies;
9678 }
9679
9680 size = sizeof(beacon_data_t) + head_len + tail_len +
9681 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009682
9683 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009684 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309685 {
9686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9687 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009688 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309689 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009690
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009691#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309692 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009693 beacon->dtim_period = params->dtim_period;
9694 else
9695 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009696#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309697 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009698 beacon->dtim_period = dtim_period;
9699 else
9700 beacon->dtim_period = old->dtim_period;
9701#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309702
Jeff Johnson295189b2012-06-20 16:38:30 -07009703 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9704 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309705 beacon->proberesp_ies = beacon->tail + tail_len;
9706 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9707
Jeff Johnson295189b2012-06-20 16:38:30 -07009708 beacon->head_len = head_len;
9709 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309710 beacon->proberesp_ies_len = proberesp_ies_len;
9711 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009712
c_manjee527ecac2017-01-25 12:25:27 +05309713 if (head && head_len)
9714 memcpy(beacon->head, head, head_len);
9715 if (tail && tail_len)
9716 memcpy(beacon->tail, tail, tail_len);
9717 if (proberesp_ies && proberesp_ies_len)
9718 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9719 if (assocresp_ies && assocresp_ies_len)
9720 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009721
9722 *ppBeacon = beacon;
9723
9724 kfree(old);
9725
9726 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009727}
Jeff Johnson295189b2012-06-20 16:38:30 -07009728
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309729v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9730#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9731 const v_U8_t *pIes,
9732#else
9733 v_U8_t *pIes,
9734#endif
9735 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009736{
9737 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309738 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009739 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309740
Jeff Johnson295189b2012-06-20 16:38:30 -07009741 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309742 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009743 elem_id = ptr[0];
9744 elem_len = ptr[1];
9745 left -= 2;
9746 if(elem_len > left)
9747 {
9748 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009749 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009750 eid,elem_len,left);
9751 return NULL;
9752 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309753 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009754 {
9755 return ptr;
9756 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309757
Jeff Johnson295189b2012-06-20 16:38:30 -07009758 left -= elem_len;
9759 ptr += (elem_len + 2);
9760 }
9761 return NULL;
9762}
9763
Jeff Johnson295189b2012-06-20 16:38:30 -07009764/* Check if rate is 11g rate or not */
9765static int wlan_hdd_rate_is_11g(u8 rate)
9766{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009767 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009768 u8 i;
9769 for (i = 0; i < 8; i++)
9770 {
9771 if(rate == gRateArray[i])
9772 return TRUE;
9773 }
9774 return FALSE;
9775}
9776
9777/* Check for 11g rate and set proper 11g only mode */
9778static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9779 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9780{
9781 u8 i, num_rates = pIe[0];
9782
9783 pIe += 1;
9784 for ( i = 0; i < num_rates; i++)
9785 {
9786 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9787 {
9788 /* If rate set have 11g rate than change the mode to 11G */
9789 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9790 if (pIe[i] & BASIC_RATE_MASK)
9791 {
9792 /* If we have 11g rate as basic rate, it means mode
9793 is 11g only mode.
9794 */
9795 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9796 *pCheckRatesfor11g = FALSE;
9797 }
9798 }
9799 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9800 {
9801 *require_ht = TRUE;
9802 }
9803 }
9804 return;
9805}
9806
9807static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9808{
9809 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9810 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9811 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9812 u8 checkRatesfor11g = TRUE;
9813 u8 require_ht = FALSE;
9814 u8 *pIe=NULL;
9815
9816 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9817
9818 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9819 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9820 if (pIe != NULL)
9821 {
9822 pIe += 1;
9823 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9824 &pConfig->SapHw_mode);
9825 }
9826
9827 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9828 WLAN_EID_EXT_SUPP_RATES);
9829 if (pIe != NULL)
9830 {
9831
9832 pIe += 1;
9833 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9834 &pConfig->SapHw_mode);
9835 }
9836
9837 if( pConfig->channel > 14 )
9838 {
9839 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9840 }
9841
9842 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9843 WLAN_EID_HT_CAPABILITY);
9844
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309845 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009846 {
9847 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9848 if(require_ht)
9849 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9850 }
9851}
9852
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309853static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9854 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9855{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009856 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309857 v_U8_t *pIe = NULL;
9858 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9859
9860 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9861 pBeacon->tail, pBeacon->tail_len);
9862
9863 if (pIe)
9864 {
9865 ielen = pIe[1] + 2;
9866 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9867 {
9868 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9869 }
9870 else
9871 {
9872 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9873 return -EINVAL;
9874 }
9875 *total_ielen += ielen;
9876 }
9877 return 0;
9878}
9879
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009880static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9881 v_U8_t *genie, v_U8_t *total_ielen)
9882{
9883 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9884 int left = pBeacon->tail_len;
9885 v_U8_t *ptr = pBeacon->tail;
9886 v_U8_t elem_id, elem_len;
9887 v_U16_t ielen = 0;
9888
9889 if ( NULL == ptr || 0 == left )
9890 return;
9891
9892 while (left >= 2)
9893 {
9894 elem_id = ptr[0];
9895 elem_len = ptr[1];
9896 left -= 2;
9897 if (elem_len > left)
9898 {
9899 hddLog( VOS_TRACE_LEVEL_ERROR,
9900 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9901 elem_id, elem_len, left);
9902 return;
9903 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309904 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009905 {
9906 /* skipping the VSIE's which we don't want to include or
9907 * it will be included by existing code
9908 */
9909 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9910#ifdef WLAN_FEATURE_WFD
9911 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9912#endif
9913 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9914 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9915 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9916 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9917 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9918 {
9919 ielen = ptr[1] + 2;
9920 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9921 {
9922 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9923 *total_ielen += ielen;
9924 }
9925 else
9926 {
9927 hddLog( VOS_TRACE_LEVEL_ERROR,
9928 "IE Length is too big "
9929 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9930 elem_id, elem_len, *total_ielen);
9931 }
9932 }
9933 }
9934
9935 left -= elem_len;
9936 ptr += (elem_len + 2);
9937 }
9938 return;
9939}
9940
Kapil Gupta137ef892016-12-13 19:38:00 +05309941int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009942{
9943 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309944 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009945 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009946 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309947 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009948
9949 genie = vos_mem_malloc(MAX_GENIE_LEN);
9950
9951 if(genie == NULL) {
9952
9953 return -ENOMEM;
9954 }
9955
Kapil Gupta137ef892016-12-13 19:38:00 +05309956 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309957 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9958 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009959 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309960 hddLog(LOGE,
9961 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309962 ret = -EINVAL;
9963 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009964 }
9965
9966#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309967 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9968 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9969 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309970 hddLog(LOGE,
9971 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309972 ret = -EINVAL;
9973 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009974 }
9975#endif
9976
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309977 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9978 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009979 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309980 hddLog(LOGE,
9981 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309982 ret = -EINVAL;
9983 goto done;
9984 }
9985
9986 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9987 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009988 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009989 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009990
9991 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9992 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9993 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9994 {
9995 hddLog(LOGE,
9996 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009997 ret = -EINVAL;
9998 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009999 }
10000
10001 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10002 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10003 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10004 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10005 ==eHAL_STATUS_FAILURE)
10006 {
10007 hddLog(LOGE,
10008 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010009 ret = -EINVAL;
10010 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010011 }
10012
10013 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +053010014 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010015 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010016 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -070010017 u8 probe_rsp_ie_len[3] = {0};
10018 u8 counter = 0;
10019 /* Check Probe Resp Length if it is greater then 255 then Store
10020 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
10021 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
10022 Store More then 255 bytes into One Variable.
10023 */
10024 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
10025 {
10026 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
10027 {
10028 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
10029 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
10030 }
10031 else
10032 {
10033 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
10034 rem_probe_resp_ie_len = 0;
10035 }
10036 }
10037
10038 rem_probe_resp_ie_len = 0;
10039
10040 if (probe_rsp_ie_len[0] > 0)
10041 {
10042 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10043 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +053010044 (tANI_U8*)&pBeacon->
10045 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010046 probe_rsp_ie_len[0], NULL,
10047 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10048 {
10049 hddLog(LOGE,
10050 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010051 ret = -EINVAL;
10052 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010053 }
10054 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10055 }
10056
10057 if (probe_rsp_ie_len[1] > 0)
10058 {
10059 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10060 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +053010061 (tANI_U8*)&pBeacon->
10062 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010063 probe_rsp_ie_len[1], NULL,
10064 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10065 {
10066 hddLog(LOGE,
10067 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010068 ret = -EINVAL;
10069 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010070 }
10071 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10072 }
10073
10074 if (probe_rsp_ie_len[2] > 0)
10075 {
10076 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10077 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +053010078 (tANI_U8*)&pBeacon->
10079 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010080 probe_rsp_ie_len[2], NULL,
10081 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10082 {
10083 hddLog(LOGE,
10084 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010085 ret = -EINVAL;
10086 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010087 }
10088 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10089 }
10090
10091 if (probe_rsp_ie_len[1] == 0 )
10092 {
10093 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10094 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10095 eANI_BOOLEAN_FALSE) )
10096 {
10097 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010098 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010099 }
10100 }
10101
10102 if (probe_rsp_ie_len[2] == 0 )
10103 {
10104 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10105 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10106 eANI_BOOLEAN_FALSE) )
10107 {
10108 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010109 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010110 }
10111 }
10112
10113 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10114 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10115 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10116 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10117 == eHAL_STATUS_FAILURE)
10118 {
10119 hddLog(LOGE,
10120 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010121 ret = -EINVAL;
10122 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010123 }
10124 }
10125 else
10126 {
10127 // Reset WNI_CFG_PROBE_RSP Flags
10128 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
10129
10130 hddLog(VOS_TRACE_LEVEL_INFO,
10131 "%s: No Probe Response IE received in set beacon",
10132 __func__);
10133 }
10134
10135 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +053010136 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010137 {
10138 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +053010139 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
10140 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -070010141 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10142 {
10143 hddLog(LOGE,
10144 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010145 ret = -EINVAL;
10146 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010147 }
10148
10149 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10150 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
10151 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10152 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10153 == eHAL_STATUS_FAILURE)
10154 {
10155 hddLog(LOGE,
10156 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010157 ret = -EINVAL;
10158 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010159 }
10160 }
10161 else
10162 {
10163 hddLog(VOS_TRACE_LEVEL_INFO,
10164 "%s: No Assoc Response IE received in set beacon",
10165 __func__);
10166
10167 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10168 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10169 eANI_BOOLEAN_FALSE) )
10170 {
10171 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010172 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010173 }
10174 }
10175
Jeff Johnsone7245742012-09-05 17:12:55 -070010176done:
Jeff Johnson295189b2012-06-20 16:38:30 -070010177 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010178 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010179}
Jeff Johnson295189b2012-06-20 16:38:30 -070010180
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010181/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010182 * FUNCTION: wlan_hdd_validate_operation_channel
10183 * called by wlan_hdd_cfg80211_start_bss() and
10184 * wlan_hdd_cfg80211_set_channel()
10185 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010186 * channel list.
10187 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -070010188VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010189{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010190
Jeff Johnson295189b2012-06-20 16:38:30 -070010191 v_U32_t num_ch = 0;
10192 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10193 u32 indx = 0;
10194 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010195 v_U8_t fValidChannel = FALSE, count = 0;
10196 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010197
Jeff Johnson295189b2012-06-20 16:38:30 -070010198 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10199
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010200 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010201 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010202 /* Validate the channel */
10203 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010204 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010205 if ( channel == rfChannels[count].channelNum )
10206 {
10207 fValidChannel = TRUE;
10208 break;
10209 }
10210 }
10211 if (fValidChannel != TRUE)
10212 {
10213 hddLog(VOS_TRACE_LEVEL_ERROR,
10214 "%s: Invalid Channel [%d]", __func__, channel);
10215 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010216 }
10217 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010218 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010219 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010220 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10221 valid_ch, &num_ch))
10222 {
10223 hddLog(VOS_TRACE_LEVEL_ERROR,
10224 "%s: failed to get valid channel list", __func__);
10225 return VOS_STATUS_E_FAILURE;
10226 }
10227 for (indx = 0; indx < num_ch; indx++)
10228 {
10229 if (channel == valid_ch[indx])
10230 {
10231 break;
10232 }
10233 }
10234
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010235 if (indx >= num_ch)
10236 {
10237 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10238 {
10239 eCsrBand band;
10240 unsigned int freq;
10241
10242 sme_GetFreqBand(hHal, &band);
10243
10244 if (eCSR_BAND_5G == band)
10245 {
10246#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10247 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10248 {
10249 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010250 HDD_NL80211_BAND_2GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010251 }
10252 else
10253 {
10254 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010255 HDD_NL80211_BAND_5GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010256 }
10257#else
10258 freq = ieee80211_channel_to_frequency(channel);
10259#endif
10260 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
10261 return VOS_STATUS_SUCCESS;
10262 }
10263 }
10264
10265 hddLog(VOS_TRACE_LEVEL_ERROR,
10266 "%s: Invalid Channel [%d]", __func__, channel);
10267 return VOS_STATUS_E_FAILURE;
10268 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010269 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010270
Jeff Johnson295189b2012-06-20 16:38:30 -070010271 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010272
Jeff Johnson295189b2012-06-20 16:38:30 -070010273}
10274
Viral Modi3a32cc52013-02-08 11:14:52 -080010275/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010276 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -080010277 * This function is used to set the channel number
10278 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010279static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -080010280 struct ieee80211_channel *chan,
10281 enum nl80211_channel_type channel_type
10282 )
10283{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010284 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -080010285 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -070010286 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -080010287 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010288 hdd_context_t *pHddCtx;
10289 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010290
10291 ENTER();
10292
10293 if( NULL == dev )
10294 {
10295 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010296 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010297 return -ENODEV;
10298 }
10299 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010300
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010301 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10302 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10303 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010304 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010305 "%s: device_mode = %s (%d) freq = %d", __func__,
10306 hdd_device_modetoString(pAdapter->device_mode),
10307 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010308
10309 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10310 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010311 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010312 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010313 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010314 }
10315
10316 /*
10317 * Do freq to chan conversion
10318 * TODO: for 11a
10319 */
10320
10321 channel = ieee80211_frequency_to_channel(freq);
10322
10323 /* Check freq range */
10324 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10325 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10326 {
10327 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010328 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010329 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10330 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10331 return -EINVAL;
10332 }
10333
10334 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10335
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010336 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10337 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010338 {
10339 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10340 {
10341 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010342 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010343 return -EINVAL;
10344 }
10345 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10346 "%s: set channel to [%d] for device mode =%d",
10347 __func__, channel,pAdapter->device_mode);
10348 }
10349 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010350 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010351 )
10352 {
10353 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10354 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10355 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10356
10357 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10358 {
10359 /* Link is up then return cant set channel*/
10360 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010361 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010362 return -EINVAL;
10363 }
10364
10365 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10366 pHddStaCtx->conn_info.operationChannel = channel;
10367 pRoamProfile->ChannelInfo.ChannelList =
10368 &pHddStaCtx->conn_info.operationChannel;
10369 }
10370 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010371 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010372 )
10373 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010374 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10375 {
10376 if(VOS_STATUS_SUCCESS !=
10377 wlan_hdd_validate_operation_channel(pAdapter,channel))
10378 {
10379 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010380 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010381 return -EINVAL;
10382 }
10383 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10384 }
10385 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010386 {
10387 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10388
10389 /* If auto channel selection is configured as enable/ 1 then ignore
10390 channel set by supplicant
10391 */
10392 if ( cfg_param->apAutoChannelSelection )
10393 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010394 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10395 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010396 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010397 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10398 __func__, hdd_device_modetoString(pAdapter->device_mode),
10399 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010400 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010401 else
10402 {
10403 if(VOS_STATUS_SUCCESS !=
10404 wlan_hdd_validate_operation_channel(pAdapter,channel))
10405 {
10406 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010407 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010408 return -EINVAL;
10409 }
10410 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10411 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010412 }
10413 }
10414 else
10415 {
10416 hddLog(VOS_TRACE_LEVEL_FATAL,
10417 "%s: Invalid device mode failed to set valid channel", __func__);
10418 return -EINVAL;
10419 }
10420 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010421 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010422}
10423
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010424static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10425 struct net_device *dev,
10426 struct ieee80211_channel *chan,
10427 enum nl80211_channel_type channel_type
10428 )
10429{
10430 int ret;
10431
10432 vos_ssr_protect(__func__);
10433 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10434 vos_ssr_unprotect(__func__);
10435
10436 return ret;
10437}
10438
Anurag Chouhan83026002016-12-13 22:46:21 +053010439#ifdef DHCP_SERVER_OFFLOAD
10440void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10441 VOS_STATUS status)
10442{
10443 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10444
10445 ENTER();
10446
10447 if (NULL == adapter)
10448 {
10449 hddLog(VOS_TRACE_LEVEL_ERROR,
10450 "%s: adapter is NULL",__func__);
10451 return;
10452 }
10453
10454 adapter->dhcp_status.dhcp_offload_status = status;
10455 vos_event_set(&adapter->dhcp_status.vos_event);
10456 return;
10457}
10458
10459/**
10460 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10461 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010462 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010463 *
10464 * Return: None
10465 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010466VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10467 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010468{
10469 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10470 sir_dhcp_srv_offload_info dhcp_srv_info;
10471 tANI_U8 num_entries = 0;
10472 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10473 tANI_U8 num;
10474 tANI_U32 temp;
10475 VOS_STATUS ret;
10476
10477 ENTER();
10478
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010479 if (!re_init) {
10480 ret = wlan_hdd_validate_context(hdd_ctx);
10481 if (0 != ret)
10482 return VOS_STATUS_E_INVAL;
10483 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010484
10485 /* Prepare the request to send to SME */
10486 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10487 if (NULL == dhcp_srv_info) {
10488 hddLog(VOS_TRACE_LEVEL_ERROR,
10489 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10490 return VOS_STATUS_E_NOMEM;
10491 }
10492
10493 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10494
10495 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10496 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10497 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10498 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10499 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10500 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10501
10502 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10503 srv_ip,
10504 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010505 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010506 if (num_entries != IPADDR_NUM_ENTRIES) {
10507 hddLog(VOS_TRACE_LEVEL_ERROR,
10508 "%s: incorrect IP address (%s) assigned for DHCP server!",
10509 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10510 vos_mem_free(dhcp_srv_info);
10511 return VOS_STATUS_E_FAILURE;
10512 }
10513
10514 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10515 hddLog(VOS_TRACE_LEVEL_ERROR,
10516 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10517 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10518 vos_mem_free(dhcp_srv_info);
10519 return VOS_STATUS_E_FAILURE;
10520 }
10521
10522 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10523 hddLog(VOS_TRACE_LEVEL_ERROR,
10524 "%s: invalid IP address (%s)! The last field must be less than 100!",
10525 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10526 vos_mem_free(dhcp_srv_info);
10527 return VOS_STATUS_E_FAILURE;
10528 }
10529
10530 for (num = 0; num < num_entries; num++) {
10531 temp = srv_ip[num];
10532 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10533 }
10534
10535 if (eHAL_STATUS_SUCCESS !=
10536 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10537 hddLog(VOS_TRACE_LEVEL_ERROR,
10538 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10539 vos_mem_free(dhcp_srv_info);
10540 return VOS_STATUS_E_FAILURE;
10541 }
10542
10543 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10544 "%s: enable DHCP Server offload successfully!", __func__);
10545
10546 vos_mem_free(dhcp_srv_info);
10547 return 0;
10548}
10549#endif /* DHCP_SERVER_OFFLOAD */
10550
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010551/*
10552 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10553 * @wiphy_chan: wiphy channel number
10554 * @rfChannel: channel hw value
10555 * @disable: Disable/enable the flags
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010556 * @hdd_ctx: The HDD context handler
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010557 *
10558 * Modify wiphy flags and cds state if channel is indoor.
10559 *
10560 * Return: void
10561 */
10562void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010563 v_U32_t rfChannel, bool disable, hdd_context_t *hdd_ctx)
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010564{
10565 v_U32_t channelLoop;
10566 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10567
10568 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10569
10570 if (rfChannels[channelLoop].channelNum == rfChannel) {
10571 channelEnum = (eRfChannels)channelLoop;
10572 break;
10573 }
10574 }
10575
10576 if (INVALID_RF_CHANNEL == channelEnum)
10577 return;
10578
10579 if (disable) {
10580 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10581 wiphy_chan->flags |=
10582 IEEE80211_CHAN_DISABLED;
10583 regChannels[channelEnum].enabled =
10584 NV_CHANNEL_DISABLE;
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010585 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as DISABLE",
10586 channelEnum);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010587 }
10588 } else {
10589 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10590 wiphy_chan->flags &=
10591 ~IEEE80211_CHAN_DISABLED;
10592 /*
10593 * Indoor channels are marked as DFS
10594 * during regulatory processing
10595 */
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010596 if ((wiphy_chan->flags & (IEEE80211_CHAN_RADAR |
10597 IEEE80211_CHAN_PASSIVE_SCAN)) ||
10598 ((hdd_ctx->cfg_ini->indoor_channel_support == false)
10599 && (wiphy_chan->flags &
10600 IEEE80211_CHAN_INDOOR_ONLY))) {
10601 regChannels[channelEnum].enabled = NV_CHANNEL_DFS;
10602 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as DFS",
10603 channelEnum);
10604 } else {
10605 regChannels[channelEnum].enabled =
10606 NV_CHANNEL_ENABLE;
10607 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as ENABLE",
10608 channelEnum);
10609 }
10610 }
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010611
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010612 }
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010613}
10614
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010615void hdd_update_indoor_channel(hdd_context_t *hdd_ctx, bool disable)
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010616{
10617 int band_num;
10618 int chan_num;
10619 v_U32_t rfChannel;
10620 struct ieee80211_channel *wiphy_chan;
10621 struct wiphy *wiphy;
10622
10623 ENTER();
10624 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10625
10626 wiphy = hdd_ctx->wiphy;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010627 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010628
10629 if (wiphy->bands[band_num] == NULL)
10630 continue;
10631
10632 for (chan_num = 0;
10633 chan_num < wiphy->bands[band_num]->n_channels;
10634 chan_num++) {
10635
10636 wiphy_chan =
10637 &(wiphy->bands[band_num]->channels[chan_num]);
10638 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10639
10640 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010641 disable, hdd_ctx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010642 }
10643 }
10644 EXIT();
10645}
10646
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010647int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10648{
10649 int status, result = 0;
10650 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
10658 status = wlan_hdd_validate_context(pHddCtx);
10659 if (0 != status)
10660 {
10661 return status;
10662 }
10663 /* Indicate sme of disconnect so that in progress connection or preauth
10664 * can be aborted
10665 */
10666 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10667 pAdapter->sessionId);
10668 pHddCtx->isAmpAllowed = VOS_TRUE;
10669
10670 /* Need to apply spin lock before decreasing active sessions
10671 * as there can be chance for double decrement if context switch
10672 * Calls hdd_DisConnectHandler.
10673 */
10674
10675 prev_conn_state = pHddStaCtx->conn_info.connState;
10676
10677 spin_lock_bh(&pAdapter->lock_for_active_session);
10678 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10679 {
10680 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10681 }
10682 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10683 spin_unlock_bh(&pAdapter->lock_for_active_session);
10684 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
10685
10686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10687 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10688
10689 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10690
10691 /*
10692 * stop tx queues before deleting STA/BSS context from the firmware.
10693 * tx has to be disabled because the firmware can get busy dropping
10694 * the tx frames after BSS/STA has been deleted and will not send
10695 * back a response resulting in WDI timeout
10696 */
10697 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10698 netif_tx_disable(pAdapter->dev);
10699 netif_carrier_off(pAdapter->dev);
10700
10701 wlan_hdd_check_and_stop_mon(pAdapter, true);
10702
10703 /*issue disconnect*/
10704 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10705 pAdapter->sessionId, reason);
10706 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
10707 prev_conn_state != eConnectionState_Connecting)
10708 {
10709 hddLog(LOG1,
10710 FL("status = %d, already disconnected"), status);
10711 result = 0;
10712 /*
10713 * Wait here instead of returning directly. This will block the
10714 * next connect command and allow processing of the disconnect
10715 * in SME else we might hit some race conditions leading to SME
10716 * and HDD out of sync. As disconnect is already in progress,
10717 * wait here for 1 sec instead of 5 sec.
10718 */
10719 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
10720 goto wait_for_disconnect;
10721 }
10722 /*
10723 * Wait here instead of returning directly, this will block the next
10724 * connect command and allow processing of the scan for ssid and
10725 * the previous connect command in CSR. Else we might hit some
10726 * race conditions leading to SME and HDD out of sync.
10727 */
10728 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10729 {
10730 hddLog(LOG1,
10731 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
10732 }
10733 else if ( 0 != status )
10734 {
10735 hddLog(LOGE,
10736 FL("csrRoamDisconnect failure, returned %d"),
10737 (int)status);
10738 result = -EINVAL;
10739 goto disconnected;
10740 }
10741wait_for_disconnect:
10742 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
10743 msecs_to_jiffies(wait_time));
10744 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
10745 {
10746 hddLog(LOGE,
10747 "%s: Failed to disconnect, timed out", __func__);
10748 result = -ETIMEDOUT;
10749 }
10750disconnected:
10751 hddLog(LOG1,
10752 FL("Set HDD connState to eConnectionState_NotConnected"));
10753 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10754#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
10755 /* Sending disconnect event to userspace for kernel version < 3.11
10756 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
10757 */
10758 hddLog(LOG1, FL("Send disconnected event to userspace"));
10759
10760 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
10761 WLAN_REASON_UNSPECIFIED);
10762#endif
10763
10764 EXIT();
10765 return result;
10766}
10767
10768/*
10769 * hdd_check_and_disconnect_sta_on_invalid_channel() - Disconnect STA if it is
10770 * on indoor channel
10771 * @hdd_ctx: pointer to hdd context
10772 *
10773 * STA should be disconnected before starting the SAP if it is on indoor
10774 * channel.
10775 *
10776 * Return: void
10777 */
10778void hdd_check_and_disconnect_sta_on_invalid_channel(hdd_context_t *hdd_ctx)
10779{
10780
10781 hdd_adapter_t *sta_adapter;
10782 tANI_U8 sta_chan;
10783
10784 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
10785
10786 if (!sta_chan) {
10787 hddLog(LOG1, FL("STA not connected"));
10788 return;
10789 }
10790
10791 hddLog(LOG1, FL("STA connected on chan %hu"), sta_chan);
10792
10793 if (sme_IsChannelValid(hdd_ctx->hHal, sta_chan)) {
10794 hddLog(LOG1, FL("STA connected on chan %hu and it is valid"),
10795 sta_chan);
10796 return;
10797 }
10798
10799 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
10800
10801 if (!sta_adapter) {
10802 hddLog(LOG1, FL("STA adapter doesn't exist"));
10803 return;
10804 }
10805
10806 hddLog(LOG1, FL("chan %hu not valid, issue disconnect"), sta_chan);
10807 /* Issue Disconnect request */
10808 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10809}
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010810
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010811int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx)
10812{
10813 struct hdd_cache_channels *cache_chann;
10814 struct wiphy *wiphy;
10815 int freq, status, rfChannel;
10816 int i, band_num, channel_num;
10817 struct ieee80211_channel *wiphy_channel;
10818
10819 ENTER();
10820
10821 if (!hdd_ctx) {
10822 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10823 return -EINVAL;
10824 }
10825
10826 wiphy = hdd_ctx->wiphy;
10827
10828 mutex_lock(&hdd_ctx->cache_channel_lock);
10829
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010830 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010831
10832 if (!cache_chann || !cache_chann->num_channels) {
10833 hddLog(VOS_TRACE_LEVEL_INFO,
10834 "%s channel list is NULL or num channels are zero",
10835 __func__);
10836 mutex_unlock(&hdd_ctx->cache_channel_lock);
10837 return -EINVAL;
10838 }
10839
10840 for (i = 0; i < cache_chann->num_channels; i++) {
10841 status = hdd_wlan_get_freq(
10842 cache_chann->channel_info[i].channel_num,
10843 &freq);
10844
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010845 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
10846 band_num++) {
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010847 for (channel_num = 0; channel_num <
10848 wiphy->bands[band_num]->n_channels;
10849 channel_num++) {
10850 wiphy_channel = &(wiphy->bands[band_num]->
10851 channels[channel_num]);
10852 if (wiphy_channel->center_freq == freq) {
10853 rfChannel = wiphy_channel->hw_value;
10854 /*
10855 *Restore the orginal states
10856 *of the channels
10857 */
10858 vos_nv_set_channel_state(
10859 rfChannel,
10860 cache_chann->
10861 channel_info[i].reg_status);
10862 wiphy_channel->flags =
10863 cache_chann->
10864 channel_info[i].wiphy_status;
10865 break;
10866 }
10867 }
10868 if (channel_num < wiphy->bands[band_num]->n_channels)
10869 break;
10870 }
10871 }
10872
10873 mutex_unlock(&hdd_ctx->cache_channel_lock);
10874
10875 status = sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10876 if (status)
10877 hddLog(VOS_TRACE_LEVEL_ERROR, "Can't Restore channel list");
10878 EXIT();
10879
10880 return 0;
10881}
10882
10883/*
10884 * wlan_hdd_disable_channels() - Cache the the channels
10885 * and current state of the channels from the channel list
10886 * received in the command and disable the channels on the
10887 * wiphy and NV table.
10888 * @hdd_ctx: Pointer to hdd context
10889 *
10890 * @return: 0 on success, Error code on failure
10891 */
10892
10893static int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx)
10894{
10895 struct hdd_cache_channels *cache_chann;
10896 struct wiphy *wiphy;
10897 int freq, status, rfChannel;
10898 int i, band_num, band_ch_num;
10899 struct ieee80211_channel *wiphy_channel;
10900
10901 if (!hdd_ctx) {
10902 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10903 return -EINVAL;
10904 }
10905
10906 wiphy = hdd_ctx->wiphy;
10907
10908 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010909 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010910
10911 if (!cache_chann || !cache_chann->num_channels) {
10912 hddLog(VOS_TRACE_LEVEL_INFO,
10913 "%s channel list is NULL or num channels are zero",
10914 __func__);
10915 mutex_unlock(&hdd_ctx->cache_channel_lock);
10916 return -EINVAL;
10917 }
10918
10919 for (i = 0; i < cache_chann->num_channels; i++) {
10920 status = hdd_wlan_get_freq(
10921 cache_chann->channel_info[i].channel_num,
10922 &freq);
10923
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010924 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010925 band_num++) {
10926 for (band_ch_num = 0; band_ch_num <
10927 wiphy->bands[band_num]->n_channels;
10928 band_ch_num++) {
10929 wiphy_channel = &(wiphy->bands[band_num]->
10930 channels[band_ch_num]);
10931 if (wiphy_channel->center_freq == freq) {
10932 rfChannel = wiphy_channel->hw_value;
10933 /*
10934 * Cache the current states of
10935 * the channels
10936 */
10937 cache_chann->
10938 channel_info[i].reg_status =
10939 vos_nv_getChannelEnabledState(
10940 rfChannel);
10941
10942 cache_chann->
10943 channel_info[i].wiphy_status =
10944 wiphy_channel->flags;
10945 hddLog(VOS_TRACE_LEVEL_INFO,
10946 "Disable channel %d reg_stat %d wiphy_stat 0x%x",
10947 cache_chann->
10948 channel_info[i].channel_num,
10949 cache_chann->
10950 channel_info[i].reg_status,
10951 wiphy_channel->flags);
10952
10953 vos_nv_set_channel_state(
10954 rfChannel,
10955 NV_CHANNEL_DISABLE);
10956 wiphy_channel->flags |=
10957 IEEE80211_CHAN_DISABLED;
10958 break;
10959 }
10960 }
10961 if (band_ch_num < wiphy->bands[band_num]->n_channels)
10962 break;
10963 }
10964 }
10965
10966 mutex_unlock(&hdd_ctx->cache_channel_lock);
10967 sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10968 return 0;
10969}
10970
Jeff Johnson295189b2012-06-20 16:38:30 -070010971#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10972static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10973 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010974#else
10975static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10976 struct cfg80211_beacon_data *params,
10977 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010978 enum nl80211_hidden_ssid hidden_ssid,
10979 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010980#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010981{
10982 tsap_Config_t *pConfig;
10983 beacon_data_t *pBeacon = NULL;
10984 struct ieee80211_mgmt *pMgmt_frame;
10985 v_U8_t *pIe=NULL;
10986 v_U16_t capab_info;
10987 eCsrAuthType RSNAuthType;
10988 eCsrEncryptionType RSNEncryptType;
10989 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010990 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010991 tpWLAN_SAPEventCB pSapEventCallback;
10992 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070010993 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010994 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010995 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010996 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070010997 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080010998 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Vignesh Viswanathan36575f82018-06-14 16:52:21 +053010999 hdd_adapter_t *sta_adapter;
Peng Xu2446a892014-09-05 17:21:18 +053011000 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070011001 v_BOOL_t MFPCapable = VOS_FALSE;
11002 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011003 v_BOOL_t sapEnable11AC =
11004 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053011005 u_int16_t prev_rsn_length = 0;
11006
Jeff Johnson295189b2012-06-20 16:38:30 -070011007 ENTER();
11008
Nitesh Shah9b066282017-06-06 18:05:52 +053011009 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Vignesh Viswanathan36575f82018-06-14 16:52:21 +053011010
11011 /*
11012 * For STA+SAP concurrency support from GUI, first STA connection gets
11013 * triggered and while it is in progress, SAP start also comes up.
11014 * Once STA association is successful, STA connect event is sent to
11015 * kernel which gets queued in kernel workqueue and supplicant won't
11016 * process M1 received from AP and send M2 until this NL80211_CONNECT
11017 * event is received. Workqueue is not scheduled as RTNL lock is already
11018 * taken by hostapd thread which has issued start_bss command to driver.
11019 * Driver cannot complete start_bss as the pending command at the head
11020 * of the SME command pending list is hw_mode_update for STA session
11021 * which cannot be processed as SME is in WAITforKey state for STA
11022 * interface. The start_bss command for SAP interface is queued behind
11023 * the hw_mode_update command and so it cannot be processed until
11024 * hw_mode_update command is processed. This is causing a deadlock so
11025 * disconnect the STA interface first if connection or key exchange is
11026 * in progress and then start SAP interface.
11027 */
11028 sta_adapter = hdd_get_sta_connection_in_progress(pHddCtx);
11029 if (sta_adapter) {
11030 hddLog(LOG1, FL("Disconnecting STA with session id: %d"),
11031 sta_adapter->sessionId);
11032 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
11033 }
11034
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011035 iniConfig = pHddCtx->cfg_ini;
11036
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011037 /* Mark the indoor channel (passive) to disable */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011038 if (iniConfig->disable_indoor_channel &&
11039 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011040 hdd_update_indoor_channel(pHddCtx, true);
11041
11042 if (!VOS_IS_STATUS_SUCCESS(
11043 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
11044 hdd_update_indoor_channel(pHddCtx, false);
11045 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
11046 FL("Can't start BSS: update channel list failed"));
11047 return eHAL_STATUS_FAILURE;
11048 }
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053011049
11050 /* check if STA is on indoor channel */
11051 if (hdd_is_sta_sap_scc_allowed_on_dfs_chan(pHddCtx))
11052 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011053 }
11054
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011055 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
11056 /* Disable the channels received in command SET_DISABLE_CHANNEL_LIST*/
11057 wlan_hdd_disable_channels(pHddCtx);
11058 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
11059 }
11060
Jeff Johnson295189b2012-06-20 16:38:30 -070011061 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
11062
11063 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
11064
11065 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
11066
11067 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
11068
11069 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
11070
11071 //channel is already set in the set_channel Call back
11072 //pConfig->channel = pCommitConfig->channel;
11073
11074 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011075 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070011076 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
11077
11078 pConfig->dtim_period = pBeacon->dtim_period;
11079
Arif Hussain6d2a3322013-11-17 19:50:10 -080011080 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070011081 pConfig->dtim_period);
11082
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080011083 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070011084 {
11085 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011086 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053011087 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
11088 {
11089 tANI_BOOLEAN restartNeeded;
11090 pConfig->ieee80211d = 1;
11091 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
11092 sme_setRegInfo(hHal, pConfig->countryCode);
11093 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
11094 }
11095 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070011096 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070011097 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070011098 pConfig->ieee80211d = 1;
11099 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
11100 sme_setRegInfo(hHal, pConfig->countryCode);
11101 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070011102 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011103 else
11104 {
11105 pConfig->ieee80211d = 0;
11106 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011107 /*
11108 * If auto channel is configured i.e. channel is 0,
11109 * so skip channel validation.
11110 */
11111 if( AUTO_CHANNEL_SELECT != pConfig->channel )
11112 {
11113 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
11114 {
11115 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011116 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011117 ret = -EINVAL;
11118 goto error;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011119 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011120 pConfig->user_config_channel = pConfig->channel;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011121 }
11122 else
11123 {
11124 if(1 != pHddCtx->is_dynamic_channel_range_set)
11125 {
11126 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
11127 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
11128 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
11129 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011130 pHddCtx->is_dynamic_channel_range_set = 0;
11131 pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011132 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011133 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011134 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011135 {
11136 pConfig->ieee80211d = 0;
11137 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011138
11139#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11140 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11141 pConfig->authType = eSAP_OPEN_SYSTEM;
11142 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11143 pConfig->authType = eSAP_SHARED_KEY;
11144 else
11145 pConfig->authType = eSAP_AUTO_SWITCH;
11146#else
11147 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11148 pConfig->authType = eSAP_OPEN_SYSTEM;
11149 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11150 pConfig->authType = eSAP_SHARED_KEY;
11151 else
11152 pConfig->authType = eSAP_AUTO_SWITCH;
11153#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011154
11155 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011156
11157 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070011158 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053011159#ifdef SAP_AUTH_OFFLOAD
11160 /* In case of sap offload, hostapd.conf is configuted with open mode and
11161 * security is configured from ini file. Due to open mode in hostapd.conf
11162 * privacy bit is set to false which will result in not sending,
11163 * data packets as encrypted.
11164 * If enable_sap_auth_offload is enabled in ini and
11165 * sap_auth_offload_sec_type is type of WPA2-PSK,
11166 * driver will set privacy bit to 1.
11167 */
11168 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
11169 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
11170 pConfig->privacy = VOS_TRUE;
11171#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011172
11173 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
11174
11175 /*Set wps station to configured*/
11176 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
11177
11178 if(pIe)
11179 {
11180 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
11181 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011182 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011183 ret = -EINVAL;
11184 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011185 }
11186 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
11187 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070011188 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070011189 /* Check 15 bit of WPS IE as it contain information for wps state
11190 * WPS state
11191 */
11192 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
11193 {
11194 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
11195 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
11196 {
11197 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
11198 }
11199 }
11200 }
11201 else
11202 {
11203 pConfig->wps_state = SAP_WPS_DISABLED;
11204 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011205 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070011206
c_hpothufe599e92014-06-16 11:38:55 +053011207 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11208 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11209 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
11210 eCSR_ENCRYPT_TYPE_NONE;
11211
Jeff Johnson295189b2012-06-20 16:38:30 -070011212 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053011213 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011214 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011215 WLAN_EID_RSN);
11216 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011217 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011218 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011219 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11220 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11221 pConfig->RSNWPAReqIELength);
11222 else
11223 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11224 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011225 /* The actual processing may eventually be more extensive than
11226 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070011227 * by the app.
11228 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011229 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011230 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11231 &RSNEncryptType,
11232 &mcRSNEncryptType,
11233 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011234 &MFPCapable,
11235 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011236 pConfig->RSNWPAReqIE[1]+2,
11237 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011238
11239 if( VOS_STATUS_SUCCESS == status )
11240 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011241 /* Now copy over all the security attributes you have
11242 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011243 * */
11244 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11245 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11246 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11247 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011248 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011249 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011250 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11251 }
11252 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011253
Jeff Johnson295189b2012-06-20 16:38:30 -070011254 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11255 pBeacon->tail, pBeacon->tail_len);
11256
11257 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
11258 {
Kapil Gupta137ef892016-12-13 19:38:00 +053011259 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011260 {
11261 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053011262 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070011263 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011264 if (pConfig->RSNWPAReqIELength <=
11265 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
11266 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
11267 pIe[1] + 2);
11268 else
11269 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11270 pConfig->RSNWPAReqIELength);
11271
Jeff Johnson295189b2012-06-20 16:38:30 -070011272 }
11273 else
11274 {
11275 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011276 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11277 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11278 pConfig->RSNWPAReqIELength);
11279 else
11280 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11281 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011282 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011283 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11284 &RSNEncryptType,
11285 &mcRSNEncryptType,
11286 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011287 &MFPCapable,
11288 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011289 pConfig->RSNWPAReqIE[1]+2,
11290 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011291
11292 if( VOS_STATUS_SUCCESS == status )
11293 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011294 /* Now copy over all the security attributes you have
11295 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011296 * */
11297 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11298 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11299 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11300 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011301 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011302 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011303 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11304 }
11305 }
11306 }
11307
Kapil Gupta137ef892016-12-13 19:38:00 +053011308 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070011309 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011310 ret = -EINVAL;
11311 goto error;
Jeff Johnson4416a782013-03-25 14:17:50 -070011312 }
11313
Jeff Johnson295189b2012-06-20 16:38:30 -070011314 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
11315
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011316#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011317 if (params->ssid != NULL)
11318 {
11319 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
11320 pConfig->SSIDinfo.ssid.length = params->ssid_len;
11321 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11322 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11323 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011324#else
11325 if (ssid != NULL)
11326 {
11327 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
11328 pConfig->SSIDinfo.ssid.length = ssid_len;
11329 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11330 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11331 }
11332#endif
11333
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011334 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070011335 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011336
Jeff Johnson295189b2012-06-20 16:38:30 -070011337 /* default value */
11338 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
11339 pConfig->num_accept_mac = 0;
11340 pConfig->num_deny_mac = 0;
11341
11342 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11343 pBeacon->tail, pBeacon->tail_len);
11344
11345 /* pIe for black list is following form:
11346 type : 1 byte
11347 length : 1 byte
11348 OUI : 4 bytes
11349 acl type : 1 byte
11350 no of mac addr in black list: 1 byte
11351 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011352 */
11353 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011354 {
11355 pConfig->SapMacaddr_acl = pIe[6];
11356 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011357 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011358 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011359 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
11360 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011361 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11362 for (i = 0; i < pConfig->num_deny_mac; i++)
11363 {
11364 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11365 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011366 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011367 }
11368 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11369 pBeacon->tail, pBeacon->tail_len);
11370
11371 /* pIe for white list is following form:
11372 type : 1 byte
11373 length : 1 byte
11374 OUI : 4 bytes
11375 acl type : 1 byte
11376 no of mac addr in white list: 1 byte
11377 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011378 */
11379 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011380 {
11381 pConfig->SapMacaddr_acl = pIe[6];
11382 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011383 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011384 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011385 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
11386 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011387 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11388 for (i = 0; i < pConfig->num_accept_mac; i++)
11389 {
11390 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11391 acl_entry++;
11392 }
11393 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011394
Jeff Johnson295189b2012-06-20 16:38:30 -070011395 wlan_hdd_set_sapHwmode(pHostapdAdapter);
11396
Jeff Johnsone7245742012-09-05 17:12:55 -070011397#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011398 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011399 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
11400 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053011401 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
11402 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011403 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
11404 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011405 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
11406 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070011407 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011408 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070011409 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011410 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011411
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011412 /* If ACS disable and selected channel <= 14
11413 * OR
11414 * ACS enabled and ACS operating band is choosen as 2.4
11415 * AND
11416 * VHT in 2.4G Disabled
11417 * THEN
11418 * Fallback to 11N mode
11419 */
11420 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
11421 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053011422 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011423 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011424 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011425 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
11426 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011427 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
11428 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011429 }
11430#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011431
Jeff Johnson295189b2012-06-20 16:38:30 -070011432 // ht_capab is not what the name conveys,this is used for protection bitmap
11433 pConfig->ht_capab =
11434 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
11435
Kapil Gupta137ef892016-12-13 19:38:00 +053011436 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070011437 {
11438 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011439 ret = -EINVAL;
11440 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011441 }
11442
11443 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011444 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070011445 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
11446 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011447 pConfig->obssProtEnabled =
11448 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070011449
Chet Lanctot8cecea22014-02-11 19:09:36 -080011450#ifdef WLAN_FEATURE_11W
11451 pConfig->mfpCapable = MFPCapable;
11452 pConfig->mfpRequired = MFPRequired;
11453 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
11454 pConfig->mfpCapable, pConfig->mfpRequired);
11455#endif
11456
Arif Hussain6d2a3322013-11-17 19:50:10 -080011457 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070011458 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011459 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
11460 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
11461 (int)pConfig->channel);
11462 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
11463 pConfig->SapHw_mode, pConfig->privacy,
11464 pConfig->authType);
11465 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
11466 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
11467 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
11468 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070011469
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011470 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070011471 {
11472 //Bss already started. just return.
11473 //TODO Probably it should update some beacon params.
11474 hddLog( LOGE, "Bss Already started...Ignore the request");
11475 EXIT();
11476 return 0;
11477 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011478
Agarwal Ashish51325b52014-06-16 16:50:49 +053011479 if (vos_max_concurrent_connections_reached()) {
11480 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011481 ret = -EINVAL;
11482 goto error;
Agarwal Ashish51325b52014-06-16 16:50:49 +053011483 }
11484
Jeff Johnson295189b2012-06-20 16:38:30 -070011485 pConfig->persona = pHostapdAdapter->device_mode;
11486
Peng Xu2446a892014-09-05 17:21:18 +053011487 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
11488 if ( NULL != psmeConfig)
11489 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011490 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053011491 sme_GetConfigParam(hHal, psmeConfig);
11492 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011493#ifdef WLAN_FEATURE_AP_HT40_24G
11494 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11495 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
11496 && pHddCtx->cfg_ini->apHT40_24GEnabled)
11497 {
11498 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
11499 sme_UpdateConfig (hHal, psmeConfig);
11500 }
11501#endif
Peng Xu2446a892014-09-05 17:21:18 +053011502 vos_mem_free(psmeConfig);
11503 }
Peng Xuafc34e32014-09-25 13:23:55 +053011504 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053011505
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011506 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -070011507 pSapEventCallback = hdd_hostapd_SAPEventCB;
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011508
11509 vos_event_reset(&pHostapdState->vosEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -070011510 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
11511 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
11512 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011513 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011514 ret = -EINVAL;
11515 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011516 }
11517
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011518 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070011519 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
11520
11521 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011522
Jeff Johnson295189b2012-06-20 16:38:30 -070011523 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011524 {
11525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011526 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070011527 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011528 VOS_ASSERT(0);
11529 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011530
Jeff Johnson295189b2012-06-20 16:38:30 -070011531 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053011532 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
11533 VOS_STATUS_SUCCESS)
11534 {
11535 hddLog(LOGE,FL("Fail to get Softap sessionID"));
11536 VOS_ASSERT(0);
11537 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053011538 /* Initialize WMM configuation */
11539 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011540 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011541
Anurag Chouhan83026002016-12-13 22:46:21 +053011542#ifdef DHCP_SERVER_OFFLOAD
11543 /* set dhcp server offload */
11544 if (iniConfig->enable_dhcp_srv_offload &&
11545 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011546 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053011547 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053011548 if (!VOS_IS_STATUS_SUCCESS(status))
11549 {
11550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11551 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011552 vos_event_reset(&pHostapdState->vosEvent);
11553 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11554 status = vos_wait_single_event(&pHostapdState->vosEvent,
11555 10000);
11556 if (!VOS_IS_STATUS_SUCCESS(status)) {
11557 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011558 ret = -EINVAL;
11559 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011560 }
11561 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011562 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011563 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
11564 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
11565 {
11566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11567 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
11568 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011569 vos_event_reset(&pHostapdState->vosEvent);
11570 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11571 status = vos_wait_single_event(&pHostapdState->vosEvent,
11572 10000);
11573 if (!VOS_IS_STATUS_SUCCESS(status)) {
11574 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011575 ret = -EINVAL;
11576 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011577 }
11578 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011579 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011580#ifdef MDNS_OFFLOAD
11581 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011582 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011583 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
11584 if (VOS_IS_STATUS_SUCCESS(status))
11585 {
11586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11587 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011588 vos_event_reset(&pHostapdState->vosEvent);
11589 if (VOS_STATUS_SUCCESS ==
11590 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11591 status = vos_wait_single_event(&pHostapdState->vosEvent,
11592 10000);
11593 if (!VOS_IS_STATUS_SUCCESS(status)) {
11594 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011595 ret = -EINVAL;
11596 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011597 }
11598 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011599 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011600 status = vos_wait_single_event(&pHostapdAdapter->
11601 mdns_status.vos_event, 2000);
11602 if (!VOS_IS_STATUS_SUCCESS(status) ||
11603 pHostapdAdapter->mdns_status.mdns_enable_status ||
11604 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
11605 pHostapdAdapter->mdns_status.mdns_resp_status)
11606 {
11607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11608 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
11609 pHostapdAdapter->mdns_status.mdns_enable_status,
11610 pHostapdAdapter->mdns_status.mdns_fqdn_status,
11611 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011612 vos_event_reset(&pHostapdState->vosEvent);
11613 if (VOS_STATUS_SUCCESS ==
11614 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11615 status = vos_wait_single_event(&pHostapdState->vosEvent,
11616 10000);
11617 if (!VOS_IS_STATUS_SUCCESS(status)) {
11618 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011619 ret = -EINVAL;
11620 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011621 }
11622 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011623 }
11624 }
11625#endif /* MDNS_OFFLOAD */
11626 } else {
11627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11628 ("DHCP Disabled ini %d, FW %d"),
11629 iniConfig->enable_dhcp_srv_offload,
11630 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053011631 }
11632#endif /* DHCP_SERVER_OFFLOAD */
11633
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011634#ifdef WLAN_FEATURE_P2P_DEBUG
11635 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
11636 {
11637 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
11638 {
11639 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11640 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011641 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011642 }
11643 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
11644 {
11645 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11646 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011647 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011648 }
11649 }
11650#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053011651 /* Check and restart SAP if it is on Unsafe channel */
11652 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011653
Jeff Johnson295189b2012-06-20 16:38:30 -070011654 pHostapdState->bCommit = TRUE;
11655 EXIT();
11656
11657 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011658error:
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011659 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11660 wlan_hdd_restore_channels(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011661 /* Revert the indoor to passive marking if START BSS fails */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011662 if (iniConfig->disable_indoor_channel &&
11663 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011664 hdd_update_indoor_channel(pHddCtx, false);
11665 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
11666 }
11667
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011668 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
11669 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011670}
11671
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011672#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011673static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011674 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011675 struct beacon_parameters *params)
11676{
11677 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011678 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011679 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011680
11681 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011682
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011683 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11684 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11685 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011686 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11687 hdd_device_modetoString(pAdapter->device_mode),
11688 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011689
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011690 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11691 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011692 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011693 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011694 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011695 }
11696
Agarwal Ashish51325b52014-06-16 16:50:49 +053011697 if (vos_max_concurrent_connections_reached()) {
11698 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11699 return -EINVAL;
11700 }
11701
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011702 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011703 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011704 )
11705 {
11706 beacon_data_t *old,*new;
11707
11708 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011709
Jeff Johnson295189b2012-06-20 16:38:30 -070011710 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011711 {
11712 hddLog(VOS_TRACE_LEVEL_WARN,
11713 FL("already beacon info added to session(%d)"),
11714 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011715 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011716 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011717
11718 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11719
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011720 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011721 {
11722 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011723 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011724 return -EINVAL;
11725 }
11726
11727 pAdapter->sessionCtx.ap.beacon = new;
11728
11729 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11730 }
11731
11732 EXIT();
11733 return status;
11734}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011735
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011736static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11737 struct net_device *dev,
11738 struct beacon_parameters *params)
11739{
11740 int ret;
11741
11742 vos_ssr_protect(__func__);
11743 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11744 vos_ssr_unprotect(__func__);
11745
11746 return ret;
11747}
11748
11749static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011750 struct net_device *dev,
11751 struct beacon_parameters *params)
11752{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011753 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011754 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11755 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011756 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011757
11758 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011759
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011760 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11761 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11762 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11763 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11764 __func__, hdd_device_modetoString(pAdapter->device_mode),
11765 pAdapter->device_mode);
11766
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011767 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11768 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011769 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011770 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011771 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011772 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011773
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011774 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011775 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011776 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011777 {
11778 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011779
Jeff Johnson295189b2012-06-20 16:38:30 -070011780 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011781
Jeff Johnson295189b2012-06-20 16:38:30 -070011782 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011783 {
11784 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11785 FL("session(%d) old and new heads points to NULL"),
11786 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011787 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011788 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011789
11790 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11791
11792 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011793 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011794 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011795 return -EINVAL;
11796 }
11797
11798 pAdapter->sessionCtx.ap.beacon = new;
11799
11800 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11801 }
11802
11803 EXIT();
11804 return status;
11805}
11806
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011807static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11808 struct net_device *dev,
11809 struct beacon_parameters *params)
11810{
11811 int ret;
11812
11813 vos_ssr_protect(__func__);
11814 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11815 vos_ssr_unprotect(__func__);
11816
11817 return ret;
11818}
11819
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011820#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11821
11822#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011823static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011824 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011825#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011826static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011827 struct net_device *dev)
11828#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011829{
11830 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Vignesh Viswanathan5caacc22018-06-14 17:14:20 +053011831 hdd_adapter_t *staAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011832 hdd_context_t *pHddCtx = NULL;
11833 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011834 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011835 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011836
11837 ENTER();
11838
11839 if (NULL == pAdapter)
11840 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011842 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011843 return -ENODEV;
11844 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011845
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011846 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11847 TRACE_CODE_HDD_CFG80211_STOP_AP,
11848 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011849 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11850 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011851 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011852 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011853 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011854 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011855
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011856 pScanInfo = &pHddCtx->scan_info;
11857
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011858 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11859 __func__, hdd_device_modetoString(pAdapter->device_mode),
11860 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011861
Vignesh Viswanathan5caacc22018-06-14 17:14:20 +053011862 /*
11863 * if a sta connection is in progress in another adapter, disconnect
11864 * the sta and complete the sap operation. sta will reconnect
11865 * after sap stop is done.
11866 */
11867 staAdapter = hdd_get_sta_connection_in_progress(pHddCtx);
11868 if (staAdapter) {
11869 hddLog(LOG1, FL("disconnecting sta with session id: %d"),
11870 staAdapter->sessionId);
11871 wlan_hdd_disconnect(staAdapter, eCSR_DISCONNECT_REASON_DEAUTH);
11872 }
11873
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011874 ret = wlan_hdd_scan_abort(pAdapter);
11875
Girish Gowli4bf7a632014-06-12 13:42:11 +053011876 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011877 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011878 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11879 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011880
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011881 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011882 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011883 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11884 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011885
Jeff Johnsone7245742012-09-05 17:12:55 -070011886 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011887 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011888 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011889 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011890 }
11891
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011892 /* Delete all associated STAs before stopping AP/P2P GO */
11893 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011894 hdd_hostapd_stop(dev);
11895
Jeff Johnson295189b2012-06-20 16:38:30 -070011896 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011897 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011898 )
11899 {
11900 beacon_data_t *old;
11901
11902 old = pAdapter->sessionCtx.ap.beacon;
11903
11904 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011905 {
11906 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11907 FL("session(%d) beacon data points to NULL"),
11908 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011909 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011910 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011911
Jeff Johnson295189b2012-06-20 16:38:30 -070011912 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011913
11914 mutex_lock(&pHddCtx->sap_lock);
11915 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11916 {
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011917 hdd_hostapd_state_t *pHostapdState =
11918 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11919
Abhishek Singh10e17cf2018-03-12 14:34:22 +053011920 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
11921 hdd_wait_for_ecsa_complete(pHddCtx);
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011922 vos_event_reset(&pHostapdState->vosEvent);
11923
Jeff Johnson4416a782013-03-25 14:17:50 -070011924 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011925 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011926 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11927
11928 if (!VOS_IS_STATUS_SUCCESS(status))
11929 {
11930 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011931 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011932 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011933 }
11934 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011935 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011936 /* BSS stopped, clear the active sessions for this device mode */
11937 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011938 }
11939 mutex_unlock(&pHddCtx->sap_lock);
11940
11941 if(status != VOS_STATUS_SUCCESS)
11942 {
11943 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011944 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011945 return -EINVAL;
11946 }
11947
Jeff Johnson4416a782013-03-25 14:17:50 -070011948 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011949 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11950 ==eHAL_STATUS_FAILURE)
11951 {
11952 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011953 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011954 }
11955
Jeff Johnson4416a782013-03-25 14:17:50 -070011956 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011957 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11958 eANI_BOOLEAN_FALSE) )
11959 {
11960 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011961 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011962 }
11963
11964 // Reset WNI_CFG_PROBE_RSP Flags
11965 wlan_hdd_reset_prob_rspies(pAdapter);
11966
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011967 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11968
Jeff Johnson295189b2012-06-20 16:38:30 -070011969 pAdapter->sessionCtx.ap.beacon = NULL;
11970 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011971#ifdef WLAN_FEATURE_P2P_DEBUG
11972 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11973 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11974 {
11975 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11976 "GO got removed");
11977 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11978 }
11979#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011980 }
11981 EXIT();
11982 return status;
11983}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011984
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011985#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11986static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
11987 struct net_device *dev)
11988{
11989 int ret;
11990
11991 vos_ssr_protect(__func__);
11992 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
11993 vos_ssr_unprotect(__func__);
11994
11995 return ret;
11996}
11997#else
11998static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
11999 struct net_device *dev)
12000{
12001 int ret;
12002
12003 vos_ssr_protect(__func__);
12004 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
12005 vos_ssr_unprotect(__func__);
12006
12007 return ret;
12008}
12009#endif
12010
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012011#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
12012
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012013static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012014 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012015 struct cfg80211_ap_settings *params)
12016{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012017 hdd_adapter_t *pAdapter;
12018 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012019 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012020
12021 ENTER();
12022
Girish Gowlib143d7a2015-02-18 19:39:55 +053012023 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012024 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012025 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053012026 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012027 return -ENODEV;
12028 }
12029
12030 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12031 if (NULL == pAdapter)
12032 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012033 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012034 "%s: HDD adapter is Null", __func__);
12035 return -ENODEV;
12036 }
12037
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012038 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12039 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
12040 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012041 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
12042 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012044 "%s: HDD adapter magic is invalid", __func__);
12045 return -ENODEV;
12046 }
12047
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053012048 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
12049
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012050 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012051 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012052 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012053 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012054 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012055 }
12056
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012057 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
12058 __func__, hdd_device_modetoString(pAdapter->device_mode),
12059 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012060
12061 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012062 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012063 )
12064 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012065 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012066
12067 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012068
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012069 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012070 {
12071 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12072 FL("already beacon info added to session(%d)"),
12073 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012074 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012075 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012076
Girish Gowlib143d7a2015-02-18 19:39:55 +053012077#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
12078 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12079 &new,
12080 &params->beacon);
12081#else
12082 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12083 &new,
12084 &params->beacon,
12085 params->dtim_period);
12086#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012087
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012088 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012089 {
12090 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012091 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012092 return -EINVAL;
12093 }
12094 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080012095#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070012096 wlan_hdd_cfg80211_set_channel(wiphy, dev,
12097#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
12098 params->channel, params->channel_type);
12099#else
12100 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
12101#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080012102#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012103 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012104 params->ssid_len, params->hidden_ssid,
12105 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012106 }
12107
12108 EXIT();
12109 return status;
12110}
12111
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012112static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
12113 struct net_device *dev,
12114 struct cfg80211_ap_settings *params)
12115{
12116 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012117
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012118 vos_ssr_protect(__func__);
12119 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
12120 vos_ssr_unprotect(__func__);
12121
12122 return ret;
12123}
12124
12125static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012126 struct net_device *dev,
12127 struct cfg80211_beacon_data *params)
12128{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012129 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012130 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012131 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012132
12133 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012134
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012135 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12136 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
12137 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080012138 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012139 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012140
12141 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12142 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012143 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012144 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012145 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012146 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012147
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012148 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012149 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012150 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012151 {
12152 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012153
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012154 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012155
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012156 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012157 {
12158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12159 FL("session(%d) beacon data points to NULL"),
12160 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012161 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012162 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012163
12164 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
12165
12166 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012167 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012168 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012169 return -EINVAL;
12170 }
12171
12172 pAdapter->sessionCtx.ap.beacon = new;
12173
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012174 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
12175 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012176 }
12177
12178 EXIT();
12179 return status;
12180}
12181
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012182static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
12183 struct net_device *dev,
12184 struct cfg80211_beacon_data *params)
12185{
12186 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012187
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012188 vos_ssr_protect(__func__);
12189 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
12190 vos_ssr_unprotect(__func__);
12191
12192 return ret;
12193}
12194
12195#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070012196
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012197static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012198 struct net_device *dev,
12199 struct bss_parameters *params)
12200{
12201 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012202 hdd_context_t *pHddCtx;
12203 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012204
12205 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012206
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012207 if (NULL == pAdapter)
12208 {
12209 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12210 "%s: HDD adapter is Null", __func__);
12211 return -ENODEV;
12212 }
12213 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012214 ret = wlan_hdd_validate_context(pHddCtx);
12215 if (0 != ret)
12216 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012217 return ret;
12218 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012219 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12220 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
12221 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012222 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12223 __func__, hdd_device_modetoString(pAdapter->device_mode),
12224 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012225
12226 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012227 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012228 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012229 {
12230 /* ap_isolate == -1 means that in change bss, upper layer doesn't
12231 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012232 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070012233 {
12234 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012235 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012236 }
12237
12238 EXIT();
12239 return 0;
12240}
12241
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012242static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
12243 struct net_device *dev,
12244 struct bss_parameters *params)
12245{
12246 int ret;
12247
12248 vos_ssr_protect(__func__);
12249 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
12250 vos_ssr_unprotect(__func__);
12251
12252 return ret;
12253}
Kiet Lam10841362013-11-01 11:36:50 +053012254/* FUNCTION: wlan_hdd_change_country_code_cd
12255* to wait for contry code completion
12256*/
12257void* wlan_hdd_change_country_code_cb(void *pAdapter)
12258{
12259 hdd_adapter_t *call_back_pAdapter = pAdapter;
12260 complete(&call_back_pAdapter->change_country_code);
12261 return NULL;
12262}
12263
Jeff Johnson295189b2012-06-20 16:38:30 -070012264/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012265 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070012266 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
12267 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012268int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012269 struct net_device *ndev,
12270 enum nl80211_iftype type,
12271 u32 *flags,
12272 struct vif_params *params
12273 )
12274{
12275 struct wireless_dev *wdev;
12276 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012277 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070012278 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012279 tCsrRoamProfile *pRoamProfile = NULL;
12280 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012281 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012282 eMib_dot11DesiredBssType connectedBssType;
12283 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012284 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012285
12286 ENTER();
12287
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012288 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012289 {
12290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12291 "%s: Adapter context is null", __func__);
12292 return VOS_STATUS_E_FAILURE;
12293 }
12294
12295 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12296 if (!pHddCtx)
12297 {
12298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12299 "%s: HDD context is null", __func__);
12300 return VOS_STATUS_E_FAILURE;
12301 }
12302
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012303 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12304 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
12305 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012306 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012307 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012308 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012309 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012310 }
12311
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012312 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12313 __func__, hdd_device_modetoString(pAdapter->device_mode),
12314 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012315
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012316 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
12317 hddLog(VOS_TRACE_LEVEL_FATAL,
12318 "%s: STA + MON is in progress, cannot change interface",
12319 __func__);
12320 }
12321
Agarwal Ashish51325b52014-06-16 16:50:49 +053012322 if (vos_max_concurrent_connections_reached()) {
12323 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12324 return -EINVAL;
12325 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012326 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012327 wdev = ndev->ieee80211_ptr;
12328
12329#ifdef WLAN_BTAMP_FEATURE
12330 if((NL80211_IFTYPE_P2P_CLIENT == type)||
12331 (NL80211_IFTYPE_ADHOC == type)||
12332 (NL80211_IFTYPE_AP == type)||
12333 (NL80211_IFTYPE_P2P_GO == type))
12334 {
12335 pHddCtx->isAmpAllowed = VOS_FALSE;
12336 // stop AMP traffic
12337 status = WLANBAP_StopAmp();
12338 if(VOS_STATUS_SUCCESS != status )
12339 {
12340 pHddCtx->isAmpAllowed = VOS_TRUE;
12341 hddLog(VOS_TRACE_LEVEL_FATAL,
12342 "%s: Failed to stop AMP", __func__);
12343 return -EINVAL;
12344 }
12345 }
12346#endif //WLAN_BTAMP_FEATURE
12347 /* Reset the current device mode bit mask*/
12348 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
12349
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053012350 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
12351 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
12352 (type == NL80211_IFTYPE_P2P_GO)))
12353 {
12354 /* Notify Mode change in case of concurrency.
12355 * Below function invokes TDLS teardown Functionality Since TDLS is
12356 * not Supported in case of concurrency i.e Once P2P session
12357 * is detected disable offchannel and teardown TDLS links
12358 */
12359 hddLog(LOG1,
12360 FL("Device mode = %d Interface type = %d"),
12361 pAdapter->device_mode, type);
12362 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
12363 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053012364
Jeff Johnson295189b2012-06-20 16:38:30 -070012365 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012366 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070012367 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012368 )
12369 {
12370 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012371 if (!pWextState)
12372 {
12373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12374 "%s: pWextState is null", __func__);
12375 return VOS_STATUS_E_FAILURE;
12376 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012377 pRoamProfile = &pWextState->roamProfile;
12378 LastBSSType = pRoamProfile->BSSType;
12379
12380 switch (type)
12381 {
12382 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012383 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012384 hddLog(VOS_TRACE_LEVEL_INFO,
12385 "%s: setting interface Type to INFRASTRUCTURE", __func__);
12386 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012387#ifdef WLAN_FEATURE_11AC
12388 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
12389 {
12390 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
12391 }
12392#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012393 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070012394 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012395 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012396 //Check for sub-string p2p to confirm its a p2p interface
12397 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012398 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053012399#ifdef FEATURE_WLAN_TDLS
12400 mutex_lock(&pHddCtx->tdls_lock);
12401 wlan_hdd_tdls_exit(pAdapter, TRUE);
12402 mutex_unlock(&pHddCtx->tdls_lock);
12403#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012404 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12405 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12406 }
12407 else
12408 {
12409 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012410 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012411 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012412 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053012413
Jeff Johnson295189b2012-06-20 16:38:30 -070012414 case NL80211_IFTYPE_ADHOC:
12415 hddLog(VOS_TRACE_LEVEL_INFO,
12416 "%s: setting interface Type to ADHOC", __func__);
12417 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
12418 pRoamProfile->phyMode =
12419 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070012420 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012421 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053012422 hdd_set_ibss_ops( pAdapter );
12423 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053012424
12425 status = hdd_sta_id_hash_attach(pAdapter);
12426 if (VOS_STATUS_SUCCESS != status) {
12427 hddLog(VOS_TRACE_LEVEL_ERROR,
12428 FL("Failed to initialize hash for IBSS"));
12429 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012430 break;
12431
12432 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012433 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012434 {
12435 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12436 "%s: setting interface Type to %s", __func__,
12437 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
12438
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012439 //Cancel any remain on channel for GO mode
12440 if (NL80211_IFTYPE_P2P_GO == type)
12441 {
12442 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
12443 }
Mohit Khanna0f232092012-09-11 14:46:08 -070012444 if (NL80211_IFTYPE_AP == type)
12445 {
12446 /* As Loading WLAN Driver one interface being created for p2p device
12447 * address. This will take one HW STA and the max number of clients
12448 * that can connect to softAP will be reduced by one. so while changing
12449 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
12450 * interface as it is not required in SoftAP mode.
12451 */
12452
12453 // Get P2P Adapter
12454 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
12455
12456 if (pP2pAdapter)
12457 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053012458 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053012459 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070012460 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12461 }
12462 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053012463 //Disable IMPS & BMPS for SAP/GO
12464 if(VOS_STATUS_E_FAILURE ==
12465 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
12466 {
12467 //Fail to Exit BMPS
12468 VOS_ASSERT(0);
12469 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053012470
12471 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
12472
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012473#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070012474
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012475 /* A Mutex Lock is introduced while changing the mode to
12476 * protect the concurrent access for the Adapters by TDLS
12477 * module.
12478 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012479 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012480#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012481 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053012482 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012483 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070012484 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12485 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012486#ifdef FEATURE_WLAN_TDLS
12487 mutex_unlock(&pHddCtx->tdls_lock);
12488#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012489 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
12490 (pConfig->apRandomBssidEnabled))
12491 {
12492 /* To meet Android requirements create a randomized
12493 MAC address of the form 02:1A:11:Fx:xx:xx */
12494 get_random_bytes(&ndev->dev_addr[3], 3);
12495 ndev->dev_addr[0] = 0x02;
12496 ndev->dev_addr[1] = 0x1A;
12497 ndev->dev_addr[2] = 0x11;
12498 ndev->dev_addr[3] |= 0xF0;
12499 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
12500 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080012501 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
12502 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012503 }
12504
Jeff Johnson295189b2012-06-20 16:38:30 -070012505 hdd_set_ap_ops( pAdapter->dev );
12506
Kiet Lam10841362013-11-01 11:36:50 +053012507 /* This is for only SAP mode where users can
12508 * control country through ini.
12509 * P2P GO follows station country code
12510 * acquired during the STA scanning. */
12511 if((NL80211_IFTYPE_AP == type) &&
12512 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
12513 {
12514 int status = 0;
12515 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
12516 "%s: setting country code from INI ", __func__);
12517 init_completion(&pAdapter->change_country_code);
12518 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
12519 (void *)(tSmeChangeCountryCallback)
12520 wlan_hdd_change_country_code_cb,
12521 pConfig->apCntryCode, pAdapter,
12522 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012523 eSIR_FALSE,
12524 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053012525 if (eHAL_STATUS_SUCCESS == status)
12526 {
12527 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012528 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053012529 &pAdapter->change_country_code,
12530 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012531 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053012532 {
12533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012534 FL("SME Timed out while setting country code %ld"),
12535 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080012536
12537 if (pHddCtx->isLogpInProgress)
12538 {
12539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12540 "%s: LOGP in Progress. Ignore!!!", __func__);
12541 return -EAGAIN;
12542 }
Kiet Lam10841362013-11-01 11:36:50 +053012543 }
12544 }
12545 else
12546 {
12547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012548 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053012549 return -EINVAL;
12550 }
12551 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053012552 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070012553 if(status != VOS_STATUS_SUCCESS)
12554 {
12555 hddLog(VOS_TRACE_LEVEL_FATAL,
12556 "%s: Error initializing the ap mode", __func__);
12557 return -EINVAL;
12558 }
12559 hdd_set_conparam(1);
12560
Nirav Shah7e3c8132015-06-22 23:51:42 +053012561 status = hdd_sta_id_hash_attach(pAdapter);
12562 if (VOS_STATUS_SUCCESS != status)
12563 {
12564 hddLog(VOS_TRACE_LEVEL_ERROR,
12565 FL("Failed to initialize hash for AP"));
12566 return -EINVAL;
12567 }
12568
Jeff Johnson295189b2012-06-20 16:38:30 -070012569 /*interface type changed update in wiphy structure*/
12570 if(wdev)
12571 {
12572 wdev->iftype = type;
12573 pHddCtx->change_iface = type;
12574 }
12575 else
12576 {
12577 hddLog(VOS_TRACE_LEVEL_ERROR,
12578 "%s: ERROR !!!! Wireless dev is NULL", __func__);
12579 return -EINVAL;
12580 }
12581 goto done;
12582 }
12583
12584 default:
12585 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12586 __func__);
12587 return -EOPNOTSUPP;
12588 }
12589 }
12590 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012591 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070012592 )
12593 {
12594 switch(type)
12595 {
12596 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012597 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012598 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053012599
12600 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012601#ifdef FEATURE_WLAN_TDLS
12602
12603 /* A Mutex Lock is introduced while changing the mode to
12604 * protect the concurrent access for the Adapters by TDLS
12605 * module.
12606 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012607 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012608#endif
c_hpothu002231a2015-02-05 14:58:51 +053012609 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012610 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012611 //Check for sub-string p2p to confirm its a p2p interface
12612 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012613 {
12614 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12615 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12616 }
12617 else
12618 {
12619 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012620 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012621 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053012622
12623 /* set con_mode to STA only when no SAP concurrency mode */
12624 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
12625 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012626 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012627 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
12628 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012629#ifdef FEATURE_WLAN_TDLS
12630 mutex_unlock(&pHddCtx->tdls_lock);
12631#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053012632 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070012633 if( VOS_STATUS_SUCCESS != status )
12634 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070012635 /* In case of JB, for P2P-GO, only change interface will be called,
12636 * This is the right place to enable back bmps_imps()
12637 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012638 if (pHddCtx->hdd_wlan_suspended)
12639 {
12640 hdd_set_pwrparams(pHddCtx);
12641 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012642 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012643 goto done;
12644 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012645 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012646 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012647 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12648 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012649 goto done;
12650 default:
12651 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12652 __func__);
12653 return -EOPNOTSUPP;
12654
12655 }
12656
12657 }
12658 else
12659 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012660 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
12661 __func__, hdd_device_modetoString(pAdapter->device_mode),
12662 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012663 return -EOPNOTSUPP;
12664 }
12665
12666
12667 if(pRoamProfile)
12668 {
12669 if ( LastBSSType != pRoamProfile->BSSType )
12670 {
12671 /*interface type changed update in wiphy structure*/
12672 wdev->iftype = type;
12673
12674 /*the BSS mode changed, We need to issue disconnect
12675 if connected or in IBSS disconnect state*/
12676 if ( hdd_connGetConnectedBssType(
12677 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
12678 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
12679 {
12680 /*need to issue a disconnect to CSR.*/
12681 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12682 if( eHAL_STATUS_SUCCESS ==
12683 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12684 pAdapter->sessionId,
12685 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12686 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012687 ret = wait_for_completion_interruptible_timeout(
12688 &pAdapter->disconnect_comp_var,
12689 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12690 if (ret <= 0)
12691 {
12692 hddLog(VOS_TRACE_LEVEL_ERROR,
12693 FL("wait on disconnect_comp_var failed %ld"), ret);
12694 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012695 }
12696 }
12697 }
12698 }
12699
12700done:
12701 /*set bitmask based on updated value*/
12702 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012703
12704 /* Only STA mode support TM now
12705 * all other mode, TM feature should be disabled */
12706 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12707 (~VOS_STA & pHddCtx->concurrency_mode) )
12708 {
12709 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12710 }
12711
Jeff Johnson295189b2012-06-20 16:38:30 -070012712#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012713 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012714 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012715 {
12716 //we are ok to do AMP
12717 pHddCtx->isAmpAllowed = VOS_TRUE;
12718 }
12719#endif //WLAN_BTAMP_FEATURE
12720 EXIT();
12721 return 0;
12722}
12723
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012724/*
12725 * FUNCTION: wlan_hdd_cfg80211_change_iface
12726 * wrapper function to protect the actual implementation from SSR.
12727 */
12728int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12729 struct net_device *ndev,
12730 enum nl80211_iftype type,
12731 u32 *flags,
12732 struct vif_params *params
12733 )
12734{
12735 int ret;
12736
12737 vos_ssr_protect(__func__);
12738 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12739 vos_ssr_unprotect(__func__);
12740
12741 return ret;
12742}
12743
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012744#ifdef FEATURE_WLAN_TDLS
12745static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012746 struct net_device *dev,
12747#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12748 const u8 *mac,
12749#else
12750 u8 *mac,
12751#endif
12752 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012753{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012754 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012755 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012756 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012757 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012758 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012759 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012760
12761 ENTER();
12762
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012763 if (!dev) {
12764 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12765 return -EINVAL;
12766 }
12767
12768 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12769 if (!pAdapter) {
12770 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12771 return -EINVAL;
12772 }
12773
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012774 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012775 {
12776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12777 "Invalid arguments");
12778 return -EINVAL;
12779 }
Hoonki Lee27511902013-03-14 18:19:06 -070012780
12781 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12782 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12783 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012784 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012785 "%s: TDLS mode is disabled OR not enabled in FW."
12786 MAC_ADDRESS_STR " Request declined.",
12787 __func__, MAC_ADDR_ARRAY(mac));
12788 return -ENOTSUPP;
12789 }
12790
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012791 if (pHddCtx->isLogpInProgress)
12792 {
12793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12794 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012795 wlan_hdd_tdls_set_link_status(pAdapter,
12796 mac,
12797 eTDLS_LINK_IDLE,
12798 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012799 return -EBUSY;
12800 }
12801
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012802 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012803 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012804
12805 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012807 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12808 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012809 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012810 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012811 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012812
12813 /* in add station, we accept existing valid staId if there is */
12814 if ((0 == update) &&
12815 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12816 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012817 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012818 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012819 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012820 " link_status %d. staId %d. add station ignored.",
12821 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012822 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012823 return 0;
12824 }
12825 /* in change station, we accept only when staId is valid */
12826 if ((1 == update) &&
12827 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12828 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12829 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012830 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012832 "%s: " MAC_ADDRESS_STR
12833 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012834 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12835 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12836 mutex_unlock(&pHddCtx->tdls_lock);
12837 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012838 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012839 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012840
12841 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012842 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012843 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12845 "%s: " MAC_ADDRESS_STR
12846 " TDLS setup is ongoing. Request declined.",
12847 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012848 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012849 }
12850
12851 /* first to check if we reached to maximum supported TDLS peer.
12852 TODO: for now, return -EPERM looks working fine,
12853 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012854 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12855 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012856 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12858 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012859 " TDLS Max peer already connected. Request declined."
12860 " Num of peers (%d), Max allowed (%d).",
12861 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12862 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012863 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012864 }
12865 else
12866 {
12867 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012868 mutex_lock(&pHddCtx->tdls_lock);
12869 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012870 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012871 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012872 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12874 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12875 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012876 return -EPERM;
12877 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012878 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012879 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012880 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012881 wlan_hdd_tdls_set_link_status(pAdapter,
12882 mac,
12883 eTDLS_LINK_CONNECTING,
12884 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012885
Jeff Johnsond75fe012013-04-06 10:53:06 -070012886 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012887 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012888 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012889 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012890 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012891 if(StaParams->htcap_present)
12892 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012894 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012895 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012896 "ht_capa->extended_capabilities: %0x",
12897 StaParams->HTCap.extendedHtCapInfo);
12898 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012900 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012902 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012903 if(StaParams->vhtcap_present)
12904 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012905 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012906 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12907 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12908 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12909 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012910 {
12911 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012912 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012913 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012915 "[%d]: %x ", i, StaParams->supported_rates[i]);
12916 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012917 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012918 else if ((1 == update) && (NULL == StaParams))
12919 {
12920 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12921 "%s : update is true, but staParams is NULL. Error!", __func__);
12922 return -EPERM;
12923 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012924
12925 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12926
12927 if (!update)
12928 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012929 /*Before adding sta make sure that device exited from BMPS*/
12930 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12931 {
12932 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12933 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12934 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12935 if (status != VOS_STATUS_SUCCESS) {
12936 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12937 }
12938 }
12939
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012940 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012941 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012942 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012943 hddLog(VOS_TRACE_LEVEL_ERROR,
12944 FL("Failed to add TDLS peer STA. Enable Bmps"));
12945 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012946 return -EPERM;
12947 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012948 }
12949 else
12950 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012951 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012952 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012953 if (ret != eHAL_STATUS_SUCCESS) {
12954 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12955 return -EPERM;
12956 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012957 }
12958
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012959 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012960 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12961
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012962 mutex_lock(&pHddCtx->tdls_lock);
12963 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12964
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012965 if ((pTdlsPeer != NULL) &&
12966 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012967 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012968 hddLog(VOS_TRACE_LEVEL_ERROR,
12969 FL("peer link status %u"), pTdlsPeer->link_status);
12970 mutex_unlock(&pHddCtx->tdls_lock);
12971 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012972 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012973 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012974
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012975 if (ret <= 0)
12976 {
12977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12978 "%s: timeout waiting for tdls add station indication %ld",
12979 __func__, ret);
12980 goto error;
12981 }
12982
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012983 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12984 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012986 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012987 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012988 }
12989
12990 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012991
12992error:
Atul Mittal115287b2014-07-08 13:26:33 +053012993 wlan_hdd_tdls_set_link_status(pAdapter,
12994 mac,
12995 eTDLS_LINK_IDLE,
12996 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012997 return -EPERM;
12998
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012999}
13000#endif
13001
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013002VOS_STATUS wlan_hdd_send_sta_authorized_event(
13003 hdd_adapter_t *adapter,
13004 hdd_context_t *hdd_ctx,
13005 const v_MACADDR_t *mac_addr)
13006{
13007 struct sk_buff *vendor_event;
13008 uint32_t sta_flags = 0;
13009 VOS_STATUS status;
13010
13011 ENTER();
13012
13013 if (!hdd_ctx) {
13014 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null"));
13015 return -EINVAL;
13016 }
13017
13018 vendor_event =
13019 cfg80211_vendor_event_alloc(
Ashish Kumar Dhanotiyac99fbef2018-04-11 12:23:32 +053013020 hdd_ctx->wiphy,
13021#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
13022 &adapter->wdev,
13023#endif
13024 sizeof(sta_flags) +
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013025 VOS_MAC_ADDR_SIZE + NLMSG_HDRLEN,
13026 QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX,
13027 GFP_KERNEL);
13028 if (!vendor_event) {
13029 hddLog(VOS_TRACE_LEVEL_ERROR,
13030 FL("cfg80211_vendor_event_alloc failed"));
13031 return -EINVAL;
13032 }
13033
13034 sta_flags |= BIT(NL80211_STA_FLAG_AUTHORIZED);
13035
13036 status = nla_put_u32(vendor_event,
13037 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS,
13038 sta_flags);
13039 if (status) {
13040 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA flag put fails"));
13041 kfree_skb(vendor_event);
13042 return VOS_STATUS_E_FAILURE;
13043 }
13044 status = nla_put(vendor_event,
13045 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_MAC,
13046 VOS_MAC_ADDR_SIZE, mac_addr->bytes);
13047 if (status) {
13048 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA MAC put fails"));
13049 kfree_skb(vendor_event);
13050 return VOS_STATUS_E_FAILURE;
13051 }
13052
13053 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
13054
13055 EXIT();
13056 return 0;
13057}
13058
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013059static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013060 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013061#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13062 const u8 *mac,
13063#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013064 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013065#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013066 struct station_parameters *params)
13067{
13068 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013069 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013070 hdd_context_t *pHddCtx;
13071 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013072 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013073 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013074#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013075 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013076 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013077 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013078 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013079#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013080
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013081 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013082
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013083 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013084 if ((NULL == pAdapter))
13085 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013086 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013087 "invalid adapter ");
13088 return -EINVAL;
13089 }
13090
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013091 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13092 TRACE_CODE_HDD_CHANGE_STATION,
13093 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053013094 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013095
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013096 ret = wlan_hdd_validate_context(pHddCtx);
13097 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053013098 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013099 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013100 }
13101
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013102 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13103
13104 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013105 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013106 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13107 "invalid HDD station context");
13108 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013109 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013110 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
13111
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013112 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
13113 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070013114 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013115 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070013116 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013117 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070013118 WLANTL_STA_AUTHENTICATED);
13119
Gopichand Nakkala29149562013-05-10 21:43:41 +053013120 if (status != VOS_STATUS_SUCCESS)
13121 {
13122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13123 "%s: Not able to change TL state to AUTHENTICATED", __func__);
13124 return -EINVAL;
13125 }
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013126 status = wlan_hdd_send_sta_authorized_event(pAdapter, pHddCtx,
13127 &STAMacAddress);
13128 if (status != VOS_STATUS_SUCCESS)
13129 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013130 }
13131 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070013132 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
13133 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013134#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013135 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13136 StaParams.capability = params->capability;
13137 StaParams.uapsd_queues = params->uapsd_queues;
13138 StaParams.max_sp = params->max_sp;
13139
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013140 /* Convert (first channel , number of channels) tuple to
13141 * the total list of channels. This goes with the assumption
13142 * that if the first channel is < 14, then the next channels
13143 * are an incremental of 1 else an incremental of 4 till the number
13144 * of channels.
13145 */
13146 if (0 != params->supported_channels_len) {
13147 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013148 for ( i = 0 ; i < params->supported_channels_len
13149 && j < SIR_MAC_MAX_SUPP_CHANNELS; i+=2)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013150 {
13151 int wifi_chan_index;
13152 StaParams.supported_channels[j] = params->supported_channels[i];
13153 wifi_chan_index =
13154 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
13155 no_of_channels = params->supported_channels[i+1];
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013156 for(k=1; k <= no_of_channels
13157 && j < SIR_MAC_MAX_SUPP_CHANNELS - 1; k++)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013158 {
13159 StaParams.supported_channels[j+1] =
13160 StaParams.supported_channels[j] + wifi_chan_index;
13161 j+=1;
13162 }
13163 }
13164 StaParams.supported_channels_len = j;
13165 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053013166 if (params->supported_oper_classes_len >
13167 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
13168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13169 "received oper classes:%d, resetting it to max supported %d",
13170 params->supported_oper_classes_len,
13171 SIR_MAC_MAX_SUPP_OPER_CLASSES);
13172 params->supported_oper_classes_len =
13173 SIR_MAC_MAX_SUPP_OPER_CLASSES;
13174 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013175 vos_mem_copy(StaParams.supported_oper_classes,
13176 params->supported_oper_classes,
13177 params->supported_oper_classes_len);
13178 StaParams.supported_oper_classes_len =
13179 params->supported_oper_classes_len;
13180
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013181 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
13182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13183 "received extn capabilities:%d, resetting it to max supported",
13184 params->ext_capab_len);
13185 params->ext_capab_len = sizeof(StaParams.extn_capability);
13186 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013187 if (0 != params->ext_capab_len)
13188 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013189 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013190
13191 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013192 {
13193 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013194 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013195 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013196
13197 StaParams.supported_rates_len = params->supported_rates_len;
13198
13199 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
13200 * The supported_rates array , for all the structures propogating till Add Sta
13201 * to the firmware has to be modified , if the supplicant (ieee80211) is
13202 * modified to send more rates.
13203 */
13204
13205 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
13206 */
13207 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
13208 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
13209
13210 if (0 != StaParams.supported_rates_len) {
13211 int i = 0;
13212 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
13213 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013215 "Supported Rates with Length %d", StaParams.supported_rates_len);
13216 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013217 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013218 "[%d]: %0x", i, StaParams.supported_rates[i]);
13219 }
13220
13221 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013222 {
13223 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013224 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013225 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013226
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013227 if (0 != params->ext_capab_len ) {
13228 /*Define A Macro : TODO Sunil*/
13229 if ((1<<4) & StaParams.extn_capability[3]) {
13230 isBufSta = 1;
13231 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013232 /* TDLS Channel Switching Support */
13233 if ((1<<6) & StaParams.extn_capability[3]) {
13234 isOffChannelSupported = 1;
13235 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013236 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013237
13238 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053013239 (params->ht_capa || params->vht_capa ||
13240 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013241 /* TDLS Peer is WME/QoS capable */
13242 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013243
13244 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13245 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
13246 __func__, isQosWmmSta, StaParams.htcap_present);
13247
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013248 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
13249 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013250 isOffChannelSupported,
13251 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013252
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013253 if (VOS_STATUS_SUCCESS != status) {
13254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13255 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
13256 return -EINVAL;
13257 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013258 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
13259
13260 if (VOS_STATUS_SUCCESS != status) {
13261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13262 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
13263 return -EINVAL;
13264 }
13265 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013266#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053013267 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013268 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013269 return status;
13270}
13271
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013272#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13273static int wlan_hdd_change_station(struct wiphy *wiphy,
13274 struct net_device *dev,
13275 const u8 *mac,
13276 struct station_parameters *params)
13277#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013278static int wlan_hdd_change_station(struct wiphy *wiphy,
13279 struct net_device *dev,
13280 u8 *mac,
13281 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013282#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013283{
13284 int ret;
13285
13286 vos_ssr_protect(__func__);
13287 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
13288 vos_ssr_unprotect(__func__);
13289
13290 return ret;
13291}
13292
Jeff Johnson295189b2012-06-20 16:38:30 -070013293/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013294 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013295 * This function is used to initialize the key information
13296 */
13297#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013298static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013299 struct net_device *ndev,
13300 u8 key_index, bool pairwise,
13301 const u8 *mac_addr,
13302 struct key_params *params
13303 )
13304#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013305static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013306 struct net_device *ndev,
13307 u8 key_index, const u8 *mac_addr,
13308 struct key_params *params
13309 )
13310#endif
13311{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013312 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013313 tCsrRoamSetKey setKey;
13314 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013315 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013316 v_U32_t roamId= 0xFF;
13317 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013318 hdd_hostapd_state_t *pHostapdState;
13319 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013320 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013321 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013322 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013323 v_MACADDR_t *peerMacAddr;
13324 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013325 uint8_t staid = HDD_MAX_STA_COUNT;
13326 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013327
13328 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013329
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013330 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13331 TRACE_CODE_HDD_CFG80211_ADD_KEY,
13332 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013333 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13334 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013335 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013336 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013337 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013338 }
13339
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013340 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13341 __func__, hdd_device_modetoString(pAdapter->device_mode),
13342 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013343
13344 if (CSR_MAX_NUM_KEY <= key_index)
13345 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013346 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013347 key_index);
13348
13349 return -EINVAL;
13350 }
13351
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013352 if (CSR_MAX_KEY_LEN < params->key_len)
13353 {
13354 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
13355 params->key_len);
13356
13357 return -EINVAL;
13358 }
13359
Jingxiang Gec438aea2017-10-26 16:44:00 +080013360 if (CSR_MAX_RSC_LEN < params->seq_len)
13361 {
13362 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
13363 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053013364
13365 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080013366 }
13367
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013368 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080013369 "%s: called with key index = %d & key length %d & seq length %d",
13370 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013371
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013372 peerMacAddr = (v_MACADDR_t *)mac_addr;
13373
Jeff Johnson295189b2012-06-20 16:38:30 -070013374 /*extract key idx, key len and key*/
13375 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13376 setKey.keyId = key_index;
13377 setKey.keyLength = params->key_len;
13378 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080013379 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013380
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013381 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013382 {
13383 case WLAN_CIPHER_SUITE_WEP40:
13384 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13385 break;
13386
13387 case WLAN_CIPHER_SUITE_WEP104:
13388 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
13389 break;
13390
13391 case WLAN_CIPHER_SUITE_TKIP:
13392 {
13393 u8 *pKey = &setKey.Key[0];
13394 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
13395
13396 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
13397
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013398 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070013399
13400 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013401 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013402 |--------------|----------|----------|
13403 <---16bytes---><--8bytes--><--8bytes-->
13404
13405 */
13406 /*Sme expects the 32 bytes key to be in the below order
13407
13408 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013409 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013410 |--------------|----------|----------|
13411 <---16bytes---><--8bytes--><--8bytes-->
13412 */
13413 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013414 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070013415
13416 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013417 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013418
13419 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013420 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013421
13422
13423 break;
13424 }
13425
13426 case WLAN_CIPHER_SUITE_CCMP:
13427 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
13428 break;
13429
13430#ifdef FEATURE_WLAN_WAPI
13431 case WLAN_CIPHER_SUITE_SMS4:
13432 {
13433 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13434 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
13435 params->key, params->key_len);
13436 return 0;
13437 }
13438#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013439
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013440#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013441 case WLAN_CIPHER_SUITE_KRK:
13442 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
13443 break;
13444#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013445
13446#ifdef WLAN_FEATURE_11W
13447 case WLAN_CIPHER_SUITE_AES_CMAC:
13448 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070013449 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070013450#endif
13451
Jeff Johnson295189b2012-06-20 16:38:30 -070013452 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013453 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070013454 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013455 status = -EOPNOTSUPP;
13456 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013457 }
13458
13459 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
13460 __func__, setKey.encType);
13461
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013462 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070013463#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13464 (!pairwise)
13465#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013466 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013467#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013468 )
13469 {
13470 /* set group key*/
13471 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13472 "%s- %d: setting Broadcast key",
13473 __func__, __LINE__);
13474 setKey.keyDirection = eSIR_RX_ONLY;
13475 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13476 }
13477 else
13478 {
13479 /* set pairwise key*/
13480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13481 "%s- %d: setting pairwise key",
13482 __func__, __LINE__);
13483 setKey.keyDirection = eSIR_TX_RX;
13484 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013485 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013486 }
13487 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
13488 {
13489 setKey.keyDirection = eSIR_TX_RX;
13490 /*Set the group key*/
13491 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13492 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070013493
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013494 if ( 0 != status )
13495 {
13496 hddLog(VOS_TRACE_LEVEL_ERROR,
13497 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013498 status = -EINVAL;
13499 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013500 }
13501 /*Save the keys here and call sme_RoamSetKey for setting
13502 the PTK after peer joins the IBSS network*/
13503 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
13504 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013505 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013506 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053013507 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
13508 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
13509 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013510 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013511 if( pHostapdState->bssState == BSS_START )
13512 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013513 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13514 vos_status = wlan_hdd_check_ula_done(pAdapter);
13515
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013516 if (peerMacAddr && (pairwise_set_key == true))
13517 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013518
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013519 if ( vos_status != VOS_STATUS_SUCCESS )
13520 {
13521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13522 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13523 __LINE__, vos_status );
13524
13525 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13526
13527 status = -EINVAL;
13528 goto end;
13529 }
13530
Jeff Johnson295189b2012-06-20 16:38:30 -070013531 status = WLANSAP_SetKeySta( pVosContext, &setKey);
13532
13533 if ( status != eHAL_STATUS_SUCCESS )
13534 {
13535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13536 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13537 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013538 status = -EINVAL;
13539 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013540 }
13541 }
13542
13543 /* Saving WEP keys */
13544 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
13545 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
13546 {
13547 //Save the wep key in ap context. Issue setkey after the BSS is started.
13548 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13549 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
13550 }
13551 else
13552 {
13553 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013554 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013555 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
13556 }
13557 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013558 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
13559 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013560 {
13561 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13562 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13563
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013564#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13565 if (!pairwise)
13566#else
13567 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
13568#endif
13569 {
13570 /* set group key*/
13571 if (pHddStaCtx->roam_info.deferKeyComplete)
13572 {
13573 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13574 "%s- %d: Perform Set key Complete",
13575 __func__, __LINE__);
13576 hdd_PerformRoamSetKeyComplete(pAdapter);
13577 }
13578 }
13579
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013580 if (pairwise_set_key == true)
13581 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013582
Jeff Johnson295189b2012-06-20 16:38:30 -070013583 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
13584
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080013585 pWextState->roamProfile.Keys.defaultIndex = key_index;
13586
13587
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013588 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013589 params->key, params->key_len);
13590
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013591
Jeff Johnson295189b2012-06-20 16:38:30 -070013592 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13593
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013594 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013595 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013596 __func__, setKey.peerMac[0], setKey.peerMac[1],
13597 setKey.peerMac[2], setKey.peerMac[3],
13598 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013599 setKey.keyDirection);
13600
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013601 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053013602
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013603 if ( vos_status != VOS_STATUS_SUCCESS )
13604 {
13605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013606 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13607 __LINE__, vos_status );
13608
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013609 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013610
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013611 status = -EINVAL;
13612 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013613
13614 }
13615
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013616#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013617 /* The supplicant may attempt to set the PTK once pre-authentication
13618 is done. Save the key in the UMAC and include it in the ADD BSS
13619 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013620 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013621 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013622 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013623 hddLog(VOS_TRACE_LEVEL_INFO_MED,
13624 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013625 status = 0;
13626 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013627 }
13628 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
13629 {
13630 hddLog(VOS_TRACE_LEVEL_ERROR,
13631 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013632 status = -EINVAL;
13633 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013634 }
13635#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070013636
13637 /* issue set key request to SME*/
13638 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13639 pAdapter->sessionId, &setKey, &roamId );
13640
13641 if ( 0 != status )
13642 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013643 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013644 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
13645 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013646 status = -EINVAL;
13647 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013648 }
13649
13650
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013651 /* in case of IBSS as there was no information available about WEP keys during
13652 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070013653 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013654 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
13655 !( ( IW_AUTH_KEY_MGMT_802_1X
13656 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070013657 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
13658 )
13659 &&
13660 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
13661 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
13662 )
13663 )
13664 {
13665 setKey.keyDirection = eSIR_RX_ONLY;
13666 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13667
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013668 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013669 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013670 __func__, setKey.peerMac[0], setKey.peerMac[1],
13671 setKey.peerMac[2], setKey.peerMac[3],
13672 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013673 setKey.keyDirection);
13674
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013675 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013676 pAdapter->sessionId, &setKey, &roamId );
13677
13678 if ( 0 != status )
13679 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013680 hddLog(VOS_TRACE_LEVEL_ERROR,
13681 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013682 __func__, status);
13683 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013684 status = -EINVAL;
13685 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013686 }
13687 }
13688 }
13689
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013690 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013691 for (i = 0; i < params->seq_len; i++) {
13692 rsc_counter |= (params->seq[i] << i*8);
13693 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013694 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
13695 }
13696
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013697end:
13698 /* Need to clear any trace of key value in the memory.
13699 * Thus zero out the memory even though it is local
13700 * variable.
13701 */
13702 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013703 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013704 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013705}
13706
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013707#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13708static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13709 struct net_device *ndev,
13710 u8 key_index, bool pairwise,
13711 const u8 *mac_addr,
13712 struct key_params *params
13713 )
13714#else
13715static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13716 struct net_device *ndev,
13717 u8 key_index, const u8 *mac_addr,
13718 struct key_params *params
13719 )
13720#endif
13721{
13722 int ret;
13723 vos_ssr_protect(__func__);
13724#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13725 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
13726 mac_addr, params);
13727#else
13728 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
13729 params);
13730#endif
13731 vos_ssr_unprotect(__func__);
13732
13733 return ret;
13734}
13735
Jeff Johnson295189b2012-06-20 16:38:30 -070013736/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013737 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013738 * This function is used to get the key information
13739 */
13740#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013741static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013742 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013743 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013744 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013745 const u8 *mac_addr, void *cookie,
13746 void (*callback)(void *cookie, struct key_params*)
13747 )
13748#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013749static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013750 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013751 struct net_device *ndev,
13752 u8 key_index, const u8 *mac_addr, void *cookie,
13753 void (*callback)(void *cookie, struct key_params*)
13754 )
13755#endif
13756{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013757 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013758 hdd_wext_state_t *pWextState = NULL;
13759 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013760 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013761 hdd_context_t *pHddCtx;
13762 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013763
13764 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013765
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013766 if (NULL == pAdapter)
13767 {
13768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13769 "%s: HDD adapter is Null", __func__);
13770 return -ENODEV;
13771 }
13772
13773 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13774 ret = wlan_hdd_validate_context(pHddCtx);
13775 if (0 != ret)
13776 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013777 return ret;
13778 }
13779
13780 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13781 pRoamProfile = &(pWextState->roamProfile);
13782
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013783 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13784 __func__, hdd_device_modetoString(pAdapter->device_mode),
13785 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013786
Jeff Johnson295189b2012-06-20 16:38:30 -070013787 memset(&params, 0, sizeof(params));
13788
13789 if (CSR_MAX_NUM_KEY <= key_index)
13790 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013791 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013792 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013793 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013794
13795 switch(pRoamProfile->EncryptionType.encryptionType[0])
13796 {
13797 case eCSR_ENCRYPT_TYPE_NONE:
13798 params.cipher = IW_AUTH_CIPHER_NONE;
13799 break;
13800
13801 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13802 case eCSR_ENCRYPT_TYPE_WEP40:
13803 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13804 break;
13805
13806 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13807 case eCSR_ENCRYPT_TYPE_WEP104:
13808 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13809 break;
13810
13811 case eCSR_ENCRYPT_TYPE_TKIP:
13812 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13813 break;
13814
13815 case eCSR_ENCRYPT_TYPE_AES:
13816 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13817 break;
13818
13819 default:
13820 params.cipher = IW_AUTH_CIPHER_NONE;
13821 break;
13822 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013823
c_hpothuaaf19692014-05-17 17:01:48 +053013824 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13825 TRACE_CODE_HDD_CFG80211_GET_KEY,
13826 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013827
Jeff Johnson295189b2012-06-20 16:38:30 -070013828 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13829 params.seq_len = 0;
13830 params.seq = NULL;
13831 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13832 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013833 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013834 return 0;
13835}
13836
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013837#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13838static int wlan_hdd_cfg80211_get_key(
13839 struct wiphy *wiphy,
13840 struct net_device *ndev,
13841 u8 key_index, bool pairwise,
13842 const u8 *mac_addr, void *cookie,
13843 void (*callback)(void *cookie, struct key_params*)
13844 )
13845#else
13846static int wlan_hdd_cfg80211_get_key(
13847 struct wiphy *wiphy,
13848 struct net_device *ndev,
13849 u8 key_index, const u8 *mac_addr, void *cookie,
13850 void (*callback)(void *cookie, struct key_params*)
13851 )
13852#endif
13853{
13854 int ret;
13855
13856 vos_ssr_protect(__func__);
13857#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13858 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13859 mac_addr, cookie, callback);
13860#else
13861 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13862 callback);
13863#endif
13864 vos_ssr_unprotect(__func__);
13865
13866 return ret;
13867}
13868
Jeff Johnson295189b2012-06-20 16:38:30 -070013869/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013870 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013871 * This function is used to delete the key information
13872 */
13873#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013874static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013875 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013876 u8 key_index,
13877 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013878 const u8 *mac_addr
13879 )
13880#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013881static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013882 struct net_device *ndev,
13883 u8 key_index,
13884 const u8 *mac_addr
13885 )
13886#endif
13887{
13888 int status = 0;
13889
13890 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013891 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013892 //it is observed that this is invalidating peer
13893 //key index whenever re-key is done. This is affecting data link.
13894 //It should be ok to ignore del_key.
13895#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013896 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13897 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013898 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13899 tCsrRoamSetKey setKey;
13900 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013901
Jeff Johnson295189b2012-06-20 16:38:30 -070013902 ENTER();
13903
13904 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13905 __func__,pAdapter->device_mode);
13906
13907 if (CSR_MAX_NUM_KEY <= key_index)
13908 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013909 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013910 key_index);
13911
13912 return -EINVAL;
13913 }
13914
13915 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13916 setKey.keyId = key_index;
13917
13918 if (mac_addr)
13919 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13920 else
13921 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13922
13923 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13924
13925 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013926 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013927 )
13928 {
13929
13930 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013931 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13932 if( pHostapdState->bssState == BSS_START)
13933 {
13934 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013935
Jeff Johnson295189b2012-06-20 16:38:30 -070013936 if ( status != eHAL_STATUS_SUCCESS )
13937 {
13938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13939 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13940 __LINE__, status );
13941 }
13942 }
13943 }
13944 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013945 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013946 )
13947 {
13948 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13949
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013950 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13951
13952 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013953 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013954 __func__, setKey.peerMac[0], setKey.peerMac[1],
13955 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013956 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013957 if(pAdapter->sessionCtx.station.conn_info.connState ==
13958 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013959 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013960 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013961 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013962
Jeff Johnson295189b2012-06-20 16:38:30 -070013963 if ( 0 != status )
13964 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013965 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013966 "%s: sme_RoamSetKey failure, returned %d",
13967 __func__, status);
13968 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13969 return -EINVAL;
13970 }
13971 }
13972 }
13973#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013974 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013975 return status;
13976}
13977
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013978#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13979static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13980 struct net_device *ndev,
13981 u8 key_index,
13982 bool pairwise,
13983 const u8 *mac_addr
13984 )
13985#else
13986static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13987 struct net_device *ndev,
13988 u8 key_index,
13989 const u8 *mac_addr
13990 )
13991#endif
13992{
13993 int ret;
13994
13995 vos_ssr_protect(__func__);
13996#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13997 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
13998 mac_addr);
13999#else
14000 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
14001#endif
14002 vos_ssr_unprotect(__func__);
14003
14004 return ret;
14005}
14006
Jeff Johnson295189b2012-06-20 16:38:30 -070014007/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014008 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070014009 * This function is used to set the default tx key index
14010 */
14011#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014012static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014013 struct net_device *ndev,
14014 u8 key_index,
14015 bool unicast, bool multicast)
14016#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014017static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014018 struct net_device *ndev,
14019 u8 key_index)
14020#endif
14021{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014022 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014023 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053014024 hdd_wext_state_t *pWextState;
14025 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014026 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014027
14028 ENTER();
14029
Gopichand Nakkala29149562013-05-10 21:43:41 +053014030 if ((NULL == pAdapter))
14031 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053014033 "invalid adapter");
14034 return -EINVAL;
14035 }
14036
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014037 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14038 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
14039 pAdapter->sessionId, key_index));
14040
Gopichand Nakkala29149562013-05-10 21:43:41 +053014041 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14042 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14043
14044 if ((NULL == pWextState) || (NULL == pHddStaCtx))
14045 {
14046 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14047 "invalid Wext state or HDD context");
14048 return -EINVAL;
14049 }
14050
Arif Hussain6d2a3322013-11-17 19:50:10 -080014051 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014052 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014053
Jeff Johnson295189b2012-06-20 16:38:30 -070014054 if (CSR_MAX_NUM_KEY <= key_index)
14055 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014056 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014057 key_index);
14058
14059 return -EINVAL;
14060 }
14061
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014062 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14063 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014064 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014065 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014066 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014067 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014068
Jeff Johnson295189b2012-06-20 16:38:30 -070014069 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070014070 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014071 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014072 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053014073 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080014074 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080014075#ifdef FEATURE_WLAN_WAPI
14076 (eCSR_ENCRYPT_TYPE_WPI !=
14077 pHddStaCtx->conn_info.ucEncryptionType) &&
14078#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014079 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080014080 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070014081 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014082 {
14083 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070014084 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014085
Jeff Johnson295189b2012-06-20 16:38:30 -070014086 tCsrRoamSetKey setKey;
14087 v_U32_t roamId= 0xFF;
14088 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014089
14090 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014091 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014092
Jeff Johnson295189b2012-06-20 16:38:30 -070014093 Keys->defaultIndex = (u8)key_index;
14094 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
14095 setKey.keyId = key_index;
14096 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014097
14098 vos_mem_copy(&setKey.Key[0],
14099 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014100 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014101
Gopichand Nakkala29149562013-05-10 21:43:41 +053014102 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014103
14104 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070014105 &pHddStaCtx->conn_info.bssId[0],
14106 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014107
Gopichand Nakkala29149562013-05-10 21:43:41 +053014108 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
14109 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
14110 eCSR_ENCRYPT_TYPE_WEP104)
14111 {
14112 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
14113 even though ap is configured for WEP-40 encryption. In this canse the key length
14114 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
14115 type(104) and switching encryption type to 40*/
14116 pWextState->roamProfile.EncryptionType.encryptionType[0] =
14117 eCSR_ENCRYPT_TYPE_WEP40;
14118 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
14119 eCSR_ENCRYPT_TYPE_WEP40;
14120 }
14121
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014122 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014123 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014124
Jeff Johnson295189b2012-06-20 16:38:30 -070014125 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014126 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014127 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014128
Jeff Johnson295189b2012-06-20 16:38:30 -070014129 if ( 0 != status )
14130 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014131 hddLog(VOS_TRACE_LEVEL_ERROR,
14132 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014133 status);
14134 return -EINVAL;
14135 }
14136 }
14137 }
14138
14139 /* In SoftAp mode setting key direction for default mode */
14140 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
14141 {
14142 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
14143 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
14144 (eCSR_ENCRYPT_TYPE_AES !=
14145 pWextState->roamProfile.EncryptionType.encryptionType[0])
14146 )
14147 {
14148 /* Saving key direction for default key index to TX default */
14149 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
14150 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
14151 }
14152 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014153 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014154 return status;
14155}
14156
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014157#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14158static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14159 struct net_device *ndev,
14160 u8 key_index,
14161 bool unicast, bool multicast)
14162#else
14163static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14164 struct net_device *ndev,
14165 u8 key_index)
14166#endif
14167{
14168 int ret;
14169 vos_ssr_protect(__func__);
14170#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14171 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
14172 multicast);
14173#else
14174 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
14175#endif
14176 vos_ssr_unprotect(__func__);
14177
14178 return ret;
14179}
14180
Jeff Johnson295189b2012-06-20 16:38:30 -070014181/*
14182 * FUNCTION: wlan_hdd_cfg80211_inform_bss
14183 * This function is used to inform the BSS details to nl80211 interface.
14184 */
14185static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
14186 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
14187{
14188 struct net_device *dev = pAdapter->dev;
14189 struct wireless_dev *wdev = dev->ieee80211_ptr;
14190 struct wiphy *wiphy = wdev->wiphy;
14191 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
14192 int chan_no;
14193 int ie_length;
14194 const char *ie;
14195 unsigned int freq;
14196 struct ieee80211_channel *chan;
14197 int rssi = 0;
14198 struct cfg80211_bss *bss = NULL;
14199
Jeff Johnson295189b2012-06-20 16:38:30 -070014200 if( NULL == pBssDesc )
14201 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014202 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014203 return bss;
14204 }
14205
14206 chan_no = pBssDesc->channelId;
14207 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
14208 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
14209
14210 if( NULL == ie )
14211 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014212 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014213 return bss;
14214 }
14215
14216#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
14217 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
14218 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014219 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014220 }
14221 else
14222 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014223 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014224 }
14225#else
14226 freq = ieee80211_channel_to_frequency(chan_no);
14227#endif
14228
14229 chan = __ieee80211_get_channel(wiphy, freq);
14230
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053014231 if (!chan) {
14232 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
14233 return NULL;
14234 }
14235
Abhishek Singhaee43942014-06-16 18:55:47 +053014236 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070014237
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014238 return cfg80211_inform_bss(wiphy, chan,
14239#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14240 CFG80211_BSS_FTYPE_UNKNOWN,
14241#endif
14242 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014243 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070014244 pBssDesc->capabilityInfo,
14245 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053014246 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070014247}
14248
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014249/*
14250 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
14251 * interface that BSS might have been lost.
14252 * @pAdapter: adaptor
14253 * @bssid: bssid which might have been lost
14254 *
14255 * Return: bss which is unlinked from kernel cache
14256 */
14257struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
14258 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
14259{
14260 struct net_device *dev = pAdapter->dev;
14261 struct wireless_dev *wdev = dev->ieee80211_ptr;
14262 struct wiphy *wiphy = wdev->wiphy;
14263 struct cfg80211_bss *bss = NULL;
14264
Abhishek Singh5a597e62016-12-05 15:16:30 +053014265 bss = hdd_get_bss_entry(wiphy,
14266 NULL, bssid,
14267 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014268 if (bss == NULL) {
14269 hddLog(LOGE, FL("BSS not present"));
14270 } else {
14271 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
14272 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
14273 cfg80211_unlink_bss(wiphy, bss);
14274 }
14275 return bss;
14276}
Jeff Johnson295189b2012-06-20 16:38:30 -070014277
14278
14279/*
14280 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
14281 * This function is used to inform the BSS details to nl80211 interface.
14282 */
14283struct cfg80211_bss*
14284wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
14285 tSirBssDescription *bss_desc
14286 )
14287{
14288 /*
14289 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
14290 already exists in bss data base of cfg80211 for that particular BSS ID.
14291 Using cfg80211_inform_bss_frame to update the bss entry instead of
14292 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
14293 now there is no possibility to get the mgmt(probe response) frame from PE,
14294 converting bss_desc to ieee80211_mgmt(probe response) and passing to
14295 cfg80211_inform_bss_frame.
14296 */
14297 struct net_device *dev = pAdapter->dev;
14298 struct wireless_dev *wdev = dev->ieee80211_ptr;
14299 struct wiphy *wiphy = wdev->wiphy;
14300 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014301#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14302 qcom_ie_age *qie_age = NULL;
14303 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
14304#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014305 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014306#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014307 const char *ie =
14308 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
14309 unsigned int freq;
14310 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014311 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014312 struct cfg80211_bss *bss_status = NULL;
Hanumanth Reddy Pothulae04e06c2018-05-31 14:41:36 +053014313 size_t frame_len = ie_length + offsetof(struct ieee80211_mgmt,
14314 u.probe_resp.variable);
Jeff Johnson295189b2012-06-20 16:38:30 -070014315 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070014316 hdd_context_t *pHddCtx;
14317 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070014318#ifdef WLAN_OPEN_SOURCE
14319 struct timespec ts;
14320#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014321
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014322
Wilson Yangf80a0542013-10-07 13:02:37 -070014323 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14324 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070014325 if (0 != status)
14326 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014327 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014328 }
14329
Hanumanth Reddy Pothula33548e22018-05-31 13:28:51 +053014330 mgmt = kzalloc(frame_len, GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070014331 if (!mgmt)
14332 {
14333 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14334 "%s: memory allocation failed ", __func__);
14335 return NULL;
14336 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014337
Jeff Johnson295189b2012-06-20 16:38:30 -070014338 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014339
14340#ifdef WLAN_OPEN_SOURCE
14341 /* Android does not want the timestamp from the frame.
14342 Instead it wants a monotonic increasing value */
14343 get_monotonic_boottime(&ts);
14344 mgmt->u.probe_resp.timestamp =
14345 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
14346#else
14347 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014348 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
14349 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070014350
14351#endif
14352
Jeff Johnson295189b2012-06-20 16:38:30 -070014353 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
14354 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014355
14356#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14357 /* GPS Requirement: need age ie per entry. Using vendor specific. */
14358 /* Assuming this is the last IE, copy at the end */
14359 ie_length -=sizeof(qcom_ie_age);
14360 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
14361 qie_age->element_id = QCOM_VENDOR_IE_ID;
14362 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
14363 qie_age->oui_1 = QCOM_OUI1;
14364 qie_age->oui_2 = QCOM_OUI2;
14365 qie_age->oui_3 = QCOM_OUI3;
14366 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053014367 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
14368 * bss related timestamp is in units of ms. Due to this when scan results
14369 * are sent to lowi the scan age is high.To address this, send age in units
14370 * of 1/10 ms.
14371 */
14372 qie_age->age = (vos_timer_get_system_time() -
14373 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014374#endif
14375
Jeff Johnson295189b2012-06-20 16:38:30 -070014376 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053014377 if (bss_desc->fProbeRsp)
14378 {
14379 mgmt->frame_control |=
14380 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
14381 }
14382 else
14383 {
14384 mgmt->frame_control |=
14385 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
14386 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014387
14388#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014389 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014390 (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014391 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014392 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014393 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014394 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014395 (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014396
14397 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014398 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014399 }
14400 else
14401 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014402 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
14403 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070014404 kfree(mgmt);
14405 return NULL;
14406 }
14407#else
14408 freq = ieee80211_channel_to_frequency(chan_no);
14409#endif
14410 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014411 /*when the band is changed on the fly using the GUI, three things are done
14412 * 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)
14413 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
14414 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
14415 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
14416 * and discards the channels correponding to previous band and calls back with zero bss results.
14417 * 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
14418 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
14419 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
14420 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
14421 * So drop the bss and continue to next bss.
14422 */
14423 if(chan == NULL)
14424 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053014425 hddLog(VOS_TRACE_LEVEL_ERROR,
14426 FL("chan pointer is NULL, chan_no: %d freq: %d"),
14427 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070014428 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014429 return NULL;
14430 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053014431 /*To keep the rssi icon of the connected AP in the scan window
14432 *and the rssi icon of the wireless networks in sync
14433 * */
14434 if (( eConnectionState_Associated ==
14435 pAdapter->sessionCtx.station.conn_info.connState ) &&
14436 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
14437 pAdapter->sessionCtx.station.conn_info.bssId,
14438 WNI_CFG_BSSID_LEN)) &&
14439 (pHddCtx->hdd_wlan_suspended == FALSE))
14440 {
14441 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
14442 rssi = (pAdapter->rssi * 100);
14443 }
14444 else
14445 {
14446 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
14447 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014448
Nirav Shah20ac06f2013-12-12 18:14:06 +053014449 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053014450 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
14451 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053014452
Jeff Johnson295189b2012-06-20 16:38:30 -070014453 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
14454 frame_len, rssi, GFP_KERNEL);
14455 kfree(mgmt);
14456 return bss_status;
14457}
14458
14459/*
14460 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
14461 * This function is used to update the BSS data base of CFG8011
14462 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014463struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014464 tCsrRoamInfo *pRoamInfo
14465 )
14466{
14467 tCsrRoamConnectedProfile roamProfile;
14468 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14469 struct cfg80211_bss *bss = NULL;
14470
14471 ENTER();
14472
14473 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
14474 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
14475
14476 if (NULL != roamProfile.pBssDesc)
14477 {
Girish Gowlif4b68022014-08-28 23:18:57 +053014478 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14479 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070014480
14481 if (NULL == bss)
14482 {
14483 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
14484 __func__);
14485 }
14486
14487 sme_RoamFreeConnectProfile(hHal, &roamProfile);
14488 }
14489 else
14490 {
14491 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
14492 __func__);
14493 }
14494 return bss;
14495}
14496
14497/*
14498 * FUNCTION: wlan_hdd_cfg80211_update_bss
14499 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014500static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
14501 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070014502 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014503{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014504 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014505 tCsrScanResultInfo *pScanResult;
14506 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014507 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014508 tScanResultHandle pResult;
14509 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014510 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014511 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070014512 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014513
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014514 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14515 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
14516 NO_SESSION, pAdapter->sessionId));
14517
Wilson Yangf80a0542013-10-07 13:02:37 -070014518 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014519 ret = wlan_hdd_validate_context(pHddCtx);
14520 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070014521 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014522 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070014523 }
14524
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014525 if (pAdapter->request != NULL)
14526 {
14527 if ((pAdapter->request->n_ssids == 1)
14528 && (pAdapter->request->ssids != NULL)
14529 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
14530 is_p2p_scan = true;
14531 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014532 /*
14533 * start getting scan results and populate cgf80211 BSS database
14534 */
14535 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
14536
14537 /* no scan results */
14538 if (NULL == pResult)
14539 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014540 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
14541 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014542 wlan_hdd_get_frame_logs(pAdapter,
14543 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070014544 return status;
14545 }
14546
14547 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
14548
14549 while (pScanResult)
14550 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014551 /*
14552 * cfg80211_inform_bss() is not updating ie field of bss entry, if
14553 * entry already exists in bss data base of cfg80211 for that
14554 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
14555 * bss entry instead of cfg80211_inform_bss, But this call expects
14556 * mgmt packet as input. As of now there is no possibility to get
14557 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070014558 * ieee80211_mgmt(probe response) and passing to c
14559 * fg80211_inform_bss_frame.
14560 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014561 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
14562 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
14563 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014564 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14565 continue; //Skip the non p2p bss entries
14566 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014567 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14568 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014569
Jeff Johnson295189b2012-06-20 16:38:30 -070014570
14571 if (NULL == bss_status)
14572 {
14573 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014574 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014575 }
14576 else
14577 {
Yue Maf49ba872013-08-19 12:04:25 -070014578 cfg80211_put_bss(
14579#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
14580 wiphy,
14581#endif
14582 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070014583 }
14584
14585 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14586 }
14587
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014588 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014589 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014590 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014591}
14592
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014593void
14594hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
14595{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014596 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080014597 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014598} /****** end hddPrintMacAddr() ******/
14599
14600void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014601hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014602{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014603 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014604 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014605 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
14606 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
14607 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014608} /****** end hddPrintPmkId() ******/
14609
14610//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
14611//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
14612
14613//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
14614//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
14615
14616#define dump_bssid(bssid) \
14617 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014618 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
14619 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014620 }
14621
14622#define dump_pmkid(pMac, pmkid) \
14623 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014624 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
14625 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014626 }
14627
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070014628#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014629/*
14630 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
14631 * This function is used to notify the supplicant of a new PMKSA candidate.
14632 */
14633int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014634 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014635 int index, bool preauth )
14636{
Jeff Johnsone7245742012-09-05 17:12:55 -070014637#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014638 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014639 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014640
14641 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070014642 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014643
14644 if( NULL == pRoamInfo )
14645 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014646 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014647 return -EINVAL;
14648 }
14649
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014650 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
14651 {
14652 dump_bssid(pRoamInfo->bssid);
14653 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014654 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014655 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014656#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014657 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014658}
14659#endif //FEATURE_WLAN_LFR
14660
Yue Maef608272013-04-08 23:09:17 -070014661#ifdef FEATURE_WLAN_LFR_METRICS
14662/*
14663 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
14664 * 802.11r/LFR metrics reporting function to report preauth initiation
14665 *
14666 */
14667#define MAX_LFR_METRICS_EVENT_LENGTH 100
14668VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
14669 tCsrRoamInfo *pRoamInfo)
14670{
14671 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14672 union iwreq_data wrqu;
14673
14674 ENTER();
14675
14676 if (NULL == pAdapter)
14677 {
14678 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14679 return VOS_STATUS_E_FAILURE;
14680 }
14681
14682 /* create the event */
14683 memset(&wrqu, 0, sizeof(wrqu));
14684 memset(metrics_notification, 0, sizeof(metrics_notification));
14685
14686 wrqu.data.pointer = metrics_notification;
14687 wrqu.data.length = scnprintf(metrics_notification,
14688 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
14689 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14690
14691 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14692
14693 EXIT();
14694
14695 return VOS_STATUS_SUCCESS;
14696}
14697
14698/*
14699 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
14700 * 802.11r/LFR metrics reporting function to report preauth completion
14701 * or failure
14702 */
14703VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
14704 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
14705{
14706 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14707 union iwreq_data wrqu;
14708
14709 ENTER();
14710
14711 if (NULL == pAdapter)
14712 {
14713 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14714 return VOS_STATUS_E_FAILURE;
14715 }
14716
14717 /* create the event */
14718 memset(&wrqu, 0, sizeof(wrqu));
14719 memset(metrics_notification, 0, sizeof(metrics_notification));
14720
14721 scnprintf(metrics_notification, sizeof(metrics_notification),
14722 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
14723 MAC_ADDR_ARRAY(pRoamInfo->bssid));
14724
14725 if (1 == preauth_status)
14726 strncat(metrics_notification, " TRUE", 5);
14727 else
14728 strncat(metrics_notification, " FALSE", 6);
14729
14730 wrqu.data.pointer = metrics_notification;
14731 wrqu.data.length = strlen(metrics_notification);
14732
14733 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14734
14735 EXIT();
14736
14737 return VOS_STATUS_SUCCESS;
14738}
14739
14740/*
14741 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
14742 * 802.11r/LFR metrics reporting function to report handover initiation
14743 *
14744 */
14745VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
14746 tCsrRoamInfo *pRoamInfo)
14747{
14748 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14749 union iwreq_data wrqu;
14750
14751 ENTER();
14752
14753 if (NULL == pAdapter)
14754 {
14755 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14756 return VOS_STATUS_E_FAILURE;
14757 }
14758
14759 /* create the event */
14760 memset(&wrqu, 0, sizeof(wrqu));
14761 memset(metrics_notification, 0, sizeof(metrics_notification));
14762
14763 wrqu.data.pointer = metrics_notification;
14764 wrqu.data.length = scnprintf(metrics_notification,
14765 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14766 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14767
14768 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14769
14770 EXIT();
14771
14772 return VOS_STATUS_SUCCESS;
14773}
14774#endif
14775
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014776
14777/**
14778 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14779 * @scan_req: scan request to be checked
14780 *
14781 * Return: true or false
14782 */
14783#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14784static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14785 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014786 *scan_req, hdd_context_t
14787 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014788{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014789 if (!scan_req || !scan_req->wiphy ||
14790 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014791 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14792 return false;
14793 }
14794 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14795 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14796 return false;
14797 }
14798 return true;
14799}
14800#else
14801static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14802 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014803 *scan_req, hdd_context_t
14804 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014805{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014806 if (!scan_req || !scan_req->wiphy ||
14807 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014808 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14809 return false;
14810 }
14811 return true;
14812}
14813#endif
14814
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014815#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
14816/**
14817 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14818 * @adapter: Pointer to the adapter
14819 * @req : Scan request
14820 * @aborted : true scan aborted false scan success
14821 *
14822 * This function notifies scan done to cfg80211
14823 *
14824 * Return: none
14825 */
14826static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14827 struct cfg80211_scan_request *req,
14828 bool aborted)
14829{
14830 struct cfg80211_scan_info info = {
14831 .aborted = aborted
14832 };
14833
14834 if (adapter->dev->flags & IFF_UP)
14835 cfg80211_scan_done(req, &info);
14836 else
14837 hddLog(LOGW,
14838 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14839}
14840#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14841/**
14842 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14843 * @adapter: Pointer to the adapter
14844 * @req : Scan request
14845 * @aborted : true scan aborted false scan success
14846 *
14847 * This function notifies scan done to cfg80211
14848 *
14849 * Return: none
14850 */
14851static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14852 struct cfg80211_scan_request *req,
14853 bool aborted)
14854{
14855 if (adapter->dev->flags & IFF_UP)
14856 cfg80211_scan_done(req, aborted);
14857 else
14858 hddLog(LOGW,
14859 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14860}
14861#else
14862/**
14863 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14864 * @adapter: Pointer to the adapter
14865 * @req : Scan request
14866 * @aborted : true scan aborted false scan success
14867 *
14868 * This function notifies scan done to cfg80211
14869 *
14870 * Return: none
14871 */
14872static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14873 struct cfg80211_scan_request *req,
14874 bool aborted)
14875{
14876 cfg80211_scan_done(req, aborted);
14877}
14878#endif
14879
Mukul Sharmab392b642017-08-17 17:45:29 +053014880#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014881/*
14882 * FUNCTION: hdd_cfg80211_scan_done_callback
14883 * scanning callback function, called after finishing scan
14884 *
14885 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014886static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014887 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14888{
14889 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014890 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014891 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014892 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014893 struct cfg80211_scan_request *req = NULL;
14894 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014895 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014896 long waitRet = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014897 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014898
14899 ENTER();
14900
c_manjee1b4ab9a2016-10-26 11:36:55 +053014901 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14902 !pAdapter->dev) {
14903 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14904 return 0;
14905 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014906 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014907 if (NULL == pHddCtx) {
14908 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014909 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014910 }
14911
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014912#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014913 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014914 {
14915 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014916 }
14917#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014918 pScanInfo = &pHddCtx->scan_info;
14919
Jeff Johnson295189b2012-06-20 16:38:30 -070014920 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014921 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014922 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014923 __func__, halHandle, pContext, (int) scanId, (int) status);
14924
Kiet Lamac06e2c2013-10-23 16:25:07 +053014925 pScanInfo->mScanPendingCounter = 0;
14926
Jeff Johnson295189b2012-06-20 16:38:30 -070014927 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014928 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014929 &pScanInfo->scan_req_completion_event,
14930 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014931 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014932 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014933 hddLog(VOS_TRACE_LEVEL_ERROR,
14934 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014935 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014936 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014937 }
14938
Yue Maef608272013-04-08 23:09:17 -070014939 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014940 {
14941 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014942 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014943 }
14944
14945 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014946 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014947 {
14948 hddLog(VOS_TRACE_LEVEL_INFO,
14949 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014950 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014951 (int) scanId);
14952 }
14953
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014954#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014955 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014956#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014957 {
14958 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14959 pAdapter);
14960 if (0 > ret)
14961 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014962 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014963
Jeff Johnson295189b2012-06-20 16:38:30 -070014964 /* If any client wait scan result through WEXT
14965 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014966 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014967 {
14968 /* The other scan request waiting for current scan finish
14969 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014970 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014971 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014972 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014973 }
14974 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014975 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014976 {
14977 struct net_device *dev = pAdapter->dev;
14978 union iwreq_data wrqu;
14979 int we_event;
14980 char *msg;
14981
14982 memset(&wrqu, '\0', sizeof(wrqu));
14983 we_event = SIOCGIWSCAN;
14984 msg = NULL;
14985 wireless_send_event(dev, we_event, &wrqu, msg);
14986 }
14987 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014988 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014989
14990 /* Get the Scan Req */
14991 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014992 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014993
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014994 /* Scan is no longer pending */
14995 pScanInfo->mScanPending = VOS_FALSE;
14996
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014997 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070014998 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014999#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
15000 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053015001 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053015002#endif
15003
15004 if (pAdapter->dev) {
15005 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
15006 pAdapter->dev->name);
15007 }
mukul sharmae7041822015-12-03 15:09:21 +053015008 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070015009 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070015010 }
15011
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015012 /* last_scan_timestamp is used to decide if new scan
15013 * is needed or not on station interface. If last station
15014 * scan time and new station scan time is less then
15015 * last_scan_timestamp ; driver will return cached scan.
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015016 * Also only last_scan_timestamp is updated here last_scan_channellist
15017 * is updated on receiving scan request itself to make sure kernel
15018 * allocated scan request(scan_req) object is not dereferenced here,
15019 * because interface down, where kernel frees scan_req, may happen any
15020 * time while driver is processing scan_done_callback. So it's better
15021 * not to access scan_req in this routine.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015022 */
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015023 if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
15024 if (status == eCSR_SCAN_SUCCESS)
15025 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
15026 else {
15027 vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
15028 sizeof(pHddCtx->scan_info.last_scan_channelList));
15029 pHddCtx->scan_info.last_scan_numChannels = 0;
15030 pScanInfo->last_scan_timestamp = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015031 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015032 }
15033
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070015034 /*
15035 * cfg80211_scan_done informing NL80211 about completion
15036 * of scanning
15037 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015038 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
15039 {
15040 aborted = true;
15041 }
mukul sharmae7041822015-12-03 15:09:21 +053015042
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015043#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015044 if (NET_DEV_IS_IFF_UP(pAdapter) &&
15045 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015046#endif
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015047 hdd_cfg80211_scan_done(pAdapter, req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053015048
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080015049 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070015050
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015051allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015052 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
15053 ) && (pHddCtx->spoofMacAddr.isEnabled
15054 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053015055 /* Generate new random mac addr for next scan */
15056 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053015057
15058 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
15059 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053015060 }
15061
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015062 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015063 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015064
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015065 /* Acquire wakelock to handle the case where APP's tries to suspend
15066 * immediatly after the driver gets connect request(i.e after scan)
15067 * from supplicant, this result in app's is suspending and not able
15068 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015069 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015070
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015071#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015072 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015073#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015074#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015075 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015076#endif
15077
Jeff Johnson295189b2012-06-20 16:38:30 -070015078 EXIT();
15079 return 0;
15080}
15081
15082/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053015083 * FUNCTION: hdd_isConnectionInProgress
15084 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015085 *
15086 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015087v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
15088 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015089{
15090 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15091 hdd_station_ctx_t *pHddStaCtx = NULL;
15092 hdd_adapter_t *pAdapter = NULL;
15093 VOS_STATUS status = 0;
15094 v_U8_t staId = 0;
15095 v_U8_t *staMac = NULL;
15096
15097 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15098
15099 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15100 {
15101 pAdapter = pAdapterNode->pAdapter;
15102
15103 if( pAdapter )
15104 {
15105 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015106 "%s: Adapter with device mode %s (%d) exists",
15107 __func__, hdd_device_modetoString(pAdapter->device_mode),
15108 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015109 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053015110 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15111 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
15112 (eConnectionState_Connecting ==
15113 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
15114 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015115 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015116 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053015117 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015118 if (session_id && reason)
15119 {
15120 *session_id = pAdapter->sessionId;
15121 *reason = eHDD_CONNECTION_IN_PROGRESS;
15122 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015123 return VOS_TRUE;
15124 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015125 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053015126 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015127 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015128 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015129 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015130 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015131 if (session_id && reason)
15132 {
15133 *session_id = pAdapter->sessionId;
15134 *reason = eHDD_REASSOC_IN_PROGRESS;
15135 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015136 return VOS_TRUE;
15137 }
15138 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015139 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15140 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015141 {
15142 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15143 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Vignesh Viswanathan0ac8e562018-06-14 17:24:10 +053015144 sme_is_sta_key_exchange_in_progress(pHddCtx->hHal,
15145 pAdapter->sessionId))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015146 {
15147 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015148 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015149 "%s: client " MAC_ADDRESS_STR
15150 " is in the middle of WPS/EAPOL exchange.", __func__,
15151 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015152 if (session_id && reason)
15153 {
15154 *session_id = pAdapter->sessionId;
15155 *reason = eHDD_EAPOL_IN_PROGRESS;
15156 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015157 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015158 }
15159 }
15160 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
15161 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
15162 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015163 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15164 ptSapContext pSapCtx = NULL;
15165 pSapCtx = VOS_GET_SAP_CB(pVosContext);
15166 if(pSapCtx == NULL){
15167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15168 FL("psapCtx is NULL"));
15169 return VOS_FALSE;
15170 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015171 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
15172 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015173 if ((pSapCtx->aStaInfo[staId].isUsed) &&
15174 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015175 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015176 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015177
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015178 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015179 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
15180 "middle of WPS/EAPOL exchange.", __func__,
15181 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015182 if (session_id && reason)
15183 {
15184 *session_id = pAdapter->sessionId;
15185 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
15186 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015187 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015188 }
15189 }
15190 }
15191 }
15192 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15193 pAdapterNode = pNext;
15194 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015195 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015196}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015197
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015198/**
15199 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
15200 * to the Scan request
15201 * @scanRequest: Pointer to the csr scan request
15202 * @request: Pointer to the scan request from supplicant
15203 *
15204 * Return: None
15205 */
15206#ifdef CFG80211_SCAN_BSSID
15207static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15208 struct cfg80211_scan_request *request)
15209{
15210 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
15211}
15212#else
15213static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15214 struct cfg80211_scan_request *request)
15215{
15216}
15217#endif
15218
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015219/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015220 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070015221 * this scan respond to scan trigger and update cfg80211 scan database
15222 * later, scan dump command can be used to recieve scan results
15223 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015224int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015225#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15226 struct net_device *dev,
15227#endif
15228 struct cfg80211_scan_request *request)
15229{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015230 hdd_adapter_t *pAdapter = NULL;
15231 hdd_context_t *pHddCtx = NULL;
15232 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015233 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015234 tCsrScanRequest scanRequest;
15235 tANI_U8 *channelList = NULL, i;
15236 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015237 int status;
15238 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015239 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015240 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053015241 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015242 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015243 v_U8_t curr_session_id;
15244 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070015245
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015246#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
15247 struct net_device *dev = NULL;
15248 if (NULL == request)
15249 {
15250 hddLog(VOS_TRACE_LEVEL_ERROR,
15251 "%s: scan req param null", __func__);
15252 return -EINVAL;
15253 }
15254 dev = request->wdev->netdev;
15255#endif
15256
15257 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15258 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
15259 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15260
Jeff Johnson295189b2012-06-20 16:38:30 -070015261 ENTER();
15262
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015263 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
15264 __func__, hdd_device_modetoString(pAdapter->device_mode),
15265 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015266
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015267 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015268 if (0 != status)
15269 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015270 return status;
15271 }
15272
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015273 if (NULL == pwextBuf)
15274 {
15275 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
15276 __func__);
15277 return -EIO;
15278 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015279 cfg_param = pHddCtx->cfg_ini;
15280 pScanInfo = &pHddCtx->scan_info;
15281
Jeff Johnson295189b2012-06-20 16:38:30 -070015282#ifdef WLAN_BTAMP_FEATURE
15283 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015284 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070015285 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015286 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015287 "%s: No scanning when AMP is on", __func__);
15288 return -EOPNOTSUPP;
15289 }
15290#endif
15291 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015292 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070015293 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015294 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015295 "%s: Not scanning on device_mode = %s (%d)",
15296 __func__, hdd_device_modetoString(pAdapter->device_mode),
15297 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015298 return -EOPNOTSUPP;
15299 }
15300
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015301 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
15302 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
15303 return -EOPNOTSUPP;
15304 }
15305
Jeff Johnson295189b2012-06-20 16:38:30 -070015306 if (TRUE == pScanInfo->mScanPending)
15307 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015308 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
15309 {
15310 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
15311 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015312 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015313 }
15314
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053015315 // Don't allow scan if PNO scan is going on.
15316 if (pHddCtx->isPnoEnable)
15317 {
15318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15319 FL("pno scan in progress"));
15320 return -EBUSY;
15321 }
15322
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015323 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070015324 //Channel and action frame is pending
15325 //Otherwise Cancel Remain On Channel and allow Scan
15326 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015327 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070015328 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015329 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070015330 return -EBUSY;
15331 }
15332
Jeff Johnson295189b2012-06-20 16:38:30 -070015333 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
15334 {
15335 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080015336 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015337 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015338 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015339 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
15340 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015341 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015342 "%s: MAX TM Level Scan not allowed", __func__);
15343 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015344 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015345 }
15346 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
15347
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015348 /* Check if scan is allowed at this point of time.
15349 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053015350 if (TRUE == pHddCtx->btCoexModeSet)
15351 {
15352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15353 FL("BTCoex Mode operation in progress"));
15354 return -EBUSY;
15355 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015356 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015357 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015358
15359 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
15360 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
15361 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015362 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
15363 pHddCtx->last_scan_reject_reason != curr_reason ||
15364 !pHddCtx->last_scan_reject_timestamp)
15365 {
15366 pHddCtx->last_scan_reject_session_id = curr_session_id;
15367 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053015368 pHddCtx->last_scan_reject_timestamp =
15369 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015370 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053015371 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053015372 else
15373 {
15374 pHddCtx->scan_reject_cnt++;
15375
Abhishek Singhe4b12562017-06-20 16:53:39 +053015376 if ((pHddCtx->scan_reject_cnt >=
15377 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053015378 vos_system_time_after(jiffies_to_msecs(jiffies),
15379 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015380 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015381 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
15382 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
15383 vos_system_time_after(jiffies_to_msecs(jiffies),
15384 pHddCtx->last_scan_reject_timestamp));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015385 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015386 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015387 if (pHddCtx->cfg_ini->enableFatalEvent)
15388 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
15389 WLAN_LOG_INDICATOR_HOST_DRIVER,
15390 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
15391 FALSE, FALSE);
15392 else
15393 {
15394 hddLog(LOGE, FL("Triggering SSR"));
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +053015395 vos_wlanRestart(VOS_SCAN_REQ_EXPIRED);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015396 }
15397 }
15398 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015399 return -EBUSY;
15400 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015401 pHddCtx->last_scan_reject_timestamp = 0;
15402 pHddCtx->last_scan_reject_session_id = 0xFF;
15403 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015404 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015405
Jeff Johnson295189b2012-06-20 16:38:30 -070015406 vos_mem_zero( &scanRequest, sizeof(scanRequest));
15407
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015408 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
15409 * Becasue of this, driver is assuming that this is not wildcard scan and so
15410 * is not aging out the scan results.
15411 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053015412 if ((request->ssids) && (request->n_ssids == 1) &&
15413 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015414 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015415 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015416
15417 if ((request->ssids) && (0 < request->n_ssids))
15418 {
15419 tCsrSSIDInfo *SsidInfo;
15420 int j;
15421 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
15422 /* Allocate num_ssid tCsrSSIDInfo structure */
15423 SsidInfo = scanRequest.SSIDs.SSIDList =
15424 ( tCsrSSIDInfo *)vos_mem_malloc(
15425 request->n_ssids*sizeof(tCsrSSIDInfo));
15426
15427 if(NULL == scanRequest.SSIDs.SSIDList)
15428 {
15429 hddLog(VOS_TRACE_LEVEL_ERROR,
15430 "%s: memory alloc failed SSIDInfo buffer", __func__);
15431 return -ENOMEM;
15432 }
15433
15434 /* copy all the ssid's and their length */
15435 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
15436 {
15437 /* get the ssid length */
15438 SsidInfo->SSID.length = request->ssids[j].ssid_len;
15439 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
15440 SsidInfo->SSID.length);
15441 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
15442 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
15443 j, SsidInfo->SSID.ssId);
15444 }
15445 /* set the scan type to active */
15446 scanRequest.scanType = eSIR_ACTIVE_SCAN;
15447 }
15448 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015449 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015450 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15451 TRACE_CODE_HDD_CFG80211_SCAN,
15452 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070015453 /* set the scan type to active */
15454 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070015455 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015456 else
15457 {
15458 /*Set the scan type to default type, in this case it is ACTIVE*/
15459 scanRequest.scanType = pScanInfo->scan_mode;
15460 }
15461 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
15462 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070015463
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015464 csr_scan_request_assign_bssid(&scanRequest, request);
15465
Jeff Johnson295189b2012-06-20 16:38:30 -070015466 /* set BSSType to default type */
15467 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
15468
15469 /*TODO: scan the requested channels only*/
15470
15471 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015472 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070015473 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015474 hddLog(VOS_TRACE_LEVEL_WARN,
15475 "No of Scan Channels exceeded limit: %d", request->n_channels);
15476 request->n_channels = MAX_CHANNEL;
15477 }
15478
15479 hddLog(VOS_TRACE_LEVEL_INFO,
15480 "No of Scan Channels: %d", request->n_channels);
15481
15482
15483 if( request->n_channels )
15484 {
15485 char chList [(request->n_channels*5)+1];
15486 int len;
15487 channelList = vos_mem_malloc( request->n_channels );
15488 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053015489 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015490 hddLog(VOS_TRACE_LEVEL_ERROR,
15491 "%s: memory alloc failed channelList", __func__);
15492 status = -ENOMEM;
15493 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053015494 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015495
15496 for( i = 0, len = 0; i < request->n_channels ; i++ )
15497 {
15498 channelList[i] = request->channels[i]->hw_value;
15499 len += snprintf(chList+len, 5, "%d ", channelList[i]);
15500 }
15501
Nirav Shah20ac06f2013-12-12 18:14:06 +053015502 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015503 "Channel-List: %s ", chList);
15504 }
c_hpothu53512302014-04-15 18:49:53 +053015505
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015506 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
15507 scanRequest.ChannelInfo.ChannelList = channelList;
15508
15509 /* set requestType to full scan */
15510 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
15511
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015512 /* if there is back to back scan happening in driver with in
15513 * nDeferScanTimeInterval interval driver should defer new scan request
15514 * and should provide last cached scan results instead of new channel list.
15515 * This rule is not applicable if scan is p2p scan.
15516 * This condition will work only in case when last request no of channels
15517 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053015518 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053015519 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015520 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015521
Sushant Kaushik86592172015-04-27 16:35:03 +053015522 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
15523 /* if wps ie is NULL , then only defer scan */
15524 if ( pWpsIe == NULL &&
15525 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053015526 {
15527 if ( pScanInfo->last_scan_timestamp !=0 &&
15528 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
15529 {
15530 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
15531 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
15532 vos_mem_compare(pScanInfo->last_scan_channelList,
15533 channelList, pScanInfo->last_scan_numChannels))
15534 {
15535 hddLog(VOS_TRACE_LEVEL_WARN,
15536 " New and old station scan time differ is less then %u",
15537 pHddCtx->cfg_ini->nDeferScanTimeInterval);
15538
15539 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015540 pAdapter);
15541
Agarwal Ashish57e84372014-12-05 18:26:53 +053015542 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015543 "Return old cached scan as all channels and no of channels are same");
15544
Agarwal Ashish57e84372014-12-05 18:26:53 +053015545 if (0 > ret)
15546 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015547
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015548 hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015549
15550 status = eHAL_STATUS_SUCCESS;
15551 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053015552 }
15553 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015554 }
15555
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015556 /* Flush the scan results(only p2p beacons) for STA scan and P2P
15557 * search (Flush on both full scan and social scan but not on single
15558 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
15559 */
15560
15561 /* Supplicant does single channel scan after 8-way handshake
15562 * and in that case driver shoudnt flush scan results. If
15563 * driver flushes the scan results here and unfortunately if
15564 * the AP doesnt respond to our probe req then association
15565 * fails which is not desired
15566 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015567 if ((request->n_ssids == 1)
15568 && (request->ssids != NULL)
15569 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
15570 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015571
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015572 if( is_p2p_scan ||
15573 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015574 {
15575 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
15576 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
15577 pAdapter->sessionId );
15578 }
15579
15580 if( request->ie_len )
15581 {
15582 /* save this for future association (join requires this) */
15583 /*TODO: Array needs to be converted to dynamic allocation,
15584 * as multiple ie.s can be sent in cfg80211_scan_request structure
15585 * CR 597966
15586 */
15587 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
15588 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
15589 pScanInfo->scanAddIE.length = request->ie_len;
15590
15591 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15592 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15593 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015594 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015595 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070015596 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015597 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
15598 memcpy( pwextBuf->roamProfile.addIEScan,
15599 request->ie, request->ie_len);
15600 }
15601 else
15602 {
15603 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
15604 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070015605 }
15606
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015607 }
15608 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
15609 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
15610
15611 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
15612 request->ie_len);
15613 if (pP2pIe != NULL)
15614 {
15615#ifdef WLAN_FEATURE_P2P_DEBUG
15616 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
15617 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
15618 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053015619 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015620 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
15621 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15622 "Go nego completed to Connection is started");
15623 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15624 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053015625 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015626 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
15627 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015628 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015629 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
15630 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15631 "Disconnected state to Connection is started");
15632 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15633 "for 4way Handshake");
15634 }
15635#endif
15636
15637 /* no_cck will be set during p2p find to disable 11b rates */
15638 if(TRUE == request->no_cck)
15639 {
15640 hddLog(VOS_TRACE_LEVEL_INFO,
15641 "%s: This is a P2P Search", __func__);
15642 scanRequest.p2pSearch = 1;
15643
15644 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053015645 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015646 /* set requestType to P2P Discovery */
15647 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
15648 }
15649
15650 /*
15651 Skip Dfs Channel in case of P2P Search
15652 if it is set in ini file
15653 */
15654 if(cfg_param->skipDfsChnlInP2pSearch)
15655 {
15656 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015657 }
15658 else
15659 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015660 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015661 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015662
Agarwal Ashish4f616132013-12-30 23:32:50 +053015663 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015664 }
15665 }
15666
15667 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
15668
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015669#ifdef FEATURE_WLAN_TDLS
15670 /* if tdls disagree scan right now, return immediately.
15671 tdls will schedule the scan when scan is allowed. (return SUCCESS)
15672 or will reject the scan if any TDLS is in progress. (return -EBUSY)
15673 */
15674 status = wlan_hdd_tdls_scan_callback (pAdapter,
15675 wiphy,
15676#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15677 dev,
15678#endif
15679 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015680 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015681 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053015682 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015683 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
15684 "scan rejected %d", __func__, status);
15685 else
15686 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
15687 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015688 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053015689 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015690 }
15691#endif
15692
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015693 /* acquire the wakelock to avoid the apps suspend during the scan. To
15694 * address the following issues.
15695 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
15696 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
15697 * for long time, this result in apps running at full power for long time.
15698 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
15699 * be stuck in full power because of resume BMPS
15700 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015701 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015702
Nirav Shah20ac06f2013-12-12 18:14:06 +053015703 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
15704 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015705 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
15706 scanRequest.requestType, scanRequest.scanType,
15707 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053015708 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
15709
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015710 if (pHddCtx->spoofMacAddr.isEnabled &&
15711 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053015712 {
15713 hddLog(VOS_TRACE_LEVEL_INFO,
15714 "%s: MAC Spoofing enabled for current scan", __func__);
15715 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15716 * to fill TxBds for probe request during current scan
15717 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015718 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053015719 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015720
15721 if(status != VOS_STATUS_SUCCESS)
15722 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015723 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015724 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053015725#ifdef FEATURE_WLAN_TDLS
15726 wlan_hdd_tdls_scan_done_callback(pAdapter);
15727#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015728 goto free_mem;
15729 }
Siddharth Bhal76972212014-10-15 16:22:51 +053015730 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053015731 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070015732 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015733 pAdapter->sessionId, &scanRequest, &scanId,
15734 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070015735
Jeff Johnson295189b2012-06-20 16:38:30 -070015736 if (eHAL_STATUS_SUCCESS != status)
15737 {
15738 hddLog(VOS_TRACE_LEVEL_ERROR,
15739 "%s: sme_ScanRequest returned error %d", __func__, status);
15740 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015741 if(eHAL_STATUS_RESOURCES == status)
15742 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015743 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
15744 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015745 status = -EBUSY;
15746 } else {
15747 status = -EIO;
15748 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015749 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015750
15751#ifdef FEATURE_WLAN_TDLS
15752 wlan_hdd_tdls_scan_done_callback(pAdapter);
15753#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015754 goto free_mem;
15755 }
15756
15757 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015758 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070015759 pAdapter->request = request;
15760 pScanInfo->scanId = scanId;
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015761 pScanInfo->no_cck = request->no_cck;
15762 pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
15763 for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
15764 pHddCtx->scan_info.last_scan_channelList[i] =
15765 request->channels[i]->hw_value;
15766 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015767
15768 complete(&pScanInfo->scan_req_completion_event);
15769
15770free_mem:
15771 if( scanRequest.SSIDs.SSIDList )
15772 {
15773 vos_mem_free(scanRequest.SSIDs.SSIDList);
15774 }
15775
15776 if( channelList )
15777 vos_mem_free( channelList );
15778
15779 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015780 return status;
15781}
15782
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015783int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
15784#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15785 struct net_device *dev,
15786#endif
15787 struct cfg80211_scan_request *request)
15788{
15789 int ret;
15790
15791 vos_ssr_protect(__func__);
15792 ret = __wlan_hdd_cfg80211_scan(wiphy,
15793#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15794 dev,
15795#endif
15796 request);
15797 vos_ssr_unprotect(__func__);
15798
15799 return ret;
15800}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015801
15802void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
15803{
15804 v_U8_t iniDot11Mode =
15805 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
15806 eHddDot11Mode hddDot11Mode = iniDot11Mode;
15807
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015808 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
15809 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015810 switch ( iniDot11Mode )
15811 {
15812 case eHDD_DOT11_MODE_AUTO:
15813 case eHDD_DOT11_MODE_11ac:
15814 case eHDD_DOT11_MODE_11ac_ONLY:
15815#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053015816 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
15817 sme_IsFeatureSupportedByFW(DOT11AC) )
15818 hddDot11Mode = eHDD_DOT11_MODE_11ac;
15819 else
15820 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015821#else
15822 hddDot11Mode = eHDD_DOT11_MODE_11n;
15823#endif
15824 break;
15825 case eHDD_DOT11_MODE_11n:
15826 case eHDD_DOT11_MODE_11n_ONLY:
15827 hddDot11Mode = eHDD_DOT11_MODE_11n;
15828 break;
15829 default:
15830 hddDot11Mode = iniDot11Mode;
15831 break;
15832 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015833#ifdef WLAN_FEATURE_AP_HT40_24G
15834 if (operationChannel > SIR_11B_CHANNEL_END)
15835#endif
15836 {
15837 /* This call decides required channel bonding mode */
15838 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015839 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053015840 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015841 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015842}
15843
Jeff Johnson295189b2012-06-20 16:38:30 -070015844/*
15845 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015846 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015847 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015848int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053015849 const u8 *ssid, size_t ssid_len, const u8 *bssid,
15850 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070015851{
15852 int status = 0;
15853 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080015854 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015855 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015856 v_U32_t roamId;
15857 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070015858 eCsrAuthType RSNAuthType;
15859
15860 ENTER();
15861
15862 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015863 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015864 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015865
15866 status = wlan_hdd_validate_context(pHddCtx);
15867 if (status)
15868 {
Yue Mae36e3552014-03-05 17:06:20 -080015869 return status;
15870 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015871
Jeff Johnson295189b2012-06-20 16:38:30 -070015872 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
15873 {
15874 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
15875 return -EINVAL;
15876 }
15877
Nitesh Shah9b066282017-06-06 18:05:52 +053015878
Jeff Johnson295189b2012-06-20 16:38:30 -070015879 pRoamProfile = &pWextState->roamProfile;
15880
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015881 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070015882 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015883 hdd_station_ctx_t *pHddStaCtx;
15884 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053015885 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015886
Siddharth Bhalda0d1622015-04-24 15:47:49 +053015887 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
15888
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015889 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070015890 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
15891 {
15892 /*QoS not enabled in cfg file*/
15893 pRoamProfile->uapsd_mask = 0;
15894 }
15895 else
15896 {
15897 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015898 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070015899 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
15900 }
15901
15902 pRoamProfile->SSIDs.numOfSSIDs = 1;
15903 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
15904 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015905 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070015906 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
15907 ssid, ssid_len);
15908
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015909 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
15910 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
15911
Jeff Johnson295189b2012-06-20 16:38:30 -070015912 if (bssid)
15913 {
15914 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015915 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015916 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015917 /* Save BSSID in seperate variable as well, as RoamProfile
15918 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070015919 case of join failure we should send valid BSSID to supplicant
15920 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015921 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015922 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015923
Jeff Johnson295189b2012-06-20 16:38:30 -070015924 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015925 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070015926 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015927 /* Store bssid_hint to use in the scan filter. */
15928 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15929 WNI_CFG_BSSID_LEN);
15930 /*
15931 * Save BSSID in seperate variable as well, as RoamProfile
15932 * BSSID is getting zeroed out in the association process. And in
15933 * case of join failure we should send valid BSSID to supplicant
15934 */
15935 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15936 WNI_CFG_BSSID_LEN);
15937 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15938 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015939 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015940
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015941
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015942 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15943 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015944 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15945 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015946 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015947 /*set gen ie*/
15948 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15949 /*set auth*/
15950 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15951 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015952#ifdef FEATURE_WLAN_WAPI
15953 if (pAdapter->wapi_info.nWapiMode)
15954 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015955 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015956 switch (pAdapter->wapi_info.wapiAuthMode)
15957 {
15958 case WAPI_AUTH_MODE_PSK:
15959 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015960 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015961 pAdapter->wapi_info.wapiAuthMode);
15962 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15963 break;
15964 }
15965 case WAPI_AUTH_MODE_CERT:
15966 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015967 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015968 pAdapter->wapi_info.wapiAuthMode);
15969 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15970 break;
15971 }
15972 } // End of switch
15973 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15974 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15975 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015976 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015977 pRoamProfile->AuthType.numEntries = 1;
15978 pRoamProfile->EncryptionType.numEntries = 1;
15979 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15980 pRoamProfile->mcEncryptionType.numEntries = 1;
15981 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15982 }
15983 }
15984#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015985#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015986 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015987 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15988 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
15989 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015990 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
15991 sizeof (tSirGtkOffloadParams));
15992 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015993 }
15994#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015995 pRoamProfile->csrPersona = pAdapter->device_mode;
15996
Jeff Johnson32d95a32012-09-10 13:15:23 -070015997 if( operatingChannel )
15998 {
15999 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
16000 pRoamProfile->ChannelInfo.numOfChannels = 1;
16001 }
Chet Lanctot186b5732013-03-18 10:26:30 -070016002 else
16003 {
16004 pRoamProfile->ChannelInfo.ChannelList = NULL;
16005 pRoamProfile->ChannelInfo.numOfChannels = 0;
16006 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016007 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
16008 {
16009 hdd_select_cbmode(pAdapter,operatingChannel);
16010 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053016011
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016012 /*
16013 * Change conn_state to connecting before sme_RoamConnect(),
16014 * because sme_RoamConnect() has a direct path to call
16015 * hdd_smeRoamCallback(), which will change the conn_state
16016 * If direct path, conn_state will be accordingly changed
16017 * to NotConnected or Associated by either
16018 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
16019 * in sme_RoamCallback()
16020 * if sme_RomConnect is to be queued,
16021 * Connecting state will remain until it is completed.
16022 * If connection state is not changed,
16023 * connection state will remain in eConnectionState_NotConnected state.
16024 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
16025 * if conn state is eConnectionState_NotConnected.
16026 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
16027 * informed of connect result indication which is an issue.
16028 */
16029
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016030 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16031 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053016032 {
16033 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016034 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016035 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
16036 eConnectionState_Connecting);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016037 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
16038 hdd_wait_for_ecsa_complete(pHddCtx);
Abhishek Singhf4669da2014-05-26 15:07:49 +053016039 }
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016040
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016041 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070016042 pAdapter->sessionId, pRoamProfile, &roamId);
16043
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016044 if ((eHAL_STATUS_SUCCESS != status) &&
16045 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16046 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016047
16048 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016049 hddLog(VOS_TRACE_LEVEL_ERROR,
16050 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
16051 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016052 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016053 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016054 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016055 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016056
16057 pRoamProfile->ChannelInfo.ChannelList = NULL;
16058 pRoamProfile->ChannelInfo.numOfChannels = 0;
16059
Jeff Johnson295189b2012-06-20 16:38:30 -070016060 }
16061 else
16062 {
16063 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
16064 return -EINVAL;
16065 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080016066 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016067 return status;
16068}
16069
16070/*
16071 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
16072 * This function is used to set the authentication type (OPEN/SHARED).
16073 *
16074 */
16075static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
16076 enum nl80211_auth_type auth_type)
16077{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016078 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016079 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16080
16081 ENTER();
16082
16083 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016084 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070016085 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016086 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016087 hddLog(VOS_TRACE_LEVEL_INFO,
16088 "%s: set authentication type to AUTOSWITCH", __func__);
16089 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
16090 break;
16091
16092 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016093#ifdef WLAN_FEATURE_VOWIFI_11R
16094 case NL80211_AUTHTYPE_FT:
16095#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016096 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016097 "%s: set authentication type to OPEN", __func__);
16098 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
16099 break;
16100
16101 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016102 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016103 "%s: set authentication type to SHARED", __func__);
16104 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
16105 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016106#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016107 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016108 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016109 "%s: set authentication type to CCKM WPA", __func__);
16110 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
16111 break;
16112#endif
16113
16114
16115 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016116 hddLog(VOS_TRACE_LEVEL_ERROR,
16117 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016118 auth_type);
16119 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
16120 return -EINVAL;
16121 }
16122
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016123 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016124 pHddStaCtx->conn_info.authType;
16125 return 0;
16126}
16127
16128/*
16129 * FUNCTION: wlan_hdd_set_akm_suite
16130 * This function is used to set the key mgmt type(PSK/8021x).
16131 *
16132 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016133static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016134 u32 key_mgmt
16135 )
16136{
16137 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16138 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053016139 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016140#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016141#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016142#endif
16143#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016144#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016145#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016146 /*set key mgmt type*/
16147 switch(key_mgmt)
16148 {
16149 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053016150 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016151#ifdef WLAN_FEATURE_VOWIFI_11R
16152 case WLAN_AKM_SUITE_FT_PSK:
16153#endif
16154 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070016155 __func__);
16156 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
16157 break;
16158
16159 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053016160 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016161#ifdef WLAN_FEATURE_VOWIFI_11R
16162 case WLAN_AKM_SUITE_FT_8021X:
16163#endif
16164 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070016165 __func__);
16166 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16167 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016168#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016169#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
16170#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
16171 case WLAN_AKM_SUITE_CCKM:
16172 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
16173 __func__);
16174 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
16175 break;
16176#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070016177#ifndef WLAN_AKM_SUITE_OSEN
16178#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
16179 case WLAN_AKM_SUITE_OSEN:
16180 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
16181 __func__);
16182 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16183 break;
16184#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016185
16186 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016187 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016188 __func__, key_mgmt);
16189 return -EINVAL;
16190
16191 }
16192 return 0;
16193}
16194
16195/*
16196 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016197 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070016198 * (NONE/WEP40/WEP104/TKIP/CCMP).
16199 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016200static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
16201 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070016202 bool ucast
16203 )
16204{
16205 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016206 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016207 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16208
16209 ENTER();
16210
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016211 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016212 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053016213 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070016214 __func__, cipher);
16215 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16216 }
16217 else
16218 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016219
Jeff Johnson295189b2012-06-20 16:38:30 -070016220 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016221 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016222 {
16223 case IW_AUTH_CIPHER_NONE:
16224 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16225 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016226
Jeff Johnson295189b2012-06-20 16:38:30 -070016227 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016228 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070016229 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016230
Jeff Johnson295189b2012-06-20 16:38:30 -070016231 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016232 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070016233 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016234
Jeff Johnson295189b2012-06-20 16:38:30 -070016235 case WLAN_CIPHER_SUITE_TKIP:
16236 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
16237 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016238
Jeff Johnson295189b2012-06-20 16:38:30 -070016239 case WLAN_CIPHER_SUITE_CCMP:
16240 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16241 break;
16242#ifdef FEATURE_WLAN_WAPI
16243 case WLAN_CIPHER_SUITE_SMS4:
16244 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
16245 break;
16246#endif
16247
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016248#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016249 case WLAN_CIPHER_SUITE_KRK:
16250 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
16251 break;
16252#endif
16253 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016254 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016255 __func__, cipher);
16256 return -EOPNOTSUPP;
16257 }
16258 }
16259
16260 if (ucast)
16261 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016262 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016263 __func__, encryptionType);
16264 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16265 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016266 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016267 encryptionType;
16268 }
16269 else
16270 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016271 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016272 __func__, encryptionType);
16273 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
16274 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
16275 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
16276 }
16277
16278 return 0;
16279}
16280
16281
16282/*
16283 * FUNCTION: wlan_hdd_cfg80211_set_ie
16284 * This function is used to parse WPA/RSN IE's.
16285 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016286int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016287#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16288 const u8 *ie,
16289#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016290 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016291#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016292 size_t ie_len
16293 )
16294{
16295 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016296#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16297 const u8 *genie = ie;
16298#else
Jeff Johnson295189b2012-06-20 16:38:30 -070016299 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016300#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016301 v_U16_t remLen = ie_len;
16302#ifdef FEATURE_WLAN_WAPI
16303 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
16304 u16 *tmp;
16305 v_U16_t akmsuiteCount;
16306 int *akmlist;
16307#endif
16308 ENTER();
16309
16310 /* clear previous assocAddIE */
16311 pWextState->assocAddIE.length = 0;
16312 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016313 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016314
16315 while (remLen >= 2)
16316 {
16317 v_U16_t eLen = 0;
16318 v_U8_t elementId;
16319 elementId = *genie++;
16320 eLen = *genie++;
16321 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016322
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053016323 /* Sanity check on eLen */
16324 if (eLen > remLen) {
16325 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
16326 __func__, eLen, elementId);
16327 VOS_ASSERT(0);
16328 return -EINVAL;
16329 }
16330
Arif Hussain6d2a3322013-11-17 19:50:10 -080016331 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070016332 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016333
16334 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070016335 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016336 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016337 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 -070016338 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016339 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016340 "%s: Invalid WPA IE", __func__);
16341 return -EINVAL;
16342 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016343 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070016344 {
16345 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016346 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016347 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016348
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016349 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016350 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016351 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
16352 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016353 VOS_ASSERT(0);
16354 return -ENOMEM;
16355 }
16356 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16357 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16358 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016359
Jeff Johnson295189b2012-06-20 16:38:30 -070016360 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
16361 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16362 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16363 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016364 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
16365 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053016366 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16367 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
16368 __func__, eLen);
16369 VOS_ASSERT(0);
16370 return -EINVAL;
16371 }
16372
Jeff Johnson295189b2012-06-20 16:38:30 -070016373 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
16374 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16375 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
16376 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
16377 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
16378 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016379 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053016380 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070016381 {
16382 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016383 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016384 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016385
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016386 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016387 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016388 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16389 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016390 VOS_ASSERT(0);
16391 return -ENOMEM;
16392 }
16393 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16394 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16395 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016396
Jeff Johnson295189b2012-06-20 16:38:30 -070016397 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16398 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16399 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016400#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016401 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
16402 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016403 /*Consider WFD IE, only for P2P Client */
16404 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
16405 {
16406 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016407 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016408 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016409
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016410 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016411 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016412 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16413 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016414 VOS_ASSERT(0);
16415 return -ENOMEM;
16416 }
16417 // WFD IE is saved to Additional IE ; it should be accumulated to handle
16418 // WPS IE + P2P IE + WFD IE
16419 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16420 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016421
Jeff Johnson295189b2012-06-20 16:38:30 -070016422 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16423 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16424 }
16425#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016426 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016427 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016428 HS20_OUI_TYPE_SIZE)) )
16429 {
16430 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016431 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016432 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016433
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016434 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016435 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016436 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16437 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016438 VOS_ASSERT(0);
16439 return -ENOMEM;
16440 }
16441 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16442 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016443
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016444 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16445 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16446 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016447 /* Appending OSEN Information Element in Assiciation Request */
16448 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
16449 OSEN_OUI_TYPE_SIZE)) )
16450 {
16451 v_U16_t curAddIELen = pWextState->assocAddIE.length;
16452 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
16453 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016454
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016455 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016456 {
16457 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16458 "Need bigger buffer space");
16459 VOS_ASSERT(0);
16460 return -ENOMEM;
16461 }
16462 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16463 pWextState->assocAddIE.length += eLen + 2;
16464
16465 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
16466 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16467 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16468 }
16469
Abhishek Singh4322e622015-06-10 15:42:54 +053016470 /* Update only for WPA IE */
16471 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
16472 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016473
16474 /* populating as ADDIE in beacon frames */
16475 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016476 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016477 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
16478 {
16479 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16480 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
16481 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16482 {
16483 hddLog(LOGE,
16484 "Coldn't pass "
16485 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
16486 }
16487 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
16488 else
16489 hddLog(LOGE,
16490 "Could not pass on "
16491 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
16492
16493 /* IBSS mode doesn't contain params->proberesp_ies still
16494 beaconIE's need to be populated in probe response frames */
16495 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
16496 {
16497 u16 rem_probe_resp_ie_len = eLen + 2;
16498 u8 probe_rsp_ie_len[3] = {0};
16499 u8 counter = 0;
16500
16501 /* Check Probe Resp Length if it is greater then 255 then
16502 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
16503 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
16504 not able Store More then 255 bytes into One Variable */
16505
16506 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
16507 {
16508 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
16509 {
16510 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
16511 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
16512 }
16513 else
16514 {
16515 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
16516 rem_probe_resp_ie_len = 0;
16517 }
16518 }
16519
16520 rem_probe_resp_ie_len = 0;
16521
16522 if (probe_rsp_ie_len[0] > 0)
16523 {
16524 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16525 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
16526 (tANI_U8*)(genie - 2),
16527 probe_rsp_ie_len[0], NULL,
16528 eANI_BOOLEAN_FALSE)
16529 == eHAL_STATUS_FAILURE)
16530 {
16531 hddLog(LOGE,
16532 "Could not pass"
16533 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
16534 }
16535 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
16536 }
16537
16538 if (probe_rsp_ie_len[1] > 0)
16539 {
16540 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16541 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
16542 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16543 probe_rsp_ie_len[1], NULL,
16544 eANI_BOOLEAN_FALSE)
16545 == eHAL_STATUS_FAILURE)
16546 {
16547 hddLog(LOGE,
16548 "Could not pass"
16549 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
16550 }
16551 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
16552 }
16553
16554 if (probe_rsp_ie_len[2] > 0)
16555 {
16556 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16557 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
16558 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16559 probe_rsp_ie_len[2], NULL,
16560 eANI_BOOLEAN_FALSE)
16561 == eHAL_STATUS_FAILURE)
16562 {
16563 hddLog(LOGE,
16564 "Could not pass"
16565 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
16566 }
16567 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
16568 }
16569
16570 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16571 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
16572 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16573 {
16574 hddLog(LOGE,
16575 "Could not pass"
16576 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
16577 }
16578 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016579 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070016580 break;
16581 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053016582 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16583 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
16584 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
16585 VOS_ASSERT(0);
16586 return -EINVAL;
16587 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016588 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
16589 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16590 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
16591 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
16592 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16593 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016594
Abhishek Singhb16f3562016-01-20 11:08:32 +053016595 /* Appending extended capabilities with Interworking or
16596 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016597 *
16598 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016599 * interworkingService or bsstransition bit is set to 1.
16600 * Driver is only interested in interworkingService and
16601 * bsstransition capability from supplicant.
16602 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016603 * required from supplicat, it needs to be handled while
16604 * sending Assoc Req in LIM.
16605 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016606 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016607 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016608 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016609 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016610 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016611
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016612 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016613 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016614 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16615 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016616 VOS_ASSERT(0);
16617 return -ENOMEM;
16618 }
16619 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16620 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016621
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016622 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16623 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16624 break;
16625 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016626#ifdef FEATURE_WLAN_WAPI
16627 case WLAN_EID_WAPI:
16628 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016629 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016630 pAdapter->wapi_info.nWapiMode);
16631 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016632 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016633 akmsuiteCount = WPA_GET_LE16(tmp);
16634 tmp = tmp + 1;
16635 akmlist = (int *)(tmp);
16636 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16637 {
16638 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16639 }
16640 else
16641 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016642 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016643 VOS_ASSERT(0);
16644 return -EINVAL;
16645 }
16646
16647 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16648 {
16649 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016650 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016651 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016652 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016653 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016654 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016655 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016656 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016657 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
16658 }
16659 break;
16660#endif
16661 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016662 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016663 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016664 /* when Unknown IE is received we should break and continue
16665 * to the next IE in the buffer instead we were returning
16666 * so changing this to break */
16667 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016668 }
16669 genie += eLen;
16670 remLen -= eLen;
16671 }
16672 EXIT();
16673 return 0;
16674}
16675
16676/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016677 * FUNCTION: hdd_isWPAIEPresent
16678 * Parse the received IE to find the WPA IE
16679 *
16680 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016681static bool hdd_isWPAIEPresent(
16682#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16683 const u8 *ie,
16684#else
16685 u8 *ie,
16686#endif
16687 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016688{
16689 v_U8_t eLen = 0;
16690 v_U16_t remLen = ie_len;
16691 v_U8_t elementId = 0;
16692
16693 while (remLen >= 2)
16694 {
16695 elementId = *ie++;
16696 eLen = *ie++;
16697 remLen -= 2;
16698 if (eLen > remLen)
16699 {
16700 hddLog(VOS_TRACE_LEVEL_ERROR,
16701 "%s: IE length is wrong %d", __func__, eLen);
16702 return FALSE;
16703 }
16704 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16705 {
16706 /* OUI - 0x00 0X50 0XF2
16707 WPA Information Element - 0x01
16708 WPA version - 0x01*/
16709 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16710 return TRUE;
16711 }
16712 ie += eLen;
16713 remLen -= eLen;
16714 }
16715 return FALSE;
16716}
16717
16718/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016719 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016720 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016721 * parameters during connect operation.
16722 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016723int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016724 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016725 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016726{
16727 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016728 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016729 ENTER();
16730
16731 /*set wpa version*/
16732 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
16733
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016734 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016735 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053016736 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016737 {
16738 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16739 }
16740 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
16741 {
16742 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16743 }
16744 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016745
16746 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016747 pWextState->wpaVersion);
16748
16749 /*set authentication type*/
16750 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
16751
16752 if (0 > status)
16753 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016754 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016755 "%s: failed to set authentication type ", __func__);
16756 return status;
16757 }
16758
16759 /*set key mgmt type*/
16760 if (req->crypto.n_akm_suites)
16761 {
16762 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
16763 if (0 > status)
16764 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016765 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070016766 __func__);
16767 return status;
16768 }
16769 }
16770
16771 /*set pairwise cipher type*/
16772 if (req->crypto.n_ciphers_pairwise)
16773 {
16774 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
16775 req->crypto.ciphers_pairwise[0], true);
16776 if (0 > status)
16777 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016778 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016779 "%s: failed to set unicast cipher type", __func__);
16780 return status;
16781 }
16782 }
16783 else
16784 {
16785 /*Reset previous cipher suite to none*/
16786 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
16787 if (0 > status)
16788 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016789 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016790 "%s: failed to set unicast cipher type", __func__);
16791 return status;
16792 }
16793 }
16794
16795 /*set group cipher type*/
16796 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
16797 false);
16798
16799 if (0 > status)
16800 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016801 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070016802 __func__);
16803 return status;
16804 }
16805
Chet Lanctot186b5732013-03-18 10:26:30 -070016806#ifdef WLAN_FEATURE_11W
16807 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
16808#endif
16809
Jeff Johnson295189b2012-06-20 16:38:30 -070016810 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
16811 if (req->ie_len)
16812 {
16813 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
16814 if ( 0 > status)
16815 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016816 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016817 __func__);
16818 return status;
16819 }
16820 }
16821
16822 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016823 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016824 {
16825 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
16826 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
16827 )
16828 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016829 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070016830 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
16831 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016832 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016833 __func__);
16834 return -EOPNOTSUPP;
16835 }
16836 else
16837 {
16838 u8 key_len = req->key_len;
16839 u8 key_idx = req->key_idx;
16840
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016841 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016842 && (CSR_MAX_NUM_KEY > key_idx)
16843 )
16844 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016845 hddLog(VOS_TRACE_LEVEL_INFO,
16846 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016847 __func__, key_idx, key_len);
16848 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016849 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070016850 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016851 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016852 (u8)key_len;
16853 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
16854 }
16855 }
16856 }
16857 }
16858
16859 return status;
16860}
16861
16862/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016863 * FUNCTION: wlan_hdd_try_disconnect
16864 * This function is used to disconnect from previous
16865 * connection
16866 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053016867int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016868{
16869 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016870 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016871 hdd_station_ctx_t *pHddStaCtx;
16872 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016873 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016874
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016875 ret = wlan_hdd_validate_context(pHddCtx);
16876 if (0 != ret)
16877 {
16878 return ret;
16879 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016880 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16881
16882 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
16883
16884 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
16885 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053016886 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016887 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
16888 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053016889 /* Indicate disconnect to SME so that in-progress connection or preauth
16890 * can be aborted
16891 */
16892 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
16893 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016894 spin_lock_bh(&pAdapter->lock_for_active_session);
16895 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16896 {
16897 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16898 }
16899 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053016900 hdd_connSetConnectionState(pHddStaCtx,
16901 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016902 /* Issue disconnect to CSR */
16903 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016904 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016905 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016906 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16907 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
16908 hddLog(LOG1,
16909 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
16910 } else if ( 0 != status ) {
16911 hddLog(LOGE,
16912 FL("csrRoamDisconnect failure, returned %d"),
16913 (int)status );
16914 result = -EINVAL;
16915 goto disconnected;
16916 }
16917 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016918 &pAdapter->disconnect_comp_var,
16919 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016920 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
16921 hddLog(LOGE,
16922 "%s: Failed to disconnect, timed out", __func__);
16923 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016924 }
16925 }
16926 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
16927 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016928 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016929 &pAdapter->disconnect_comp_var,
16930 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016931 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016932 {
16933 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016934 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016935 }
16936 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016937disconnected:
16938 hddLog(LOG1,
16939 FL("Set HDD connState to eConnectionState_NotConnected"));
16940 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16941 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016942}
16943
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016944/**
16945 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16946 * @adapter: Pointer to the HDD adapter
16947 * @req: Pointer to the structure cfg_connect_params receieved from user space
16948 *
16949 * This function will start reassociation if bssid hint, channel hint and
16950 * previous bssid parameters are present in the connect request
16951 *
16952 * Return: success if reassociation is happening
16953 * Error code if reassociation is not permitted or not happening
16954 */
16955#ifdef CFG80211_CONNECT_PREV_BSSID
16956static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16957 struct cfg80211_connect_params *req)
16958{
16959 int status = -EPERM;
16960 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
16961 hddLog(VOS_TRACE_LEVEL_INFO,
16962 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
16963 req->channel_hint->hw_value,
16964 MAC_ADDR_ARRAY(req->bssid_hint));
16965 status = hdd_reassoc(adapter, req->bssid_hint,
16966 req->channel_hint->hw_value,
16967 CONNECT_CMD_USERSPACE);
16968 }
16969 return status;
16970}
16971#else
16972static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16973 struct cfg80211_connect_params *req)
16974{
16975 return -EPERM;
16976}
16977#endif
16978
Abhishek Singhe3beee22017-07-31 15:35:40 +053016979/**
16980 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
16981 * connect in HT20 mode
16982 * @hdd_ctx: hdd context
16983 * @adapter: Pointer to the HDD adapter
16984 * @req: Pointer to the structure cfg_connect_params receieved from user space
16985 *
16986 * This function will check if supplicant has indicated to to connect in HT20
16987 * mode. this is currently applicable only for 2.4Ghz mode only.
16988 * if feature is enabled and supplicant indicate HT20 set
16989 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
16990 *
16991 * Return: void
16992 */
16993#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
16994static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16995 hdd_adapter_t *adapter,
16996 struct cfg80211_connect_params *req)
16997{
16998 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16999 tCsrRoamProfile *roam_profile;
17000
17001 roam_profile = &wext_state->roamProfile;
17002 roam_profile->force_24ghz_in_ht20 = false;
17003 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
17004 !(req->ht_capa.cap_info &
17005 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
17006 roam_profile->force_24ghz_in_ht20 = true;
17007
17008 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
17009 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
17010}
17011#else
17012static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
17013 hdd_adapter_t *adapter,
17014 struct cfg80211_connect_params *req)
17015{
17016 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
17017 tCsrRoamProfile *roam_profile;
17018
17019 roam_profile = &wext_state->roamProfile;
17020 roam_profile->force_24ghz_in_ht20 = false;
17021}
17022#endif
17023
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017024/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053017025 * FUNCTION: __wlan_hdd_cfg80211_connect
17026 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070017027 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017028static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017029 struct net_device *ndev,
17030 struct cfg80211_connect_params *req
17031 )
17032{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017033 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017034 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053017035#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
17036 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017037 const u8 *bssid_hint = req->bssid_hint;
17038#else
17039 const u8 *bssid_hint = NULL;
17040#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017041 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017042 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053017043 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017044
17045 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017046
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017047 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17048 TRACE_CODE_HDD_CFG80211_CONNECT,
17049 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017050 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017051 "%s: device_mode = %s (%d)", __func__,
17052 hdd_device_modetoString(pAdapter->device_mode),
17053 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017054
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017055 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017056 if (!pHddCtx)
17057 {
17058 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17059 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053017060 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017061 }
17062
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017063 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017064 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017065 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017066 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017067 }
17068
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053017069 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
17070 return -EINVAL;
17071
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017072 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
17073 if (0 == status)
17074 return status;
17075
Agarwal Ashish51325b52014-06-16 16:50:49 +053017076
Jeff Johnson295189b2012-06-20 16:38:30 -070017077#ifdef WLAN_BTAMP_FEATURE
17078 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017079 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070017080 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017081 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017082 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080017083 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070017084 }
17085#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017086
17087 //If Device Mode is Station Concurrent Sessions Exit BMps
17088 //P2P Mode will be taken care in Open/close adapter
17089 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053017090 (vos_concurrent_open_sessions_running())) {
17091 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
17092 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017093 }
17094
17095 /*Try disconnecting if already in connected state*/
17096 status = wlan_hdd_try_disconnect(pAdapter);
17097 if ( 0 > status)
17098 {
17099 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17100 " connection"));
17101 return -EALREADY;
17102 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053017103 /* Check for max concurrent connections after doing disconnect if any*/
17104 if (vos_max_concurrent_connections_reached()) {
17105 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17106 return -ECONNREFUSED;
17107 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017108
Jeff Johnson295189b2012-06-20 16:38:30 -070017109 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017110 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070017111
17112 if ( 0 > status)
17113 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017114 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070017115 __func__);
17116 return status;
17117 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053017118
17119 if (pHddCtx->spoofMacAddr.isEnabled)
17120 {
17121 hddLog(VOS_TRACE_LEVEL_INFO,
17122 "%s: MAC Spoofing enabled ", __func__);
17123 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
17124 * to fill TxBds for probe request during SSID scan which may happen
17125 * as part of connect command
17126 */
17127 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
17128 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
17129 if (status != VOS_STATUS_SUCCESS)
17130 return -ECONNREFUSED;
17131 }
17132
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017133 if (req->channel)
17134 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070017135 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017136 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053017137
17138 /* Abort if any scan is going on */
17139 status = wlan_hdd_scan_abort(pAdapter);
17140 if (0 != status)
17141 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
17142
Abhishek Singhe3beee22017-07-31 15:35:40 +053017143 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
17144
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017145 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
17146 req->ssid_len, req->bssid,
17147 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017148
Sushant Kaushikd7083982015-03-18 14:33:24 +053017149 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017150 {
17151 //ReEnable BMPS if disabled
17152 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
17153 (NULL != pHddCtx))
17154 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053017155 if (pHddCtx->hdd_wlan_suspended)
17156 {
17157 hdd_set_pwrparams(pHddCtx);
17158 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017159 //ReEnable Bmps and Imps back
17160 hdd_enable_bmps_imps(pHddCtx);
17161 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053017162 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070017163 return status;
17164 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017165 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017166 EXIT();
17167 return status;
17168}
17169
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017170static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
17171 struct net_device *ndev,
17172 struct cfg80211_connect_params *req)
17173{
17174 int ret;
17175 vos_ssr_protect(__func__);
17176 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
17177 vos_ssr_unprotect(__func__);
17178
17179 return ret;
17180}
Jeff Johnson295189b2012-06-20 16:38:30 -070017181
17182/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017183 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070017184 * This function is used to issue a disconnect request to SME
17185 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017186static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017187 struct net_device *dev,
17188 u16 reason
17189 )
17190{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017191 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017192 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017193 tCsrRoamProfile *pRoamProfile;
17194 hdd_station_ctx_t *pHddStaCtx;
17195 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017196#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017197 tANI_U8 staIdx;
17198#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017199
Jeff Johnson295189b2012-06-20 16:38:30 -070017200 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017201
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017202 if (!pAdapter) {
17203 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17204 return -EINVAL;
17205 }
17206
17207 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17208 if (!pHddStaCtx) {
17209 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
17210 return -EINVAL;
17211 }
17212
17213 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17214 status = wlan_hdd_validate_context(pHddCtx);
17215 if (0 != status)
17216 {
17217 return status;
17218 }
17219
17220 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
17221
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017222 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17223 TRACE_CODE_HDD_CFG80211_DISCONNECT,
17224 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017225 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
17226 __func__, hdd_device_modetoString(pAdapter->device_mode),
17227 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017228
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017229 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
17230 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070017231
Jeff Johnson295189b2012-06-20 16:38:30 -070017232 if (NULL != pRoamProfile)
17233 {
17234 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017235 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
17236 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070017237 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017238 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070017239 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017240 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070017241 switch(reason)
17242 {
17243 case WLAN_REASON_MIC_FAILURE:
17244 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
17245 break;
17246
17247 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
17248 case WLAN_REASON_DISASSOC_AP_BUSY:
17249 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
17250 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
17251 break;
17252
17253 case WLAN_REASON_PREV_AUTH_NOT_VALID:
17254 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053017255 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070017256 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
17257 break;
17258
Jeff Johnson295189b2012-06-20 16:38:30 -070017259 default:
17260 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
17261 break;
17262 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017263 pScanInfo = &pHddCtx->scan_info;
17264 if (pScanInfo->mScanPending)
17265 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017266 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017267 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053017268 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017269 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017270 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053017271 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017272#ifdef FEATURE_WLAN_TDLS
17273 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017274 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017275 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017276 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
17277 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017278 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017279 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017280 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017281 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017282 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017283 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017284 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017285 status = sme_DeleteTdlsPeerSta(
17286 WLAN_HDD_GET_HAL_CTX(pAdapter),
17287 pAdapter->sessionId,
17288 mac);
17289 if (status != eHAL_STATUS_SUCCESS) {
17290 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
17291 return -EPERM;
17292 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017293 }
17294 }
17295#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053017296
17297 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
17298 reasonCode,
17299 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017300 status = wlan_hdd_disconnect(pAdapter, reasonCode);
17301 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070017302 {
17303 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017304 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017305 __func__, (int)status );
17306 return -EINVAL;
17307 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017308 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017309 else
17310 {
17311 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
17312 "called while in %d state", __func__,
17313 pHddStaCtx->conn_info.connState);
17314 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017315 }
17316 else
17317 {
17318 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
17319 }
17320
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017321 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017322 return status;
17323}
17324
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017325static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
17326 struct net_device *dev,
17327 u16 reason
17328 )
17329{
17330 int ret;
17331 vos_ssr_protect(__func__);
17332 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
17333 vos_ssr_unprotect(__func__);
17334
17335 return ret;
17336}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017337
Jeff Johnson295189b2012-06-20 16:38:30 -070017338/*
17339 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017340 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070017341 * settings in IBSS mode.
17342 */
17343static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017344 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070017345 struct cfg80211_ibss_params *params
17346 )
17347{
17348 int status = 0;
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017349 tANI_U32 ret;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017350 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070017351 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
17352 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017353
Jeff Johnson295189b2012-06-20 16:38:30 -070017354 ENTER();
17355
17356 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070017357 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070017358
17359 if (params->ie_len && ( NULL != params->ie) )
17360 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017361 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17362 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017363 {
17364 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
17365 encryptionType = eCSR_ENCRYPT_TYPE_AES;
17366 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017367 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017368 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017369 tDot11fIEWPA dot11WPAIE;
17370 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017371 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017372
Wilson Yang00256342013-10-10 23:13:38 -070017373 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017374 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17375 params->ie_len, DOT11F_EID_WPA);
17376 if ( NULL != ie )
17377 {
17378 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
Hanumanth Reddy Pothulad6d2d2c2018-06-27 12:28:12 +053017379
17380 if (ie[1] < DOT11F_IE_WPA_MIN_LEN ||
17381 ie[1] > DOT11F_IE_WPA_MAX_LEN) {
17382 hddLog(LOGE, FL("invalid ie len:%d"), ie[1]);
17383 return -EINVAL;
17384 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017385 // Unpack the WPA IE
17386 //Skip past the EID byte and length byte - and four byte WiFi OUI
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017387 ret = dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017388 &ie[2+4],
17389 ie[1] - 4,
17390 &dot11WPAIE);
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017391 if (DOT11F_FAILED(ret))
17392 {
17393 hddLog(LOGE,
17394 FL("unpack failed status:(0x%08x)"),
17395 ret);
17396 return -EINVAL;
17397 }
17398
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017399 /*Extract the multicast cipher, the encType for unicast
17400 cipher for wpa-none is none*/
17401 encryptionType =
17402 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
17403 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017404 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017405
Jeff Johnson295189b2012-06-20 16:38:30 -070017406 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
17407
17408 if (0 > status)
17409 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017410 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070017411 __func__);
17412 return status;
17413 }
17414 }
17415
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017416 pWextState->roamProfile.AuthType.authType[0] =
17417 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070017418 eCSR_AUTH_TYPE_OPEN_SYSTEM;
Jeff Johnson295189b2012-06-20 16:38:30 -070017419 if (params->privacy)
17420 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017421 /* Security enabled IBSS, At this time there is no information available
17422 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070017423 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017424 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070017425 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017426 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070017427 *enable privacy bit in beacons */
17428
17429 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
17430 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017431 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17432 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070017433 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
17434 pWextState->roamProfile.EncryptionType.numEntries = 1;
17435 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070017436 return status;
17437}
17438
17439/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017440 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017441 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017442 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017443static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017444 struct net_device *dev,
17445 struct cfg80211_ibss_params *params
17446 )
17447{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017448 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017449 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17450 tCsrRoamProfile *pRoamProfile;
17451 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017452 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17453 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017454 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070017455
17456 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017457
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017458 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17459 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
17460 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017461 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017462 "%s: device_mode = %s (%d)", __func__,
17463 hdd_device_modetoString(pAdapter->device_mode),
17464 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017465
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017466 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017467 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017468 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017469 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017470 }
17471
17472 if (NULL == pWextState)
17473 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017474 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017475 __func__);
17476 return -EIO;
17477 }
17478
Agarwal Ashish51325b52014-06-16 16:50:49 +053017479 if (vos_max_concurrent_connections_reached()) {
17480 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17481 return -ECONNREFUSED;
17482 }
17483
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017484 /*Try disconnecting if already in connected state*/
17485 status = wlan_hdd_try_disconnect(pAdapter);
17486 if ( 0 > status)
17487 {
17488 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17489 " IBSS connection"));
17490 return -EALREADY;
17491 }
17492
Jeff Johnson295189b2012-06-20 16:38:30 -070017493 pRoamProfile = &pWextState->roamProfile;
17494
17495 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
17496 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017497 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017498 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017499 return -EINVAL;
17500 }
17501
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017502 /* BSSID is provided by upper layers hence no need to AUTO generate */
17503 if (NULL != params->bssid) {
17504 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17505 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
17506 hddLog (VOS_TRACE_LEVEL_ERROR,
17507 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17508 return -EIO;
17509 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017510 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017511 }
krunal sonie9002db2013-11-25 14:24:17 -080017512 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
17513 {
17514 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17515 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
17516 {
17517 hddLog (VOS_TRACE_LEVEL_ERROR,
17518 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17519 return -EIO;
17520 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017521
17522 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080017523 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017524 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080017525 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017526
Jeff Johnson295189b2012-06-20 16:38:30 -070017527 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070017528 if (NULL !=
17529#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17530 params->chandef.chan)
17531#else
17532 params->channel)
17533#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017534 {
17535 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017536 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17537 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
17538 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17539 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017540
17541 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017542 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070017543 ieee80211_frequency_to_channel(
17544#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17545 params->chandef.chan->center_freq);
17546#else
17547 params->channel->center_freq);
17548#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017549
17550 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17551 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070017552 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017553 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
17554 __func__);
17555 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070017556 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017557
17558 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017559 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017560 if (channelNum == validChan[indx])
17561 {
17562 break;
17563 }
17564 }
17565 if (indx >= numChans)
17566 {
17567 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017568 __func__, channelNum);
17569 return -EINVAL;
17570 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017571 /* Set the Operational Channel */
17572 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
17573 channelNum);
17574 pRoamProfile->ChannelInfo.numOfChannels = 1;
17575 pHddStaCtx->conn_info.operationChannel = channelNum;
17576 pRoamProfile->ChannelInfo.ChannelList =
17577 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070017578 }
17579
17580 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017581 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070017582 if (status < 0)
17583 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017584 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070017585 __func__);
17586 return status;
17587 }
17588
17589 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017590 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053017591 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017592 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017593
17594 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017595 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017596
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017597 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017598 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017599}
17600
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017601static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17602 struct net_device *dev,
17603 struct cfg80211_ibss_params *params
17604 )
17605{
17606 int ret = 0;
17607
17608 vos_ssr_protect(__func__);
17609 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17610 vos_ssr_unprotect(__func__);
17611
17612 return ret;
17613}
17614
Jeff Johnson295189b2012-06-20 16:38:30 -070017615/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017616 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017617 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017618 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017619static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017620 struct net_device *dev
17621 )
17622{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017623 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017624 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17625 tCsrRoamProfile *pRoamProfile;
17626 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017627 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017628 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017629#ifdef WLAN_FEATURE_RMC
17630 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17631#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017632
17633 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017634
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017635 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17636 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17637 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017638 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017639 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017640 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017641 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017642 }
17643
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017644 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17645 hdd_device_modetoString(pAdapter->device_mode),
17646 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017647 if (NULL == pWextState)
17648 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017649 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017650 __func__);
17651 return -EIO;
17652 }
17653
17654 pRoamProfile = &pWextState->roamProfile;
17655
17656 /* Issue disconnect only if interface type is set to IBSS */
17657 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17658 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017659 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017660 __func__);
17661 return -EINVAL;
17662 }
17663
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017664#ifdef WLAN_FEATURE_RMC
17665 /* Clearing add IE of beacon */
17666 if (ccmCfgSetStr(pHddCtx->hHal,
17667 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17668 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17669 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17670 {
17671 hddLog (VOS_TRACE_LEVEL_ERROR,
17672 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17673 return -EINVAL;
17674 }
17675 if (ccmCfgSetInt(pHddCtx->hHal,
17676 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17677 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17678 {
17679 hddLog (VOS_TRACE_LEVEL_ERROR,
17680 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17681 __func__);
17682 return -EINVAL;
17683 }
17684
17685 // Reset WNI_CFG_PROBE_RSP Flags
17686 wlan_hdd_reset_prob_rspies(pAdapter);
17687
17688 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17689 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17690 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17691 {
17692 hddLog (VOS_TRACE_LEVEL_ERROR,
17693 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17694 __func__);
17695 return -EINVAL;
17696 }
17697#endif
17698
Jeff Johnson295189b2012-06-20 16:38:30 -070017699 /* Issue Disconnect request */
17700 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017701 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17702 pAdapter->sessionId,
17703 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17704 if (!HAL_STATUS_SUCCESS(hal_status)) {
17705 hddLog(LOGE,
17706 FL("sme_RoamDisconnect failed hal_status(%d)"),
17707 hal_status);
17708 return -EAGAIN;
17709 }
17710 status = wait_for_completion_timeout(
17711 &pAdapter->disconnect_comp_var,
17712 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17713 if (!status) {
17714 hddLog(LOGE,
17715 FL("wait on disconnect_comp_var failed"));
17716 return -ETIMEDOUT;
17717 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017718
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017719 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017720 return 0;
17721}
17722
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017723static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17724 struct net_device *dev
17725 )
17726{
17727 int ret = 0;
17728
17729 vos_ssr_protect(__func__);
17730 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17731 vos_ssr_unprotect(__func__);
17732
17733 return ret;
17734}
17735
Jeff Johnson295189b2012-06-20 16:38:30 -070017736/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017737 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017738 * This function is used to set the phy parameters
17739 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17740 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017741static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017742 u32 changed)
17743{
17744 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17745 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017746 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017747
17748 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017749
17750 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017751 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17752 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017753
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017754 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017755 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017756 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017757 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017758 }
17759
Jeff Johnson295189b2012-06-20 16:38:30 -070017760 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17761 {
17762 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17763 WNI_CFG_RTS_THRESHOLD_STAMAX :
17764 wiphy->rts_threshold;
17765
17766 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017767 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017768 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017769 hddLog(VOS_TRACE_LEVEL_ERROR,
17770 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017771 __func__, rts_threshold);
17772 return -EINVAL;
17773 }
17774
17775 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17776 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017777 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017778 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017779 hddLog(VOS_TRACE_LEVEL_ERROR,
17780 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017781 __func__, rts_threshold);
17782 return -EIO;
17783 }
17784
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017785 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017786 rts_threshold);
17787 }
17788
17789 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17790 {
17791 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17792 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17793 wiphy->frag_threshold;
17794
17795 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017796 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017797 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017798 hddLog(VOS_TRACE_LEVEL_ERROR,
17799 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017800 frag_threshold);
17801 return -EINVAL;
17802 }
17803
17804 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
17805 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017806 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017807 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017808 hddLog(VOS_TRACE_LEVEL_ERROR,
17809 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017810 __func__, frag_threshold);
17811 return -EIO;
17812 }
17813
17814 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
17815 frag_threshold);
17816 }
17817
17818 if ((changed & WIPHY_PARAM_RETRY_SHORT)
17819 || (changed & WIPHY_PARAM_RETRY_LONG))
17820 {
17821 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
17822 wiphy->retry_short :
17823 wiphy->retry_long;
17824
17825 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17826 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17827 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017828 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017829 __func__, retry_value);
17830 return -EINVAL;
17831 }
17832
17833 if (changed & WIPHY_PARAM_RETRY_SHORT)
17834 {
17835 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17836 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017837 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017838 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017839 hddLog(VOS_TRACE_LEVEL_ERROR,
17840 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017841 __func__, retry_value);
17842 return -EIO;
17843 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017844 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017845 __func__, retry_value);
17846 }
17847 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17848 {
17849 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17850 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017851 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017852 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017853 hddLog(VOS_TRACE_LEVEL_ERROR,
17854 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017855 __func__, retry_value);
17856 return -EIO;
17857 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017858 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017859 __func__, retry_value);
17860 }
17861 }
17862
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017863 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017864 return 0;
17865}
17866
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017867static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17868 u32 changed)
17869{
17870 int ret;
17871
17872 vos_ssr_protect(__func__);
17873 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17874 vos_ssr_unprotect(__func__);
17875
17876 return ret;
17877}
17878
Jeff Johnson295189b2012-06-20 16:38:30 -070017879/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017880 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017881 * This function is used to set the txpower
17882 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017883static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017884#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17885 struct wireless_dev *wdev,
17886#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017887#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017888 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017889#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017890 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017891#endif
17892 int dbm)
17893{
17894 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017895 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017896 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17897 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017898 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017899
17900 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017901
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017902 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17903 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17904 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017905 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017906 if (0 != status)
17907 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017908 return status;
17909 }
17910
17911 hHal = pHddCtx->hHal;
17912
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017913 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17914 dbm, ccmCfgSetCallback,
17915 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017916 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017917 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017918 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17919 return -EIO;
17920 }
17921
17922 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17923 dbm);
17924
17925 switch(type)
17926 {
17927 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17928 /* Fall through */
17929 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17930 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17931 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017932 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17933 __func__);
17934 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017935 }
17936 break;
17937 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017938 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017939 __func__);
17940 return -EOPNOTSUPP;
17941 break;
17942 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017943 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17944 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017945 return -EIO;
17946 }
17947
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017948 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017949 return 0;
17950}
17951
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017952static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17953#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17954 struct wireless_dev *wdev,
17955#endif
17956#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17957 enum tx_power_setting type,
17958#else
17959 enum nl80211_tx_power_setting type,
17960#endif
17961 int dbm)
17962{
17963 int ret;
17964 vos_ssr_protect(__func__);
17965 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17966#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17967 wdev,
17968#endif
17969#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17970 type,
17971#else
17972 type,
17973#endif
17974 dbm);
17975 vos_ssr_unprotect(__func__);
17976
17977 return ret;
17978}
17979
Jeff Johnson295189b2012-06-20 16:38:30 -070017980/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017981 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017982 * This function is used to read the txpower
17983 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017984static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017985#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17986 struct wireless_dev *wdev,
17987#endif
17988 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070017989{
17990
17991 hdd_adapter_t *pAdapter;
17992 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017993 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017994
Jeff Johnsone7245742012-09-05 17:12:55 -070017995 ENTER();
17996
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017997 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017998 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017999 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018000 *dbm = 0;
18001 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018002 }
18003
Jeff Johnson295189b2012-06-20 16:38:30 -070018004 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
18005 if (NULL == pAdapter)
18006 {
18007 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
18008 return -ENOENT;
18009 }
18010
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018011 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18012 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
18013 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070018014 wlan_hdd_get_classAstats(pAdapter);
18015 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
18016
Jeff Johnsone7245742012-09-05 17:12:55 -070018017 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018018 return 0;
18019}
18020
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018021static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
18022#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18023 struct wireless_dev *wdev,
18024#endif
18025 int *dbm)
18026{
18027 int ret;
18028
18029 vos_ssr_protect(__func__);
18030 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
18031#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18032 wdev,
18033#endif
18034 dbm);
18035 vos_ssr_unprotect(__func__);
18036
18037 return ret;
18038}
18039
Dustin Brown8c1d4092017-07-28 18:08:01 +053018040/*
18041 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
18042 * @stats: summary stats to use as a source
18043 * @info: kernel station_info struct to use as a destination
18044 *
18045 * Return: None
18046 */
18047static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
18048 struct station_info *info)
18049{
18050 int i;
18051
18052 info->rx_packets = stats->rx_frm_cnt;
18053 info->tx_packets = 0;
18054 info->tx_retries = 0;
18055 info->tx_failed = 0;
18056
18057 for (i = 0; i < 4; ++i) {
18058 info->tx_packets += stats->tx_frm_cnt[i];
18059 info->tx_retries += stats->multiple_retry_cnt[i];
18060 info->tx_failed += stats->fail_cnt[i];
18061 }
18062
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018063#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18064 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018065 info->filled |= STATION_INFO_TX_PACKETS |
18066 STATION_INFO_TX_RETRIES |
18067 STATION_INFO_TX_FAILED |
18068 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018069#else
18070 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
18071 BIT(NL80211_STA_INFO_TX_RETRIES) |
18072 BIT(NL80211_STA_INFO_TX_FAILED) |
18073 BIT(NL80211_STA_INFO_RX_PACKETS);
18074#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053018075}
18076
18077/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018078 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
18079 * @adapter: sap adapter pointer
18080 * @staid: station id of the client
18081 * @rssi: rssi value to fill
18082 *
18083 * Return: None
18084 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053018085void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018086wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
18087{
18088 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
18089
18090 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
18091}
18092
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018093#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18094 !defined(WITH_BACKPORTS)
18095static inline void wlan_hdd_fill_station_info_signal(struct station_info
18096 *sinfo)
18097{
18098 sinfo->filled |= STATION_INFO_SIGNAL;
18099}
18100#else
18101static inline void wlan_hdd_fill_station_info_signal(struct station_info
18102 *sinfo)
18103{
18104 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
18105}
18106#endif
18107
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018108/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053018109 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
18110 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018111 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053018112 * @info: kernel station_info struct to populate
18113 *
18114 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
18115 * support "station dump" and "station get" for SAP vdevs, even though they
18116 * aren't technically stations.
18117 *
18118 * Return: errno
18119 */
18120static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018121wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
18122#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18123 const u8* mac,
18124#else
18125 u8* mac,
18126#endif
18127 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018128{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018129 v_MACADDR_t *peerMacAddr;
18130 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018131 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018132 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018133
18134 status = wlan_hdd_get_station_stats(adapter);
18135 if (!VOS_IS_STATUS_SUCCESS(status)) {
18136 hddLog(VOS_TRACE_LEVEL_ERROR,
18137 "Failed to get SAP stats; status:%d", status);
18138 return 0;
18139 }
18140
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018141 peerMacAddr = (v_MACADDR_t *)mac;
18142 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
18143 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
18144 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
18145
18146 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
18147 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018148 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018149 }
18150
Dustin Brown8c1d4092017-07-28 18:08:01 +053018151 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
18152
18153 return 0;
18154}
18155
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018156static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018157#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18158 const u8* mac,
18159#else
18160 u8* mac,
18161#endif
18162 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070018163{
18164 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
18165 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18166 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053018167 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018168
18169 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
18170 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070018171
18172 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
18173 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
18174 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
18175 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
18176 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
18177 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
18178 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018179 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018180 tANI_U16 myRate;
18181 tANI_U16 currentRate = 0;
18182 tANI_U8 maxSpeedMCS = 0;
18183 tANI_U8 maxMCSIdx = 0;
18184 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053018185 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070018186 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018187 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018188
Leo Chang6f8870f2013-03-26 18:11:36 -070018189#ifdef WLAN_FEATURE_11AC
18190 tANI_U32 vht_mcs_map;
18191 eDataRate11ACMaxMcs vhtMaxMcs;
18192#endif /* WLAN_FEATURE_11AC */
18193
Jeff Johnsone7245742012-09-05 17:12:55 -070018194 ENTER();
18195
Dustin Brown8c1d4092017-07-28 18:08:01 +053018196 status = wlan_hdd_validate_context(pHddCtx);
18197 if (0 != status)
18198 {
18199 return status;
18200 }
18201
18202 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018203 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053018204
Jeff Johnson295189b2012-06-20 16:38:30 -070018205 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
18206 (0 == ssidlen))
18207 {
18208 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
18209 " Invalid ssidlen, %d", __func__, ssidlen);
18210 /*To keep GUI happy*/
18211 return 0;
18212 }
18213
Mukul Sharma811205f2014-07-09 21:07:30 +053018214 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
18215 {
18216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18217 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053018218 /* return a cached value */
18219 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053018220 return 0;
18221 }
18222
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053018223 wlan_hdd_get_station_stats(pAdapter);
18224 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018225
Kiet Lam3b17fc82013-09-27 05:24:08 +053018226 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018227 wlan_hdd_get_snr(pAdapter, &snr);
18228 pHddStaCtx->conn_info.signal = sinfo->signal;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018229 pHddStaCtx->cache_conn_info.signal = sinfo->signal;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018230 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018231 pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018232 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053018233
c_hpothu09f19542014-05-30 21:53:31 +053018234 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053018235 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
18236 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053018237 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053018238 {
18239 rate_flags = pAdapter->maxRateFlags;
18240 }
c_hpothu44ff4e02014-05-08 00:13:57 +053018241
Jeff Johnson295189b2012-06-20 16:38:30 -070018242 //convert to the UI units of 100kbps
18243 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
18244
18245#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070018246 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 -070018247 sinfo->signal,
18248 pCfg->reportMaxLinkSpeed,
18249 myRate,
18250 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018251 (int) pCfg->linkSpeedRssiMid,
18252 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070018253 (int) rate_flags,
18254 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070018255#endif //LINKSPEED_DEBUG_ENABLED
18256
Hanumanth Reddy Pothula596b8b32018-05-01 20:17:38 +053018257#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || defined(WITH_BACKPORTS)
18258 /* assume basic BW. anything else will override this later */
18259 sinfo->txrate.bw = RATE_INFO_BW_20;
18260#endif
18261
Jeff Johnson295189b2012-06-20 16:38:30 -070018262 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
18263 {
18264 // we do not want to necessarily report the current speed
18265 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
18266 {
18267 // report the max possible speed
18268 rssidx = 0;
18269 }
18270 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
18271 {
18272 // report the max possible speed with RSSI scaling
18273 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
18274 {
18275 // report the max possible speed
18276 rssidx = 0;
18277 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018278 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070018279 {
18280 // report middle speed
18281 rssidx = 1;
18282 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018283 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
18284 {
18285 // report middle speed
18286 rssidx = 2;
18287 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018288 else
18289 {
18290 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018291 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070018292 }
18293 }
18294 else
18295 {
18296 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
18297 hddLog(VOS_TRACE_LEVEL_ERROR,
18298 "%s: Invalid value for reportMaxLinkSpeed: %u",
18299 __func__, pCfg->reportMaxLinkSpeed);
18300 rssidx = 0;
18301 }
18302
18303 maxRate = 0;
18304
18305 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018306 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
18307 OperationalRates, &ORLeng))
18308 {
18309 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18310 /*To keep GUI happy*/
18311 return 0;
18312 }
18313
Jeff Johnson295189b2012-06-20 16:38:30 -070018314 for (i = 0; i < ORLeng; i++)
18315 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018316 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018317 {
18318 /* Validate Rate Set */
18319 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
18320 {
18321 currentRate = supported_data_rate[j].supported_rate[rssidx];
18322 break;
18323 }
18324 }
18325 /* Update MAX rate */
18326 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18327 }
18328
18329 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018330 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
18331 ExtendedRates, &ERLeng))
18332 {
18333 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18334 /*To keep GUI happy*/
18335 return 0;
18336 }
18337
Jeff Johnson295189b2012-06-20 16:38:30 -070018338 for (i = 0; i < ERLeng; i++)
18339 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018340 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018341 {
18342 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
18343 {
18344 currentRate = supported_data_rate[j].supported_rate[rssidx];
18345 break;
18346 }
18347 }
18348 /* Update MAX rate */
18349 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18350 }
c_hpothu79aab322014-07-14 21:11:01 +053018351
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018352 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053018353 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018354 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053018355 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070018356 {
c_hpothu79aab322014-07-14 21:11:01 +053018357 if (rate_flags & eHAL_TX_RATE_VHT80)
18358 mode = 2;
18359 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
18360 mode = 1;
18361 else
18362 mode = 0;
18363
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018364 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
18365 MCSRates, &MCSLeng))
18366 {
18367 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18368 /*To keep GUI happy*/
18369 return 0;
18370 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018371 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070018372#ifdef WLAN_FEATURE_11AC
18373 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018374 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070018375 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018376 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018377 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070018378 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070018379 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018380 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018381 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018382 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070018383 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018384 maxMCSIdx = 7;
18385 }
18386 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
18387 {
18388 maxMCSIdx = 8;
18389 }
18390 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
18391 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018392 //VHT20 is supporting 0~8
18393 if (rate_flags & eHAL_TX_RATE_VHT20)
18394 maxMCSIdx = 8;
18395 else
18396 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070018397 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018398
c_hpothu79aab322014-07-14 21:11:01 +053018399 if (0 != rssidx)/*check for scaled */
18400 {
18401 //get middle rate MCS index if rssi=1/2
18402 for (i=0; i <= maxMCSIdx; i++)
18403 {
18404 if (sinfo->signal <= rssiMcsTbl[mode][i])
18405 {
18406 maxMCSIdx = i;
18407 break;
18408 }
18409 }
18410 }
18411
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018412 if (rate_flags & eHAL_TX_RATE_VHT80)
18413 {
18414 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
18415 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
18416 }
18417 else if (rate_flags & eHAL_TX_RATE_VHT40)
18418 {
18419 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
18420 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
18421 }
18422 else if (rate_flags & eHAL_TX_RATE_VHT20)
18423 {
18424 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
18425 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
18426 }
18427
Leo Chang6f8870f2013-03-26 18:11:36 -070018428 maxSpeedMCS = 1;
18429 if (currentRate > maxRate)
18430 {
18431 maxRate = currentRate;
18432 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018433
Leo Chang6f8870f2013-03-26 18:11:36 -070018434 }
18435 else
18436#endif /* WLAN_FEATURE_11AC */
18437 {
18438 if (rate_flags & eHAL_TX_RATE_HT40)
18439 {
18440 rateFlag |= 1;
18441 }
18442 if (rate_flags & eHAL_TX_RATE_SGI)
18443 {
18444 rateFlag |= 2;
18445 }
18446
Girish Gowli01abcee2014-07-31 20:18:55 +053018447 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053018448 if (rssidx == 1 || rssidx == 2)
18449 {
18450 //get middle rate MCS index if rssi=1/2
18451 for (i=0; i <= 7; i++)
18452 {
18453 if (sinfo->signal <= rssiMcsTbl[mode][i])
18454 {
18455 temp = i+1;
18456 break;
18457 }
18458 }
18459 }
c_hpothu79aab322014-07-14 21:11:01 +053018460
18461 for (i = 0; i < MCSLeng; i++)
18462 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018463 for (j = 0; j < temp; j++)
18464 {
18465 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
18466 {
18467 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018468 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018469 break;
18470 }
18471 }
18472 if ((j < temp) && (currentRate > maxRate))
18473 {
18474 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070018475 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018476 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018477 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018478 }
18479 }
18480
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018481 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
18482 {
18483 maxRate = myRate;
18484 maxSpeedMCS = 1;
18485 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18486 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018487 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053018488 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070018489 {
18490 maxRate = myRate;
18491 if (rate_flags & eHAL_TX_RATE_LEGACY)
18492 {
18493 maxSpeedMCS = 0;
18494 }
18495 else
18496 {
18497 maxSpeedMCS = 1;
18498 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18499 }
18500 }
18501
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018502 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070018503 {
18504 sinfo->txrate.legacy = maxRate;
18505#ifdef LINKSPEED_DEBUG_ENABLED
18506 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
18507#endif //LINKSPEED_DEBUG_ENABLED
18508 }
18509 else
18510 {
18511 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070018512#ifdef WLAN_FEATURE_11AC
18513 sinfo->txrate.nss = 1;
18514 if (rate_flags & eHAL_TX_RATE_VHT80)
18515 {
18516 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018517#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18518 defined(WITH_BACKPORTS)
18519 sinfo->txrate.bw = RATE_INFO_BW_80;
18520#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018521 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018522#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018523 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018524 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070018525 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018526 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018527#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18528 defined(WITH_BACKPORTS)
18529 sinfo->txrate.bw = RATE_INFO_BW_40;
18530#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018531 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018532#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018533 }
18534 else if (rate_flags & eHAL_TX_RATE_VHT20)
18535 {
18536 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18537 }
18538#endif /* WLAN_FEATURE_11AC */
18539 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
18540 {
18541 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18542 if (rate_flags & eHAL_TX_RATE_HT40)
18543 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018544#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18545 defined(WITH_BACKPORTS)
18546 sinfo->txrate.bw = RATE_INFO_BW_40;
18547#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018548 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018549#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018550 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018551 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018552 if (rate_flags & eHAL_TX_RATE_SGI)
18553 {
18554 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18555 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018556
Jeff Johnson295189b2012-06-20 16:38:30 -070018557#ifdef LINKSPEED_DEBUG_ENABLED
18558 pr_info("Reporting MCS rate %d flags %x\n",
18559 sinfo->txrate.mcs,
18560 sinfo->txrate.flags );
18561#endif //LINKSPEED_DEBUG_ENABLED
18562 }
18563 }
18564 else
18565 {
18566 // report current rate instead of max rate
18567
18568 if (rate_flags & eHAL_TX_RATE_LEGACY)
18569 {
18570 //provide to the UI in units of 100kbps
18571 sinfo->txrate.legacy = myRate;
18572#ifdef LINKSPEED_DEBUG_ENABLED
18573 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
18574#endif //LINKSPEED_DEBUG_ENABLED
18575 }
18576 else
18577 {
18578 //must be MCS
18579 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018580#ifdef WLAN_FEATURE_11AC
18581 sinfo->txrate.nss = 1;
18582 if (rate_flags & eHAL_TX_RATE_VHT80)
18583 {
18584 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18585 }
18586 else
18587#endif /* WLAN_FEATURE_11AC */
18588 {
18589 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18590 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018591 if (rate_flags & eHAL_TX_RATE_SGI)
18592 {
18593 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18594 }
18595 if (rate_flags & eHAL_TX_RATE_HT40)
18596 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018597#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18598 defined(WITH_BACKPORTS)
18599 sinfo->txrate.bw = RATE_INFO_BW_40;
18600#else
Jeff Johnson295189b2012-06-20 16:38:30 -070018601 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018602#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018603 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018604#ifdef WLAN_FEATURE_11AC
18605 else if (rate_flags & eHAL_TX_RATE_VHT80)
18606 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018607#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18608 defined(WITH_BACKPORTS)
18609 sinfo->txrate.bw = RATE_INFO_BW_80;
18610#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018611 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018612#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018613 }
18614#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018615#ifdef LINKSPEED_DEBUG_ENABLED
18616 pr_info("Reporting actual MCS rate %d flags %x\n",
18617 sinfo->txrate.mcs,
18618 sinfo->txrate.flags );
18619#endif //LINKSPEED_DEBUG_ENABLED
18620 }
18621 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018622
18623#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18624 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018625 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018626#else
18627 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18628#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018629
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018630 sinfo->tx_packets =
18631 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18632 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18633 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18634 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18635
18636 sinfo->tx_retries =
18637 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18638 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18639 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18640 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18641
18642 sinfo->tx_failed =
18643 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18644 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18645 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18646 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18647
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018648#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18649 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018650 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018651 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018652 STATION_INFO_TX_PACKETS |
18653 STATION_INFO_TX_RETRIES |
18654 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018655#else
18656 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18657 BIT(NL80211_STA_INFO_TX_PACKETS) |
18658 BIT(NL80211_STA_INFO_TX_RETRIES) |
18659 BIT(NL80211_STA_INFO_TX_FAILED);
18660#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018661
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018662 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018663
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018664 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18665 &sinfo->txrate, sizeof(sinfo->txrate));
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018666 vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate,
18667 &sinfo->txrate, sizeof(sinfo->txrate));
18668
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018669 if (rate_flags & eHAL_TX_RATE_LEGACY)
18670 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18671 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18672 sinfo->rx_packets);
18673 else
18674 hddLog(LOG1,
18675 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18676 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18677 sinfo->tx_packets, sinfo->rx_packets);
18678
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018679 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18680 TRACE_CODE_HDD_CFG80211_GET_STA,
18681 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018682 EXIT();
18683 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018684}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018685#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18686static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18687 const u8* mac, struct station_info *sinfo)
18688#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018689static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18690 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018691#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018692{
18693 int ret;
18694
18695 vos_ssr_protect(__func__);
18696 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18697 vos_ssr_unprotect(__func__);
18698
18699 return ret;
18700}
18701
18702static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018703 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018704{
18705 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018706 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018707 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018708 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018709
Jeff Johnsone7245742012-09-05 17:12:55 -070018710 ENTER();
18711
Jeff Johnson295189b2012-06-20 16:38:30 -070018712 if (NULL == pAdapter)
18713 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018714 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018715 return -ENODEV;
18716 }
18717
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018718 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18719 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18720 pAdapter->sessionId, timeout));
18721
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018722 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018723 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018724 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018725 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018726 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018727 }
18728
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018729 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
18730 (TRUE == pHddCtx->hdd_wlan_suspended) &&
18731 (pHddCtx->cfg_ini->fhostArpOffload) &&
18732 (eConnectionState_Associated ==
18733 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
18734 {
Amar Singhald53568e2013-09-26 11:03:45 -070018735
18736 hddLog(VOS_TRACE_LEVEL_INFO,
18737 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053018738 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018739 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18740 {
18741 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018742 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018743 __func__, vos_status);
18744 }
18745 }
18746
Jeff Johnson295189b2012-06-20 16:38:30 -070018747 /**The get power cmd from the supplicant gets updated by the nl only
18748 *on successful execution of the function call
18749 *we are oppositely mapped w.r.t mode in the driver
18750 **/
18751 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
18752
18753 if (VOS_STATUS_E_FAILURE == vos_status)
18754 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18756 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018757 return -EINVAL;
18758 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018759 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018760 return 0;
18761}
18762
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018763static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
18764 struct net_device *dev, bool mode, int timeout)
18765{
18766 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018767
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018768 vos_ssr_protect(__func__);
18769 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
18770 vos_ssr_unprotect(__func__);
18771
18772 return ret;
18773}
Sushant Kaushik084f6592015-09-10 13:11:56 +053018774
Jeff Johnson295189b2012-06-20 16:38:30 -070018775#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018776static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
18777 struct net_device *netdev,
18778 u8 key_index)
18779{
18780 ENTER();
18781 return 0;
18782}
18783
Jeff Johnson295189b2012-06-20 16:38:30 -070018784static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018785 struct net_device *netdev,
18786 u8 key_index)
18787{
18788 int ret;
18789 vos_ssr_protect(__func__);
18790 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
18791 vos_ssr_unprotect(__func__);
18792 return ret;
18793}
18794#endif //LINUX_VERSION_CODE
18795
18796#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18797static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18798 struct net_device *dev,
18799 struct ieee80211_txq_params *params)
18800{
18801 ENTER();
18802 return 0;
18803}
18804#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18805static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18806 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018807{
Jeff Johnsone7245742012-09-05 17:12:55 -070018808 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070018809 return 0;
18810}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018811#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070018812
18813#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18814static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018815 struct net_device *dev,
18816 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018817{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018818 int ret;
18819
18820 vos_ssr_protect(__func__);
18821 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
18822 vos_ssr_unprotect(__func__);
18823 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018824}
18825#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18826static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
18827 struct ieee80211_txq_params *params)
18828{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018829 int ret;
18830
18831 vos_ssr_protect(__func__);
18832 ret = __wlan_hdd_set_txq_params(wiphy, params);
18833 vos_ssr_unprotect(__func__);
18834 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018835}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018836#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018837
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018838static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018839 struct net_device *dev,
18840 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070018841{
18842 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018843 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018844 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018845 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018846 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018847 v_CONTEXT_t pVosContext = NULL;
18848 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018849
Jeff Johnsone7245742012-09-05 17:12:55 -070018850 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018851
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018852 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070018853 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018854 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018855 return -EINVAL;
18856 }
18857
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018858 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18859 TRACE_CODE_HDD_CFG80211_DEL_STA,
18860 pAdapter->sessionId, pAdapter->device_mode));
18861
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018862 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18863 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018864 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018865 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018866 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018867 }
18868
Jeff Johnson295189b2012-06-20 16:38:30 -070018869 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018870 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018871 )
18872 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018873 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
18874 pSapCtx = VOS_GET_SAP_CB(pVosContext);
18875 if(pSapCtx == NULL){
18876 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18877 FL("psapCtx is NULL"));
18878 return -ENOENT;
18879 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053018880 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
18881 {
18882 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
18883 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
18884 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
18885 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018886 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070018887 {
18888 v_U16_t i;
18889 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
18890 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018891 if ((pSapCtx->aStaInfo[i].isUsed) &&
18892 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070018893 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018894 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018895 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018896 ETHER_ADDR_LEN);
18897
Jeff Johnson295189b2012-06-20 16:38:30 -070018898 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018899 "%s: Delete STA with MAC::"
18900 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018901 __func__,
18902 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18903 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018904 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018905 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018906 }
18907 }
18908 }
18909 else
18910 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018911
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018912 vos_status = hdd_softap_GetStaId(pAdapter,
18913 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018914 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18915 {
18916 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018917 "%s: Skip this DEL STA as this is not used::"
18918 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018919 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018920 return -ENOENT;
18921 }
18922
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018923 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018924 {
18925 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018926 "%s: Skip this DEL STA as deauth is in progress::"
18927 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018928 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018929 return -ENOENT;
18930 }
18931
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018932 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018933
Jeff Johnson295189b2012-06-20 16:38:30 -070018934 hddLog(VOS_TRACE_LEVEL_INFO,
18935 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018936 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018937 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018938 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018939
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018940 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018941 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18942 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018943 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018944 hddLog(VOS_TRACE_LEVEL_INFO,
18945 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018946 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018947 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018948 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018949 return -ENOENT;
18950 }
18951
Jeff Johnson295189b2012-06-20 16:38:30 -070018952 }
18953 }
18954
18955 EXIT();
18956
18957 return 0;
18958}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018959
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018960#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018961int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018962 struct net_device *dev,
18963 struct station_del_parameters *param)
18964#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018965#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018966int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018967 struct net_device *dev, const u8 *mac)
18968#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018969int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018970 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018971#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018972#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018973{
18974 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018975 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018976
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018977 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018978
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018979#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018980 if (NULL == param) {
18981 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018982 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018983 return -EINVAL;
18984 }
18985
18986 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
18987 param->subtype, &delStaParams);
18988
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018989#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053018990 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018991 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018992#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018993 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
18994
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018995 vos_ssr_unprotect(__func__);
18996
18997 return ret;
18998}
18999
19000static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019001 struct net_device *dev,
19002#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19003 const u8 *mac,
19004#else
19005 u8 *mac,
19006#endif
19007 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019008{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019009 hdd_adapter_t *pAdapter;
19010 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019011 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019012#ifdef FEATURE_WLAN_TDLS
19013 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019014
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019015 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019016
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019017 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19018 if (NULL == pAdapter)
19019 {
19020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19021 "%s: Adapter is NULL",__func__);
19022 return -EINVAL;
19023 }
19024 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19025 status = wlan_hdd_validate_context(pHddCtx);
19026 if (0 != status)
19027 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019028 return status;
19029 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019030
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019031 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19032 TRACE_CODE_HDD_CFG80211_ADD_STA,
19033 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019034 mask = params->sta_flags_mask;
19035
19036 set = params->sta_flags_set;
19037
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019038 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019039 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
19040 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019041
19042 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
19043 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080019044 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019045 }
19046 }
19047#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019048 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019049 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070019050}
19051
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019052#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19053static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19054 struct net_device *dev, const u8 *mac,
19055 struct station_parameters *params)
19056#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019057static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19058 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019059#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019060{
19061 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019062
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019063 vos_ssr_protect(__func__);
19064 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
19065 vos_ssr_unprotect(__func__);
19066
19067 return ret;
19068}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019069#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070019070
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019071static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070019072 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019073{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019074 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19075 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019076 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019077 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019078 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019079 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070019080
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019081 ENTER();
19082
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019083 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019084 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019085 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019086 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019087 return -EINVAL;
19088 }
19089
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019090 if (!pmksa) {
19091 hddLog(LOGE, FL("pmksa is NULL"));
19092 return -EINVAL;
19093 }
19094
19095 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070019096 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019097 pmksa->bssid, pmksa->pmkid);
19098 return -EINVAL;
19099 }
19100
19101 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
19102 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19103
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019104 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19105 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019106 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019107 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019108 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019109 }
19110
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019111 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019112 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19113
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019114 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
19115 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019116
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019117 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019118 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019119 &pmk_id, 1, FALSE);
19120
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019121 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19122 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
19123 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019124
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019125 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019126 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019127}
19128
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019129static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
19130 struct cfg80211_pmksa *pmksa)
19131{
19132 int ret;
19133
19134 vos_ssr_protect(__func__);
19135 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
19136 vos_ssr_unprotect(__func__);
19137
19138 return ret;
19139}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019140
Wilson Yang6507c4e2013-10-01 20:11:19 -070019141
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019142static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070019143 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019144{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019145 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19146 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019147 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019148 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019149
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019150 ENTER();
19151
Wilson Yang6507c4e2013-10-01 20:11:19 -070019152 /* Validate pAdapter */
19153 if (NULL == pAdapter)
19154 {
19155 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
19156 return -EINVAL;
19157 }
19158
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019159 if (!pmksa) {
19160 hddLog(LOGE, FL("pmksa is NULL"));
19161 return -EINVAL;
19162 }
19163
19164 if (!pmksa->bssid) {
19165 hddLog(LOGE, FL("pmksa->bssid is NULL"));
19166 return -EINVAL;
19167 }
19168
Kiet Lam98c46a12014-10-31 15:34:57 -070019169 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
19170 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19171
Wilson Yang6507c4e2013-10-01 20:11:19 -070019172 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19173 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019174 if (0 != status)
19175 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019176 return status;
19177 }
19178
19179 /*Retrieve halHandle*/
19180 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19181
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019182 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19183 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
19184 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019185 /* Delete the PMKID CSR cache */
19186 if (eHAL_STATUS_SUCCESS !=
19187 sme_RoamDelPMKIDfromCache(halHandle,
19188 pAdapter->sessionId, pmksa->bssid, FALSE)) {
19189 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
19190 MAC_ADDR_ARRAY(pmksa->bssid));
19191 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019192 }
19193
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019194 EXIT();
19195 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019196}
19197
Wilson Yang6507c4e2013-10-01 20:11:19 -070019198
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019199static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
19200 struct cfg80211_pmksa *pmksa)
19201{
19202 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019203
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019204 vos_ssr_protect(__func__);
19205 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
19206 vos_ssr_unprotect(__func__);
19207
19208 return ret;
19209
19210}
19211
19212static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019213{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019214 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19215 tHalHandle halHandle;
19216 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019217 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019218
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019219 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070019220
19221 /* Validate pAdapter */
19222 if (NULL == pAdapter)
19223 {
19224 hddLog(VOS_TRACE_LEVEL_ERROR,
19225 "%s: Invalid Adapter" ,__func__);
19226 return -EINVAL;
19227 }
19228
19229 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19230 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019231 if (0 != status)
19232 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019233 return status;
19234 }
19235
19236 /*Retrieve halHandle*/
19237 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19238
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019239 /* Flush the PMKID cache in CSR */
19240 if (eHAL_STATUS_SUCCESS !=
19241 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
19242 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
19243 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019244 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019245 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080019246 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019247}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019248
19249static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
19250{
19251 int ret;
19252
19253 vos_ssr_protect(__func__);
19254 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
19255 vos_ssr_unprotect(__func__);
19256
19257 return ret;
19258}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019259#endif
19260
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019261#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019262static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19263 struct net_device *dev,
19264 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019265{
19266 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19267 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019268 hdd_context_t *pHddCtx;
19269 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019270
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019271 ENTER();
19272
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019273 if (NULL == pAdapter)
19274 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019275 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019276 return -ENODEV;
19277 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019278 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19279 ret = wlan_hdd_validate_context(pHddCtx);
19280 if (0 != ret)
19281 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019282 return ret;
19283 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019284 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019285 if (NULL == pHddStaCtx)
19286 {
19287 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
19288 return -EINVAL;
19289 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019290
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019291 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19292 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
19293 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019294 // Added for debug on reception of Re-assoc Req.
19295 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
19296 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019297 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019298 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080019299 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019300 }
19301
19302#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080019303 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019304 ftie->ie_len);
19305#endif
19306
19307 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053019308 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
19309 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019310 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019311
19312 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019313 return 0;
19314}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019315
19316static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19317 struct net_device *dev,
19318 struct cfg80211_update_ft_ies_params *ftie)
19319{
19320 int ret;
19321
19322 vos_ssr_protect(__func__);
19323 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
19324 vos_ssr_unprotect(__func__);
19325
19326 return ret;
19327}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019328#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019329
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019330#ifdef FEATURE_WLAN_SCAN_PNO
19331
19332void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
19333 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
19334{
19335 int ret;
19336 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
19337 hdd_context_t *pHddCtx;
19338
Nirav Shah80830bf2013-12-31 16:35:12 +053019339 ENTER();
19340
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019341 if (NULL == pAdapter)
19342 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019343 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019344 "%s: HDD adapter is Null", __func__);
19345 return ;
19346 }
19347
19348 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19349 if (NULL == pHddCtx)
19350 {
19351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19352 "%s: HDD context is Null!!!", __func__);
19353 return ;
19354 }
19355
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019356 spin_lock(&pHddCtx->schedScan_lock);
19357 if (TRUE == pHddCtx->isWiphySuspended)
19358 {
19359 pHddCtx->isSchedScanUpdatePending = TRUE;
19360 spin_unlock(&pHddCtx->schedScan_lock);
19361 hddLog(VOS_TRACE_LEVEL_INFO,
19362 "%s: Update cfg80211 scan database after it resume", __func__);
19363 return ;
19364 }
19365 spin_unlock(&pHddCtx->schedScan_lock);
19366
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019367 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
19368
19369 if (0 > ret)
19370 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053019371 else
19372 {
19373 /* Acquire wakelock to handle the case where APP's tries to suspend
19374 * immediatly after the driver gets connect request(i.e after pno)
19375 * from supplicant, this result in app's is suspending and not able
19376 * to process the connect request to AP */
19377 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
19378 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019379 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19381 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019382}
19383
19384/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019385 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019386 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019387 */
19388static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
19389{
19390 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
19391 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019392 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019393 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19394 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053019395
19396 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
19397 {
19398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19399 "%s: PNO is allowed only in STA interface", __func__);
19400 return eHAL_STATUS_FAILURE;
19401 }
19402
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019403 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
19404
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019405 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053019406 * active sessions. PNO is allowed only in case when sap session
19407 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019408 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019409 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
19410 {
19411 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019412 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019413
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019414 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
19415 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
19416 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
19417 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053019418 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
19419 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053019420 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019421 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019422 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019423 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019424 }
19425 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19426 pAdapterNode = pNext;
19427 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019428 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019429}
19430
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019431void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
19432{
19433 hdd_adapter_t *pAdapter = callbackContext;
19434 hdd_context_t *pHddCtx;
19435
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019436 ENTER();
19437
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019438 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
19439 {
19440 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19441 FL("Invalid adapter or adapter has invalid magic"));
19442 return;
19443 }
19444
19445 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19446 if (0 != wlan_hdd_validate_context(pHddCtx))
19447 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019448 return;
19449 }
19450
c_hpothub53c45d2014-08-18 16:53:14 +053019451 if (VOS_STATUS_SUCCESS != status)
19452 {
19453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019454 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053019455 pHddCtx->isPnoEnable = FALSE;
19456 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019457
19458 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
19459 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019460 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019461}
19462
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019463#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
19464 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
19465/**
19466 * hdd_config_sched_scan_plan() - configures the sched scan plans
19467 * from the framework.
19468 * @pno_req: pointer to PNO scan request
19469 * @request: pointer to scan request from framework
19470 *
19471 * Return: None
19472 */
19473static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
19474 struct cfg80211_sched_scan_request *request,
19475 hdd_context_t *hdd_ctx)
19476{
19477 v_U32_t i = 0;
19478
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019479 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019480 for (i = 0; i < request->n_scan_plans; i++)
19481 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019482 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
19483 request->scan_plans[i].iterations;
19484 pno_req->scanTimers.aTimerValues[i].uTimerValue =
19485 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019486 }
19487}
19488#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019489static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019490 struct cfg80211_sched_scan_request *request,
19491 hdd_context_t *hdd_ctx)
19492{
19493 v_U32_t i, temp_int;
19494 /* Driver gets only one time interval which is hardcoded in
19495 * supplicant for 10000ms. Taking power consumption into account 6
19496 * timers will be used, Timervalue is increased exponentially
19497 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
19498 * timer is configurable through INI param gPNOScanTimerRepeatValue.
19499 * If it is set to 0 only one timer will be used and PNO scan cycle
19500 * will be repeated after each interval specified by supplicant
19501 * till PNO is disabled.
19502 */
19503 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019504 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019505 HDD_PNO_SCAN_TIMERS_SET_ONE;
19506 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019507 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019508 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
19509
19510 temp_int = (request->interval)/1000;
19511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19512 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
19513 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019514 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019515 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019516 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019517 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019518 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019519 temp_int *= 2;
19520 }
19521 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019522 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019523}
19524#endif
19525
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019526/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019527 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
19528 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019529 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019530static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019531 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19532{
19533 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019534 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019535 hdd_context_t *pHddCtx;
19536 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019537 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053019538 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
19539 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019540 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
19541 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019542 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019543 hdd_config_t *pConfig = NULL;
19544 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019545
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019546 ENTER();
19547
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019548 if (NULL == pAdapter)
19549 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019551 "%s: HDD adapter is Null", __func__);
19552 return -ENODEV;
19553 }
19554
19555 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019556 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019557
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019558 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019559 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019560 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019561 }
19562
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019563 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019564 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19565 if (NULL == hHal)
19566 {
19567 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19568 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019569 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019570 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019571 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19572 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
19573 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019574 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053019575 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019576 {
19577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19578 "%s: aborting the existing scan is unsuccessfull", __func__);
19579 return -EBUSY;
19580 }
19581
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019582 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019583 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019585 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019586 return -EBUSY;
19587 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019588
c_hpothu37f21312014-04-09 21:49:54 +053019589 if (TRUE == pHddCtx->isPnoEnable)
19590 {
19591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19592 FL("already PNO is enabled"));
19593 return -EBUSY;
19594 }
c_hpothu225aa7c2014-10-22 17:45:13 +053019595
19596 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
19597 {
19598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19599 "%s: abort ROC failed ", __func__);
19600 return -EBUSY;
19601 }
19602
c_hpothu37f21312014-04-09 21:49:54 +053019603 pHddCtx->isPnoEnable = TRUE;
19604
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019605 pnoRequest.enable = 1; /*Enable PNO */
19606 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019607
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019608 if (( !pnoRequest.ucNetworksCount ) ||
19609 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019610 {
19611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019612 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019613 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019614 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019615 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019616 goto error;
19617 }
19618
19619 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
19620 {
19621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019622 "%s: Incorrect number of channels %d",
19623 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019624 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019625 goto error;
19626 }
19627
19628 /* Framework provides one set of channels(all)
19629 * common for all saved profile */
19630 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
19631 channels_allowed, &num_channels_allowed))
19632 {
19633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19634 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019635 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019636 goto error;
19637 }
19638 /* Checking each channel against allowed channel list */
19639 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053019640 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019641 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019642 char chList [(request->n_channels*5)+1];
19643 int len;
19644 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019645 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019646 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019647 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019648 if (request->channels[i]->hw_value == channels_allowed[indx])
19649 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019650 if ((!pConfig->enableDFSPnoChnlScan) &&
19651 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
19652 {
19653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19654 "%s : Dropping DFS channel : %d",
19655 __func__,channels_allowed[indx]);
19656 num_ignore_dfs_ch++;
19657 break;
19658 }
19659
Nirav Shah80830bf2013-12-31 16:35:12 +053019660 valid_ch[num_ch++] = request->channels[i]->hw_value;
19661 len += snprintf(chList+len, 5, "%d ",
19662 request->channels[i]->hw_value);
19663 break ;
19664 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019665 }
19666 }
Nirav Shah80830bf2013-12-31 16:35:12 +053019667 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019668
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019669 /*If all channels are DFS and dropped, then ignore the PNO request*/
19670 if (num_ignore_dfs_ch == request->n_channels)
19671 {
19672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19673 "%s : All requested channels are DFS channels", __func__);
19674 ret = -EINVAL;
19675 goto error;
19676 }
19677 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019678
19679 pnoRequest.aNetworks =
19680 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19681 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019682 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019683 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19684 FL("failed to allocate memory aNetworks %u"),
19685 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19686 goto error;
19687 }
19688 vos_mem_zero(pnoRequest.aNetworks,
19689 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19690
19691 /* Filling per profile params */
19692 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
19693 {
19694 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019695 request->match_sets[i].ssid.ssid_len;
19696
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019697 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
19698 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019699 {
19700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019701 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019702 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019703 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019704 goto error;
19705 }
19706
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019707 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019708 request->match_sets[i].ssid.ssid,
19709 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019710 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19711 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019712 i, pnoRequest.aNetworks[i].ssId.ssId);
19713 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
19714 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
19715 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019716
19717 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019718 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
19719 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019720
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019721 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019722 }
19723
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019724 for (i = 0; i < request->n_ssids; i++)
19725 {
19726 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019727 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019728 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019729 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019730 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019731 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019732 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019733 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019734 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019735 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019736 break;
19737 }
19738 j++;
19739 }
19740 }
19741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19742 "Number of hidden networks being Configured = %d",
19743 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080019745 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019746
19747 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19748 if (pnoRequest.p24GProbeTemplate == NULL)
19749 {
19750 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19751 FL("failed to allocate memory p24GProbeTemplate %u"),
19752 SIR_PNO_MAX_PB_REQ_SIZE);
19753 goto error;
19754 }
19755
19756 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19757 if (pnoRequest.p5GProbeTemplate == NULL)
19758 {
19759 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19760 FL("failed to allocate memory p5GProbeTemplate %u"),
19761 SIR_PNO_MAX_PB_REQ_SIZE);
19762 goto error;
19763 }
19764
19765 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19766 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19767
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053019768 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
19769 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019770 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019771 pnoRequest.us24GProbeTemplateLen = request->ie_len;
19772 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
19773 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019774
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019775 pnoRequest.us5GProbeTemplateLen = request->ie_len;
19776 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
19777 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019778 }
19779
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019780 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053019781
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019782 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019783
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019784 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019785 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19786 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019787 pAdapter->pno_req_status = 0;
19788
Nirav Shah80830bf2013-12-31 16:35:12 +053019789 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19790 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019791 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
19792 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053019793
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019794 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019795 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019796 hdd_cfg80211_sched_scan_done_callback, pAdapter);
19797 if (eHAL_STATUS_SUCCESS != status)
19798 {
19799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019800 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019801 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019802 goto error;
19803 }
19804
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019805 ret = wait_for_completion_timeout(
19806 &pAdapter->pno_comp_var,
19807 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19808 if (0 >= ret)
19809 {
19810 // Did not receive the response for PNO enable in time.
19811 // Assuming the PNO enable was success.
19812 // Returning error from here, because we timeout, results
19813 // in side effect of Wifi (Wifi Setting) not to work.
19814 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19815 FL("Timed out waiting for PNO to be Enabled"));
19816 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019817 }
19818
19819 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053019820 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019821
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019822error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019823 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19824 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053019825 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019826 if (pnoRequest.aNetworks)
19827 vos_mem_free(pnoRequest.aNetworks);
19828 if (pnoRequest.p24GProbeTemplate)
19829 vos_mem_free(pnoRequest.p24GProbeTemplate);
19830 if (pnoRequest.p5GProbeTemplate)
19831 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019832
19833 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019834 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019835}
19836
19837/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019838 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
19839 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019840 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019841static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
19842 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19843{
19844 int ret;
19845
19846 vos_ssr_protect(__func__);
19847 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
19848 vos_ssr_unprotect(__func__);
19849
19850 return ret;
19851}
19852
19853/*
19854 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
19855 * Function to disable PNO
19856 */
19857static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019858 struct net_device *dev)
19859{
19860 eHalStatus status = eHAL_STATUS_FAILURE;
19861 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19862 hdd_context_t *pHddCtx;
19863 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019864 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019865 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019866
19867 ENTER();
19868
19869 if (NULL == pAdapter)
19870 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019871 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019872 "%s: HDD adapter is Null", __func__);
19873 return -ENODEV;
19874 }
19875
19876 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019877
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019878 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019879 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019881 "%s: HDD context is Null", __func__);
19882 return -ENODEV;
19883 }
19884
19885 /* The return 0 is intentional when isLogpInProgress and
19886 * isLoadUnloadInProgress. We did observe a crash due to a return of
19887 * failure in sched_scan_stop , especially for a case where the unload
19888 * of the happens at the same time. The function __cfg80211_stop_sched_scan
19889 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
19890 * success. If it returns a failure , then its next invocation due to the
19891 * clean up of the second interface will have the dev pointer corresponding
19892 * to the first one leading to a crash.
19893 */
19894 if (pHddCtx->isLogpInProgress)
19895 {
19896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19897 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019898 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019899 return ret;
19900 }
19901
Mihir Shete18156292014-03-11 15:38:30 +053019902 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019903 {
19904 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19905 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19906 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019907 }
19908
19909 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19910 if (NULL == hHal)
19911 {
19912 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19913 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019914 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019915 }
19916
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019917 pnoRequest.enable = 0; /* Disable PNO */
19918 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019919
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019920 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19921 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19922 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019923
19924 INIT_COMPLETION(pAdapter->pno_comp_var);
19925 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19926 pnoRequest.callbackContext = pAdapter;
19927 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019928 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019929 pAdapter->sessionId,
19930 NULL, pAdapter);
19931 if (eHAL_STATUS_SUCCESS != status)
19932 {
19933 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19934 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019935 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019936 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019937 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019938 ret = wait_for_completion_timeout(
19939 &pAdapter->pno_comp_var,
19940 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19941 if (0 >= ret)
19942 {
19943 // Did not receive the response for PNO disable in time.
19944 // Assuming the PNO disable was success.
19945 // Returning error from here, because we timeout, results
19946 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019948 FL("Timed out waiting for PNO to be disabled"));
19949 ret = 0;
19950 }
19951
19952 ret = pAdapter->pno_req_status;
19953 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019954
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019955error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019957 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019958
19959 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019960 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019961}
19962
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019963/*
19964 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19965 * NL interface to disable PNO
19966 */
19967static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19968 struct net_device *dev)
19969{
19970 int ret;
19971
19972 vos_ssr_protect(__func__);
19973 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19974 vos_ssr_unprotect(__func__);
19975
19976 return ret;
19977}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019978#endif /*FEATURE_WLAN_SCAN_PNO*/
19979
19980
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019981#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019982#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019983static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19984 struct net_device *dev,
19985 u8 *peer, u8 action_code,
19986 u8 dialog_token,
19987 u16 status_code, u32 peer_capability,
19988 const u8 *buf, size_t len)
19989#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019990#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
19991 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019992static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19993 struct net_device *dev,
19994 const u8 *peer, u8 action_code,
19995 u8 dialog_token, u16 status_code,
19996 u32 peer_capability, bool initiator,
19997 const u8 *buf, size_t len)
19998#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19999static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20000 struct net_device *dev,
20001 const u8 *peer, u8 action_code,
20002 u8 dialog_token, u16 status_code,
20003 u32 peer_capability, const u8 *buf,
20004 size_t len)
20005#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20006static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20007 struct net_device *dev,
20008 u8 *peer, u8 action_code,
20009 u8 dialog_token,
20010 u16 status_code, u32 peer_capability,
20011 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020012#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020013static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20014 struct net_device *dev,
20015 u8 *peer, u8 action_code,
20016 u8 dialog_token,
20017 u16 status_code, const u8 *buf,
20018 size_t len)
20019#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020020#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020021{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020022 hdd_adapter_t *pAdapter;
20023 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020024 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070020025 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080020026 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070020027 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020028 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020029 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020030#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020031 u32 peer_capability = 0;
20032#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020033 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020034 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020035 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020036
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020037 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20038 if (NULL == pAdapter)
20039 {
20040 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20041 "%s: Adapter is NULL",__func__);
20042 return -EINVAL;
20043 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020044 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20045 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
20046 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020047
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020048 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020049 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020050 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020052 "Invalid arguments");
20053 return -EINVAL;
20054 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020055
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020056 if (pHddCtx->isLogpInProgress)
20057 {
20058 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20059 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053020060 wlan_hdd_tdls_set_link_status(pAdapter,
20061 peer,
20062 eTDLS_LINK_IDLE,
20063 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020064 return -EBUSY;
20065 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020066
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020067 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
20068 {
20069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20070 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
20071 return -EAGAIN;
20072 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020073
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020074 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
20075 if (!pHddTdlsCtx) {
20076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20077 "%s: pHddTdlsCtx not valid.", __func__);
Hanumanth Reddy Pothula36dfa522018-03-12 16:42:08 +053020078 return -EINVAL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020079 }
20080
Hoonki Lee27511902013-03-14 18:19:06 -070020081 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020082 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020083 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020084 "%s: TDLS mode is disabled OR not enabled in FW."
20085 MAC_ADDRESS_STR " action %d declined.",
20086 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020087 return -ENOTSUPP;
20088 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020089
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020090 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20091
20092 if( NULL == pHddStaCtx )
20093 {
20094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20095 "%s: HDD station context NULL ",__func__);
20096 return -EINVAL;
20097 }
20098
20099 /* STA should be connected and authenticated
20100 * before sending any TDLS frames
20101 */
20102 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
20103 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
20104 {
20105 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20106 "STA is not connected or unauthenticated. "
20107 "connState %u, uIsAuthenticated %u",
20108 pHddStaCtx->conn_info.connState,
20109 pHddStaCtx->conn_info.uIsAuthenticated);
20110 return -EAGAIN;
20111 }
20112
Hoonki Lee27511902013-03-14 18:19:06 -070020113 /* other than teardown frame, other mgmt frames are not sent if disabled */
20114 if (SIR_MAC_TDLS_TEARDOWN != action_code)
20115 {
20116 /* if tdls_mode is disabled to respond to peer's request */
20117 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
20118 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020120 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020121 " TDLS mode is disabled. action %d declined.",
20122 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070020123
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020124 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070020125 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053020126
20127 if (vos_max_concurrent_connections_reached())
20128 {
20129 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
20130 return -EINVAL;
20131 }
Hoonki Lee27511902013-03-14 18:19:06 -070020132 }
20133
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020134 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
20135 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053020136 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020137 {
20138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020139 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020140 " TDLS setup is ongoing. action %d declined.",
20141 __func__, MAC_ADDR_ARRAY(peer), action_code);
20142 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020143 }
20144 }
20145
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020146 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
20147 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080020148 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020149 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20150 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020151 {
20152 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
20153 we return error code at 'add_station()'. Hence we have this
20154 check again in addtion to add_station().
20155 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020156 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020157 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20159 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020160 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
20161 __func__, MAC_ADDR_ARRAY(peer), action_code,
20162 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053020163 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080020164 }
20165 else
20166 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020167 /* maximum reached. tweak to send error code to peer and return
20168 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020169 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20171 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020172 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
20173 __func__, MAC_ADDR_ARRAY(peer), status_code,
20174 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070020175 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020176 /* fall through to send setup resp with failure status
20177 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020178 }
20179 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020180 else
20181 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020182 mutex_lock(&pHddCtx->tdls_lock);
20183 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020184 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020185 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020186 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020188 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
20189 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020190 return -EPERM;
20191 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020192 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020193 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020194 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020195
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020196 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020197 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020198 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
20199 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020200
Hoonki Leea34dd892013-02-05 22:56:02 -080020201 /*Except teardown responder will not be used so just make 0*/
20202 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020203 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080020204 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020205
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020206 mutex_lock(&pHddCtx->tdls_lock);
20207 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020208
20209 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
20210 responder = pTdlsPeer->is_responder;
20211 else
Hoonki Leea34dd892013-02-05 22:56:02 -080020212 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020214 "%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 -070020215 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
20216 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020217 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020218 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080020219 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020220 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020221 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020222
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020223 /* Discard TDLS setup if peer is removed by user app */
20224 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
20225 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20226 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
20227 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
20228
20229 mutex_lock(&pHddCtx->tdls_lock);
20230 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20231 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
20232 mutex_unlock(&pHddCtx->tdls_lock);
20233 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
20234 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
20235 MAC_ADDR_ARRAY(peer), action_code);
20236 return -EINVAL;
20237 }
20238 mutex_unlock(&pHddCtx->tdls_lock);
20239 }
20240
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020241 /* For explicit trigger of DIS_REQ come out of BMPS for
20242 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070020243 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053020244 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020245 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
20246 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070020247 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020248 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020250 "%s: Sending frame action_code %u.Disable BMPS", __func__,
20251 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020252 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
20253 if (status != VOS_STATUS_SUCCESS) {
20254 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020255 } else {
20256 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020257 }
Hoonki Lee14621352013-04-16 17:51:19 -070020258 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020259 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020260 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
20262 }
20263 }
Hoonki Lee14621352013-04-16 17:51:19 -070020264 }
20265
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020266 /* make sure doesn't call send_mgmt() while it is pending */
20267 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
20268 {
20269 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080020270 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020271 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020272 ret = -EBUSY;
20273 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020274 }
20275
20276 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020277 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
20278
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020279 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
20280 pAdapter->sessionId, peer, action_code, dialog_token,
20281 status_code, peer_capability, (tANI_U8 *)buf, len,
20282 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020283
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020284 if (VOS_STATUS_SUCCESS != status)
20285 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20287 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020288 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020289 ret = -EINVAL;
20290 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020291 }
20292
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20294 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
20295 WAIT_TIME_TDLS_MGMT);
20296
Hoonki Leed37cbb32013-04-20 00:31:14 -070020297 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
20298 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
20299
20300 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020301 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070020302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070020303 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070020304 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020305 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080020306
20307 if (pHddCtx->isLogpInProgress)
20308 {
20309 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20310 "%s: LOGP in Progress. Ignore!!!", __func__);
20311 return -EAGAIN;
20312 }
Abhishek Singh837adf22015-10-01 17:37:37 +053020313 if (rc <= 0)
20314 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
20315 WLAN_LOG_INDICATOR_HOST_DRIVER,
20316 WLAN_LOG_REASON_HDD_TIME_OUT,
20317 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080020318
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020319 ret = -EINVAL;
20320 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020321 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020322 else
20323 {
20324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20325 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
20326 __func__, rc, pAdapter->mgmtTxCompletionStatus);
20327 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020328
Gopichand Nakkala05922802013-03-14 12:23:19 -070020329 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070020330 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020331 ret = max_sta_failed;
20332 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070020333 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020334
Hoonki Leea34dd892013-02-05 22:56:02 -080020335 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
20336 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020337 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020338 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20339 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020340 }
20341 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
20342 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020343 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020344 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20345 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020346 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020347
20348 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020349
20350tx_failed:
20351 /* add_station will be called before sending TDLS_SETUP_REQ and
20352 * TDLS_SETUP_RSP and as part of add_station driver will enable
20353 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
20354 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
20355 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
20356 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
20357 */
20358
20359 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20360 (SIR_MAC_TDLS_SETUP_RSP == action_code))
20361 wlan_hdd_tdls_check_bmps(pAdapter);
20362 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020363}
20364
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020365#if TDLS_MGMT_VERSION2
20366static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20367 u8 *peer, u8 action_code, u8 dialog_token,
20368 u16 status_code, u32 peer_capability,
20369 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020370#else /* TDLS_MGMT_VERSION2 */
20371#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20372static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20373 struct net_device *dev,
20374 const u8 *peer, u8 action_code,
20375 u8 dialog_token, u16 status_code,
20376 u32 peer_capability, bool initiator,
20377 const u8 *buf, size_t len)
20378#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20379static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20380 struct net_device *dev,
20381 const u8 *peer, u8 action_code,
20382 u8 dialog_token, u16 status_code,
20383 u32 peer_capability, const u8 *buf,
20384 size_t len)
20385#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20386static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20387 struct net_device *dev,
20388 u8 *peer, u8 action_code,
20389 u8 dialog_token,
20390 u16 status_code, u32 peer_capability,
20391 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020392#else
20393static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20394 u8 *peer, u8 action_code, u8 dialog_token,
20395 u16 status_code, const u8 *buf, size_t len)
20396#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020397#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020398{
20399 int ret;
20400
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020401 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020402#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020403 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20404 dialog_token, status_code,
20405 peer_capability, buf, len);
20406#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020407#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20408 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020409 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20410 dialog_token, status_code,
20411 peer_capability, initiator,
20412 buf, len);
20413#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20414 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20415 dialog_token, status_code,
20416 peer_capability, buf, len);
20417#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20418 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20419 dialog_token, status_code,
20420 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020421#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020422 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20423 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020424#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020425#endif
20426 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020427
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020428 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020429}
Atul Mittal115287b2014-07-08 13:26:33 +053020430
20431int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020432#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20433 const u8 *peer,
20434#else
Atul Mittal115287b2014-07-08 13:26:33 +053020435 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020436#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020437 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053020438 cfg80211_exttdls_callback callback)
20439{
20440
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020441 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053020442 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020443 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053020444 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20445 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
20446 __func__, MAC_ADDR_ARRAY(peer));
20447
20448 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20449 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20450
20451 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020452 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20453 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20454 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020455 return -ENOTSUPP;
20456 }
20457
20458 /* To cater the requirement of establishing the TDLS link
20459 * irrespective of the data traffic , get an entry of TDLS peer.
20460 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020461 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020462 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
20463 if (pTdlsPeer == NULL) {
20464 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20465 "%s: peer " MAC_ADDRESS_STR " not existing",
20466 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020467 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020468 return -EINVAL;
20469 }
20470
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020471 /* check FW TDLS Off Channel capability */
20472 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020473 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020474 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020475 {
20476 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
20477 pTdlsPeer->peerParams.global_operating_class =
20478 tdls_peer_params->global_operating_class;
20479 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
20480 pTdlsPeer->peerParams.min_bandwidth_kbps =
20481 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020482 /* check configured channel is valid, non dfs and
20483 * not current operating channel */
20484 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
20485 tdls_peer_params->channel)) &&
20486 (pHddStaCtx) &&
20487 (tdls_peer_params->channel !=
20488 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020489 {
20490 pTdlsPeer->isOffChannelConfigured = TRUE;
20491 }
20492 else
20493 {
20494 pTdlsPeer->isOffChannelConfigured = FALSE;
20495 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20496 "%s: Configured Tdls Off Channel is not valid", __func__);
20497
20498 }
20499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020500 "%s: tdls_off_channel %d isOffChannelConfigured %d "
20501 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020502 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020503 pTdlsPeer->isOffChannelConfigured,
20504 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020505 }
20506 else
20507 {
20508 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020509 "%s: TDLS off channel FW capability %d, "
20510 "host capab %d or Invalid TDLS Peer Params", __func__,
20511 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
20512 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020513 }
20514
Atul Mittal115287b2014-07-08 13:26:33 +053020515 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
20516
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020517 mutex_unlock(&pHddCtx->tdls_lock);
20518
Atul Mittal115287b2014-07-08 13:26:33 +053020519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20520 " %s TDLS Add Force Peer Failed",
20521 __func__);
20522 return -EINVAL;
20523 }
20524 /*EXT TDLS*/
20525
20526 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020527 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20529 " %s TDLS set callback Failed",
20530 __func__);
20531 return -EINVAL;
20532 }
20533
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020534 mutex_unlock(&pHddCtx->tdls_lock);
20535
Atul Mittal115287b2014-07-08 13:26:33 +053020536 return(0);
20537
20538}
20539
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020540int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
20541#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20542 const u8 *peer
20543#else
20544 u8 *peer
20545#endif
20546)
Atul Mittal115287b2014-07-08 13:26:33 +053020547{
20548
20549 hddTdlsPeer_t *pTdlsPeer;
20550 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020551
Atul Mittal115287b2014-07-08 13:26:33 +053020552 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20553 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
20554 __func__, MAC_ADDR_ARRAY(peer));
20555
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020556 if (0 != wlan_hdd_validate_context(pHddCtx)) {
20557 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
20558 return -EINVAL;
20559 }
20560
Atul Mittal115287b2014-07-08 13:26:33 +053020561 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20562 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20563
20564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020565 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20566 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20567 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020568 return -ENOTSUPP;
20569 }
20570
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020571 mutex_lock(&pHddCtx->tdls_lock);
20572 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053020573
20574 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020575 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020576 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020577 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053020578 __func__, MAC_ADDR_ARRAY(peer));
20579 return -EINVAL;
20580 }
20581 else {
20582 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
20583 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020584 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
20585 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020586 /* if channel switch is configured, reset
20587 the channel for this peer */
20588 if (TRUE == pTdlsPeer->isOffChannelConfigured)
20589 {
20590 pTdlsPeer->peerParams.channel = 0;
20591 pTdlsPeer->isOffChannelConfigured = FALSE;
20592 }
Atul Mittal115287b2014-07-08 13:26:33 +053020593 }
20594
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020595 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020596 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020597 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053020598 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020599 }
Atul Mittal115287b2014-07-08 13:26:33 +053020600
20601 /*EXT TDLS*/
20602
20603 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020604 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020605 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20606 " %s TDLS set callback Failed",
20607 __func__);
20608 return -EINVAL;
20609 }
Atul Mittal115287b2014-07-08 13:26:33 +053020610
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020611 mutex_unlock(&pHddCtx->tdls_lock);
20612
20613 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053020614}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020615static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020616#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20617 const u8 *peer,
20618#else
20619 u8 *peer,
20620#endif
20621 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020622{
20623 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20624 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020625 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020626 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020627
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020628 ENTER();
20629
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020630 if (!pAdapter) {
20631 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
20632 return -EINVAL;
20633 }
20634
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020635 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20636 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
20637 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020638 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020639 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070020641 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020642 return -EINVAL;
20643 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020644
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020645 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020646 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020647 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020648 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020649 }
20650
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020651
20652 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020653 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020654 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020656 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
20657 "Cannot process TDLS commands",
20658 pHddCtx->cfg_ini->fEnableTDLSSupport,
20659 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020660 return -ENOTSUPP;
20661 }
20662
20663 switch (oper) {
20664 case NL80211_TDLS_ENABLE_LINK:
20665 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020666 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020667 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053020668 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
20669 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053020670 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020671 tANI_U16 numCurrTdlsPeers = 0;
20672 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020673 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020674 tSirMacAddr peerMac;
20675 int channel;
20676 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020677
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20679 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
20680 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020681
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020682 mutex_lock(&pHddCtx->tdls_lock);
20683 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020684 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053020685 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020686 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020687 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20688 " (oper %d) not exsting. ignored",
20689 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20690 return -EINVAL;
20691 }
20692
20693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20694 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20695 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20696 "NL80211_TDLS_ENABLE_LINK");
20697
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020698 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
20699 {
20700 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
20701 MAC_ADDRESS_STR " failed",
20702 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020703 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020704 return -EINVAL;
20705 }
20706
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020707 /* before starting tdls connection, set tdls
20708 * off channel established status to default value */
20709 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020710
20711 mutex_unlock(&pHddCtx->tdls_lock);
20712
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053020713 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020714 /* TDLS Off Channel, Disable tdls channel switch,
20715 when there are more than one tdls link */
20716 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053020717 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020718 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020719 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020720 /* get connected peer and send disable tdls off chan */
20721 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020722 if ((connPeer) &&
20723 (connPeer->isOffChannelSupported == TRUE) &&
20724 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020725 {
20726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20727 "%s: More then one peer connected, Disable "
20728 "TDLS channel switch", __func__);
20729
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020730 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020731 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
20732 channel = connPeer->peerParams.channel;
20733
20734 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020735
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020736 ret = sme_SendTdlsChanSwitchReq(
20737 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020738 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020739 peerMac,
20740 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020741 TDLS_OFF_CHANNEL_BW_OFFSET,
20742 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020743 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020744 hddLog(VOS_TRACE_LEVEL_ERROR,
20745 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020746 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020747 }
20748 else
20749 {
20750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20751 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020752 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020753 "isOffChannelConfigured %d",
20754 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020755 (connPeer ? (connPeer->isOffChannelSupported)
20756 : -1),
20757 (connPeer ? (connPeer->isOffChannelConfigured)
20758 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020759 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020760 }
20761 }
20762
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020763 mutex_lock(&pHddCtx->tdls_lock);
20764 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20765 if ( NULL == pTdlsPeer ) {
20766 mutex_unlock(&pHddCtx->tdls_lock);
20767 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20768 "%s: " MAC_ADDRESS_STR
20769 " (oper %d) peer got freed in other context. ignored",
20770 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20771 return -EINVAL;
20772 }
20773 peer_status = pTdlsPeer->link_status;
20774 mutex_unlock(&pHddCtx->tdls_lock);
20775
20776 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020777 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020778 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053020779
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020780 if (0 != wlan_hdd_tdls_get_link_establish_params(
20781 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020783 return -EINVAL;
20784 }
20785 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020786
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020787 ret = sme_SendTdlsLinkEstablishParams(
20788 WLAN_HDD_GET_HAL_CTX(pAdapter),
20789 pAdapter->sessionId, peer,
20790 &tdlsLinkEstablishParams);
20791 if (ret != VOS_STATUS_SUCCESS) {
20792 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
20793 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020794 /* Send TDLS peer UAPSD capabilities to the firmware and
20795 * register with the TL on after the response for this operation
20796 * is received .
20797 */
20798 ret = wait_for_completion_interruptible_timeout(
20799 &pAdapter->tdls_link_establish_req_comp,
20800 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053020801
20802 mutex_lock(&pHddCtx->tdls_lock);
20803 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20804 if ( NULL == pTdlsPeer ) {
20805 mutex_unlock(&pHddCtx->tdls_lock);
20806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20807 "%s %d: " MAC_ADDRESS_STR
20808 " (oper %d) peer got freed in other context. ignored",
20809 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
20810 (int)oper);
20811 return -EINVAL;
20812 }
20813 peer_status = pTdlsPeer->link_status;
20814 mutex_unlock(&pHddCtx->tdls_lock);
20815
20816 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020817 {
20818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020819 FL("Link Establish Request Failed Status %ld"),
20820 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020821 return -EINVAL;
20822 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020823 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020824
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020825 mutex_lock(&pHddCtx->tdls_lock);
20826 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20827 if ( NULL == pTdlsPeer ) {
20828 mutex_unlock(&pHddCtx->tdls_lock);
20829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20830 "%s: " MAC_ADDRESS_STR
20831 " (oper %d) peer got freed in other context. ignored",
20832 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20833 return -EINVAL;
20834 }
20835
Atul Mittal115287b2014-07-08 13:26:33 +053020836 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20837 eTDLS_LINK_CONNECTED,
20838 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020839 staDesc.ucSTAId = pTdlsPeer->staId;
20840 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053020841
20842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20843 "%s: tdlsLinkEstablishParams of peer "
20844 MAC_ADDRESS_STR "uapsdQueues: %d"
20845 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
20846 "isResponder: %d peerstaId: %d",
20847 __func__,
20848 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
20849 tdlsLinkEstablishParams.uapsdQueues,
20850 tdlsLinkEstablishParams.qos,
20851 tdlsLinkEstablishParams.maxSp,
20852 tdlsLinkEstablishParams.isBufSta,
20853 tdlsLinkEstablishParams.isOffChannelSupported,
20854 tdlsLinkEstablishParams.isResponder,
20855 pTdlsPeer->staId);
20856
20857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20858 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
20859 __func__,
20860 staDesc.ucSTAId,
20861 staDesc.ucQosEnabled);
20862
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020863 ret = WLANTL_UpdateTdlsSTAClient(
20864 pHddCtx->pvosContext,
20865 &staDesc);
20866 if (ret != VOS_STATUS_SUCCESS) {
20867 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
20868 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053020869
Gopichand Nakkala471708b2013-06-04 20:03:01 +053020870 /* Mark TDLS client Authenticated .*/
20871 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
20872 pTdlsPeer->staId,
20873 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020874 if (VOS_STATUS_SUCCESS == status)
20875 {
Hoonki Lee14621352013-04-16 17:51:19 -070020876 if (pTdlsPeer->is_responder == 0)
20877 {
20878 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020879 tdlsConnInfo_t *tdlsInfo;
20880
20881 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
20882
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020883 if (!vos_timer_is_initialized(
20884 &pTdlsPeer->initiatorWaitTimeoutTimer))
20885 {
20886 /* Initialize initiator wait callback */
20887 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020888 &pTdlsPeer->initiatorWaitTimeoutTimer,
20889 VOS_TIMER_TYPE_SW,
20890 wlan_hdd_tdls_initiator_wait_cb,
20891 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020892 }
Hoonki Lee14621352013-04-16 17:51:19 -070020893 wlan_hdd_tdls_timer_restart(pAdapter,
20894 &pTdlsPeer->initiatorWaitTimeoutTimer,
20895 WAIT_TIME_TDLS_INITIATOR);
20896 /* suspend initiator TX until it receives direct packet from the
20897 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020898 ret = WLANTL_SuspendDataTx(
20899 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20900 &staId, NULL);
20901 if (ret != VOS_STATUS_SUCCESS) {
20902 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20903 }
Hoonki Lee14621352013-04-16 17:51:19 -070020904 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020905
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020906 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020907 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020908 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020909 suppChannelLen =
20910 tdlsLinkEstablishParams.supportedChannelsLen;
20911
20912 if ((suppChannelLen > 0) &&
20913 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20914 {
20915 tANI_U8 suppPeerChannel = 0;
20916 int i = 0;
20917 for (i = 0U; i < suppChannelLen; i++)
20918 {
20919 suppPeerChannel =
20920 tdlsLinkEstablishParams.supportedChannels[i];
20921
20922 pTdlsPeer->isOffChannelSupported = FALSE;
20923 if (suppPeerChannel ==
20924 pTdlsPeer->peerParams.channel)
20925 {
20926 pTdlsPeer->isOffChannelSupported = TRUE;
20927 break;
20928 }
20929 }
20930 }
20931 else
20932 {
20933 pTdlsPeer->isOffChannelSupported = FALSE;
20934 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020935 }
20936 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20937 "%s: TDLS channel switch request for channel "
20938 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020939 "%d isOffChannelSupported %d", __func__,
20940 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020941 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020942 suppChannelLen,
20943 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020944
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020945 /* TDLS Off Channel, Enable tdls channel switch,
20946 when their is only one tdls link and it supports */
20947 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20948 if ((numCurrTdlsPeers == 1) &&
20949 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20950 (TRUE == pTdlsPeer->isOffChannelConfigured))
20951 {
20952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20953 "%s: Send TDLS channel switch request for channel %d",
20954 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020955
20956 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020957 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20958 channel = pTdlsPeer->peerParams.channel;
20959
20960 mutex_unlock(&pHddCtx->tdls_lock);
20961
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020962 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20963 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020964 peerMac,
20965 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020966 TDLS_OFF_CHANNEL_BW_OFFSET,
20967 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020968 if (ret != VOS_STATUS_SUCCESS) {
20969 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20970 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020971 }
20972 else
20973 {
20974 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20975 "%s: TDLS channel switch request not sent"
20976 " numCurrTdlsPeers %d "
20977 "isOffChannelSupported %d "
20978 "isOffChannelConfigured %d",
20979 __func__, numCurrTdlsPeers,
20980 pTdlsPeer->isOffChannelSupported,
20981 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020982 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020983 }
20984
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020985 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020986 else
20987 mutex_unlock(&pHddCtx->tdls_lock);
20988
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020989 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020990
20991 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020992 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
20993 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020994 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020995 int ac;
20996 uint8 ucAc[4] = { WLANTL_AC_VO,
20997 WLANTL_AC_VI,
20998 WLANTL_AC_BK,
20999 WLANTL_AC_BE };
21000 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
21001 for(ac=0; ac < 4; ac++)
21002 {
21003 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
21004 pTdlsPeer->staId, ucAc[ac],
21005 tlTid[ac], tlTid[ac], 0, 0,
21006 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021007 if (status != VOS_STATUS_SUCCESS) {
21008 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
21009 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021010 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021011 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021012 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021013
Bhargav Shah66896792015-10-01 18:17:37 +053021014 /* stop TCP delack timer if TDLS is enable */
21015 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21016 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053021017 hdd_wlan_tdls_enable_link_event(peer,
21018 pTdlsPeer->isOffChannelSupported,
21019 pTdlsPeer->isOffChannelConfigured,
21020 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021021 }
21022 break;
21023 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080021024 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021025 tANI_U16 numCurrTdlsPeers = 0;
21026 hddTdlsPeer_t *connPeer = NULL;
21027
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21029 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
21030 __func__, MAC_ADDR_ARRAY(peer));
21031
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021032 mutex_lock(&pHddCtx->tdls_lock);
21033 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021034
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021035
Sunil Dutt41de4e22013-11-14 18:09:02 +053021036 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021037 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021038 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21039 " (oper %d) not exsting. ignored",
21040 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
21041 return -EINVAL;
21042 }
21043
21044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21045 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
21046 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
21047 "NL80211_TDLS_DISABLE_LINK");
21048
Hoonki Lee5305c3a2013-04-29 23:28:59 -070021049 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080021050 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021051 long status;
21052
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053021053 /* set tdls off channel status to false for this peer */
21054 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053021055 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
21056 eTDLS_LINK_TEARING,
21057 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
21058 eTDLS_LINK_UNSPECIFIED:
21059 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021060 mutex_unlock(&pHddCtx->tdls_lock);
21061
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021062 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
21063
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021064 status = sme_DeleteTdlsPeerSta(
21065 WLAN_HDD_GET_HAL_CTX(pAdapter),
21066 pAdapter->sessionId, peer );
21067 if (status != VOS_STATUS_SUCCESS) {
21068 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
21069 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021070
21071 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
21072 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021073
21074 mutex_lock(&pHddCtx->tdls_lock);
21075 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21076 if ( NULL == pTdlsPeer ) {
21077 mutex_unlock(&pHddCtx->tdls_lock);
21078 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21079 " peer was freed in other context",
21080 __func__, MAC_ADDR_ARRAY(peer));
21081 return -EINVAL;
21082 }
21083
Atul Mittal271a7652014-09-12 13:18:22 +053021084 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053021085 eTDLS_LINK_IDLE,
21086 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021087 mutex_unlock(&pHddCtx->tdls_lock);
21088
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021089 if (status <= 0)
21090 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021091 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21092 "%s: Del station failed status %ld",
21093 __func__, status);
21094 return -EPERM;
21095 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021096
21097 /* TDLS Off Channel, Enable tdls channel switch,
21098 when their is only one tdls link and it supports */
21099 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
21100 if (numCurrTdlsPeers == 1)
21101 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021102 tSirMacAddr peerMac;
21103 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021104
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021105 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021106 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021107
21108 if (connPeer == NULL) {
21109 mutex_unlock(&pHddCtx->tdls_lock);
21110 hddLog(VOS_TRACE_LEVEL_ERROR,
21111 "%s connPeer is NULL", __func__);
21112 return -EINVAL;
21113 }
21114
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021115 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
21116 channel = connPeer->peerParams.channel;
21117
21118 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21119 "%s: TDLS channel switch "
21120 "isOffChannelSupported %d "
21121 "isOffChannelConfigured %d "
21122 "isOffChannelEstablished %d",
21123 __func__,
21124 (connPeer ? connPeer->isOffChannelSupported : -1),
21125 (connPeer ? connPeer->isOffChannelConfigured : -1),
21126 (connPeer ? connPeer->isOffChannelEstablished : -1));
21127
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021128 if ((connPeer) &&
21129 (connPeer->isOffChannelSupported == TRUE) &&
21130 (connPeer->isOffChannelConfigured == TRUE))
21131 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053021132 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021133 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021134 status = sme_SendTdlsChanSwitchReq(
21135 WLAN_HDD_GET_HAL_CTX(pAdapter),
21136 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021137 peerMac,
21138 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021139 TDLS_OFF_CHANNEL_BW_OFFSET,
21140 TDLS_CHANNEL_SWITCH_ENABLE);
21141 if (status != VOS_STATUS_SUCCESS) {
21142 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
21143 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021144 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021145 else
21146 mutex_unlock(&pHddCtx->tdls_lock);
21147 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021148 else
21149 {
21150 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21151 "%s: TDLS channel switch request not sent "
21152 "numCurrTdlsPeers %d ",
21153 __func__, numCurrTdlsPeers);
21154 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021155 }
21156 else
21157 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021158 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21160 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080021161 }
Bhargav Shah66896792015-10-01 18:17:37 +053021162 if (numCurrTdlsPeers == 0) {
21163 /* start TCP delack timer if TDLS is disable */
21164 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21165 hdd_manage_delack_timer(pHddCtx);
21166 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021167 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021168 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021169 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021170 {
Atul Mittal115287b2014-07-08 13:26:33 +053021171 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021172
Atul Mittal115287b2014-07-08 13:26:33 +053021173 if (0 != status)
21174 {
21175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021176 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053021177 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021178 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053021179 break;
21180 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021181 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021182 {
Atul Mittal115287b2014-07-08 13:26:33 +053021183 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
21184 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021185 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053021186 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021187
Atul Mittal115287b2014-07-08 13:26:33 +053021188 if (0 != status)
21189 {
21190 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021191 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053021192 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053021193 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053021194 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021195 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021196 case NL80211_TDLS_DISCOVERY_REQ:
21197 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021199 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021200 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021201 return -ENOTSUPP;
21202 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021203 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21204 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021205 return -ENOTSUPP;
21206 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021207
21208 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021209 return 0;
21210}
Chilam NG571c65a2013-01-19 12:27:36 +053021211
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021212static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021213#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
21214 const u8 *peer,
21215#else
21216 u8 *peer,
21217#endif
21218 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021219{
21220 int ret;
21221
21222 vos_ssr_protect(__func__);
21223 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
21224 vos_ssr_unprotect(__func__);
21225
21226 return ret;
21227}
21228
Chilam NG571c65a2013-01-19 12:27:36 +053021229int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
21230 struct net_device *dev, u8 *peer)
21231{
Arif Hussaina7c8e412013-11-20 11:06:42 -080021232 hddLog(VOS_TRACE_LEVEL_INFO,
21233 "tdls send discover req: "MAC_ADDRESS_STR,
21234 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021235#if TDLS_MGMT_VERSION2
21236 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21237 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21238#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021239#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
21240 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21241 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
21242#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
21243 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21244 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21245#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
21246 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21247 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21248#else
Chilam NG571c65a2013-01-19 12:27:36 +053021249 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21250 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021251#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021252#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053021253}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021254#endif
21255
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021256#ifdef WLAN_FEATURE_GTK_OFFLOAD
21257/*
21258 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
21259 * Callback rountine called upon receiving response for
21260 * get offload info
21261 */
21262void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
21263 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
21264{
21265
21266 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021267 tANI_U8 tempReplayCounter[8];
21268 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021269
21270 ENTER();
21271
21272 if (NULL == pAdapter)
21273 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053021274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021275 "%s: HDD adapter is Null", __func__);
21276 return ;
21277 }
21278
21279 if (NULL == pGtkOffloadGetInfoRsp)
21280 {
21281 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21282 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
21283 return ;
21284 }
21285
21286 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
21287 {
21288 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21289 "%s: wlan Failed to get replay counter value",
21290 __func__);
21291 return ;
21292 }
21293
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021294 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21295 /* Update replay counter */
21296 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
21297 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21298
21299 {
21300 /* changing from little to big endian since supplicant
21301 * works on big endian format
21302 */
21303 int i;
21304 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21305
21306 for (i = 0; i < 8; i++)
21307 {
21308 tempReplayCounter[7-i] = (tANI_U8)p[i];
21309 }
21310 }
21311
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021312 /* Update replay counter to NL */
21313 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021314 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021315}
21316
21317/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021318 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021319 * This function is used to offload GTK rekeying job to the firmware.
21320 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021321int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021322 struct cfg80211_gtk_rekey_data *data)
21323{
21324 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21325 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21326 hdd_station_ctx_t *pHddStaCtx;
21327 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021328 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021329 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021330 eHalStatus status = eHAL_STATUS_FAILURE;
21331
21332 ENTER();
21333
21334 if (NULL == pAdapter)
21335 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053021336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021337 "%s: HDD adapter is Null", __func__);
21338 return -ENODEV;
21339 }
21340
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053021341 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21342 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
21343 pAdapter->sessionId, pAdapter->device_mode));
21344
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021345 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021346 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021347 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021348 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021349 }
21350
21351 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21352 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
21353 if (NULL == hHal)
21354 {
21355 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21356 "%s: HAL context is Null!!!", __func__);
21357 return -EAGAIN;
21358 }
21359
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021360 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
21361 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
21362 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
21363 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021364 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021365 {
21366 /* changing from big to little endian since driver
21367 * works on little endian format
21368 */
21369 tANI_U8 *p =
21370 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
21371 int i;
21372
21373 for (i = 0; i < 8; i++)
21374 {
21375 p[7-i] = data->replay_ctr[i];
21376 }
21377 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021378
21379 if (TRUE == pHddCtx->hdd_wlan_suspended)
21380 {
21381 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021382 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
21383 sizeof (tSirGtkOffloadParams));
21384 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021385 pAdapter->sessionId);
21386
21387 if (eHAL_STATUS_SUCCESS != status)
21388 {
21389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21390 "%s: sme_SetGTKOffload failed, returned %d",
21391 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021392
21393 /* Need to clear any trace of key value in the memory.
21394 * Thus zero out the memory even though it is local
21395 * variable.
21396 */
21397 vos_mem_zero(&hddGtkOffloadReqParams,
21398 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021399 return status;
21400 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21402 "%s: sme_SetGTKOffload successfull", __func__);
21403 }
21404 else
21405 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021406 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21407 "%s: wlan not suspended GTKOffload request is stored",
21408 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021409 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021410
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021411 /* Need to clear any trace of key value in the memory.
21412 * Thus zero out the memory even though it is local
21413 * variable.
21414 */
21415 vos_mem_zero(&hddGtkOffloadReqParams,
21416 sizeof(hddGtkOffloadReqParams));
21417
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021418 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021419 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021420}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021421
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021422int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
21423 struct cfg80211_gtk_rekey_data *data)
21424{
21425 int ret;
21426
21427 vos_ssr_protect(__func__);
21428 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
21429 vos_ssr_unprotect(__func__);
21430
21431 return ret;
21432}
21433#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021434/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021435 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021436 * This function is used to set access control policy
21437 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021438static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21439 struct net_device *dev,
21440 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021441{
21442 int i;
21443 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21444 hdd_hostapd_state_t *pHostapdState;
21445 tsap_Config_t *pConfig;
21446 v_CONTEXT_t pVosContext = NULL;
21447 hdd_context_t *pHddCtx;
21448 int status;
21449
21450 ENTER();
21451
21452 if (NULL == pAdapter)
21453 {
21454 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21455 "%s: HDD adapter is Null", __func__);
21456 return -ENODEV;
21457 }
21458
21459 if (NULL == params)
21460 {
21461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21462 "%s: params is Null", __func__);
21463 return -EINVAL;
21464 }
21465
21466 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21467 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021468 if (0 != status)
21469 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021470 return status;
21471 }
21472
21473 pVosContext = pHddCtx->pvosContext;
21474 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
21475
21476 if (NULL == pHostapdState)
21477 {
21478 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21479 "%s: pHostapdState is Null", __func__);
21480 return -EINVAL;
21481 }
21482
21483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
21484 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021485 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21486 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
21487 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021488
21489 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
21490 {
21491 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
21492
21493 /* default value */
21494 pConfig->num_accept_mac = 0;
21495 pConfig->num_deny_mac = 0;
21496
21497 /**
21498 * access control policy
21499 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
21500 * listed in hostapd.deny file.
21501 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
21502 * listed in hostapd.accept file.
21503 */
21504 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
21505 {
21506 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
21507 }
21508 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
21509 {
21510 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
21511 }
21512 else
21513 {
21514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21515 "%s:Acl Policy : %d is not supported",
21516 __func__, params->acl_policy);
21517 return -ENOTSUPP;
21518 }
21519
21520 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
21521 {
21522 pConfig->num_accept_mac = params->n_acl_entries;
21523 for (i = 0; i < params->n_acl_entries; i++)
21524 {
21525 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21526 "** Add ACL MAC entry %i in WhiletList :"
21527 MAC_ADDRESS_STR, i,
21528 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21529
21530 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
21531 sizeof(qcmacaddr));
21532 }
21533 }
21534 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
21535 {
21536 pConfig->num_deny_mac = params->n_acl_entries;
21537 for (i = 0; i < params->n_acl_entries; i++)
21538 {
21539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21540 "** Add ACL MAC entry %i in BlackList :"
21541 MAC_ADDRESS_STR, i,
21542 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21543
21544 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
21545 sizeof(qcmacaddr));
21546 }
21547 }
21548
21549 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
21550 {
21551 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21552 "%s: SAP Set Mac Acl fail", __func__);
21553 return -EINVAL;
21554 }
21555 }
21556 else
21557 {
21558 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053021559 "%s: Invalid device_mode = %s (%d)",
21560 __func__, hdd_device_modetoString(pAdapter->device_mode),
21561 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021562 return -EINVAL;
21563 }
21564
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021565 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021566 return 0;
21567}
21568
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021569static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21570 struct net_device *dev,
21571 const struct cfg80211_acl_data *params)
21572{
21573 int ret;
21574 vos_ssr_protect(__func__);
21575 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
21576 vos_ssr_unprotect(__func__);
21577
21578 return ret;
21579}
21580
Leo Chang9056f462013-08-01 19:21:11 -070021581#ifdef WLAN_NL80211_TESTMODE
21582#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070021583void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070021584(
21585 void *pAdapter,
21586 void *indCont
21587)
21588{
Leo Changd9df8aa2013-09-26 13:32:26 -070021589 tSirLPHBInd *lphbInd;
21590 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053021591 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070021592
21593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021594 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070021595
c_hpothu73f35e62014-04-18 13:40:08 +053021596 if (pAdapter == NULL)
21597 {
21598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21599 "%s: pAdapter is NULL\n",__func__);
21600 return;
21601 }
21602
Leo Chang9056f462013-08-01 19:21:11 -070021603 if (NULL == indCont)
21604 {
21605 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021606 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070021607 return;
21608 }
21609
c_hpothu73f35e62014-04-18 13:40:08 +053021610 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070021611 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070021612 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053021613 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070021614 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070021615 GFP_ATOMIC);
21616 if (!skb)
21617 {
21618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21619 "LPHB timeout, NL buffer alloc fail");
21620 return;
21621 }
21622
Leo Changac3ba772013-10-07 09:47:04 -070021623 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070021624 {
21625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21626 "WLAN_HDD_TM_ATTR_CMD put fail");
21627 goto nla_put_failure;
21628 }
Leo Changac3ba772013-10-07 09:47:04 -070021629 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070021630 {
21631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21632 "WLAN_HDD_TM_ATTR_TYPE put fail");
21633 goto nla_put_failure;
21634 }
Leo Changac3ba772013-10-07 09:47:04 -070021635 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070021636 sizeof(tSirLPHBInd), lphbInd))
21637 {
21638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21639 "WLAN_HDD_TM_ATTR_DATA put fail");
21640 goto nla_put_failure;
21641 }
Leo Chang9056f462013-08-01 19:21:11 -070021642 cfg80211_testmode_event(skb, GFP_ATOMIC);
21643 return;
21644
21645nla_put_failure:
21646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21647 "NLA Put fail");
21648 kfree_skb(skb);
21649
21650 return;
21651}
21652#endif /* FEATURE_WLAN_LPHB */
21653
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021654static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070021655{
21656 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
21657 int err = 0;
21658#ifdef FEATURE_WLAN_LPHB
21659 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070021660 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021661
21662 ENTER();
21663
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021664 err = wlan_hdd_validate_context(pHddCtx);
21665 if (0 != err)
21666 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021667 return err;
21668 }
Leo Chang9056f462013-08-01 19:21:11 -070021669#endif /* FEATURE_WLAN_LPHB */
21670
21671 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
21672 if (err)
21673 {
21674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21675 "%s Testmode INV ATTR", __func__);
21676 return err;
21677 }
21678
21679 if (!tb[WLAN_HDD_TM_ATTR_CMD])
21680 {
21681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21682 "%s Testmode INV CMD", __func__);
21683 return -EINVAL;
21684 }
21685
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021686 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21687 TRACE_CODE_HDD_CFG80211_TESTMODE,
21688 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070021689 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
21690 {
21691#ifdef FEATURE_WLAN_LPHB
21692 /* Low Power Heartbeat configuration request */
21693 case WLAN_HDD_TM_CMD_WLAN_HB:
21694 {
21695 int buf_len;
21696 void *buf;
21697 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080021698 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070021699
21700 if (!tb[WLAN_HDD_TM_ATTR_DATA])
21701 {
21702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21703 "%s Testmode INV DATA", __func__);
21704 return -EINVAL;
21705 }
21706
21707 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
21708 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080021709
Manjeet Singh3c577442017-02-10 19:03:38 +053021710 if (buf_len > sizeof(*hb_params)) {
21711 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
21712 buf_len);
21713 return -ERANGE;
21714 }
21715
Amar Singhal05852702014-02-04 14:40:00 -080021716 hb_params_temp =(tSirLPHBReq *)buf;
21717 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
21718 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
21719 return -EINVAL;
21720
Leo Chang9056f462013-08-01 19:21:11 -070021721 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
21722 if (NULL == hb_params)
21723 {
21724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21725 "%s Request Buffer Alloc Fail", __func__);
21726 return -EINVAL;
21727 }
21728
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053021729 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070021730 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070021731 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
21732 hb_params,
21733 wlan_hdd_cfg80211_lphb_ind_handler);
21734 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070021735 {
Leo Changd9df8aa2013-09-26 13:32:26 -070021736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21737 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070021738 vos_mem_free(hb_params);
21739 }
Leo Chang9056f462013-08-01 19:21:11 -070021740 return 0;
21741 }
21742#endif /* FEATURE_WLAN_LPHB */
21743 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21745 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070021746 return -EOPNOTSUPP;
21747 }
21748
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021749 EXIT();
21750 return err;
Leo Chang9056f462013-08-01 19:21:11 -070021751}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021752
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053021753static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
21754#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
21755 struct wireless_dev *wdev,
21756#endif
21757 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021758{
21759 int ret;
21760
21761 vos_ssr_protect(__func__);
21762 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
21763 vos_ssr_unprotect(__func__);
21764
21765 return ret;
21766}
Leo Chang9056f462013-08-01 19:21:11 -070021767#endif /* CONFIG_NL80211_TESTMODE */
21768
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021769extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021770static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021771 struct net_device *dev,
21772 int idx, struct survey_info *survey)
21773{
21774 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21775 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053021776 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021777 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053021778 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021779 v_S7_t snr,rssi;
21780 int status, i, j, filled = 0;
21781
21782 ENTER();
21783
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021784 if (NULL == pAdapter)
21785 {
21786 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21787 "%s: HDD adapter is Null", __func__);
21788 return -ENODEV;
21789 }
21790
21791 if (NULL == wiphy)
21792 {
21793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21794 "%s: wiphy is Null", __func__);
21795 return -ENODEV;
21796 }
21797
21798 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21799 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021800 if (0 != status)
21801 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021802 return status;
21803 }
21804
Mihir Sheted9072e02013-08-21 17:02:29 +053021805 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21806
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021807 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053021808 0 != pAdapter->survey_idx ||
21809 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021810 {
21811 /* The survey dump ops when implemented completely is expected to
21812 * return a survey of all channels and the ops is called by the
21813 * kernel with incremental values of the argument 'idx' till it
21814 * returns -ENONET. But we can only support the survey for the
21815 * operating channel for now. survey_idx is used to track
21816 * that the ops is called only once and then return -ENONET for
21817 * the next iteration
21818 */
21819 pAdapter->survey_idx = 0;
21820 return -ENONET;
21821 }
21822
Mukul Sharma9d5233b2015-06-11 20:28:20 +053021823 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
21824 {
21825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21826 "%s: Roaming in progress, hence return ", __func__);
21827 return -ENONET;
21828 }
21829
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021830 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
21831
21832 wlan_hdd_get_snr(pAdapter, &snr);
21833 wlan_hdd_get_rssi(pAdapter, &rssi);
21834
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021835 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21836 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
21837 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021838 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
21839 hdd_wlan_get_freq(channel, &freq);
21840
21841
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053021842 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021843 {
21844 if (NULL == wiphy->bands[i])
21845 {
21846 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
21847 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
21848 continue;
21849 }
21850
21851 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
21852 {
21853 struct ieee80211_supported_band *band = wiphy->bands[i];
21854
21855 if (band->channels[j].center_freq == (v_U16_t)freq)
21856 {
21857 survey->channel = &band->channels[j];
21858 /* The Rx BDs contain SNR values in dB for the received frames
21859 * while the supplicant expects noise. So we calculate and
21860 * return the value of noise (dBm)
21861 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
21862 */
21863 survey->noise = rssi - snr;
21864 survey->filled = SURVEY_INFO_NOISE_DBM;
21865 filled = 1;
21866 }
21867 }
21868 }
21869
21870 if (filled)
21871 pAdapter->survey_idx = 1;
21872 else
21873 {
21874 pAdapter->survey_idx = 0;
21875 return -ENONET;
21876 }
21877
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021878 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021879 return 0;
21880}
21881
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021882static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
21883 struct net_device *dev,
21884 int idx, struct survey_info *survey)
21885{
21886 int ret;
21887
21888 vos_ssr_protect(__func__);
21889 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
21890 vos_ssr_unprotect(__func__);
21891
21892 return ret;
21893}
21894
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021895/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021896 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021897 * this is called when cfg80211 driver resume
21898 * driver updates latest sched_scan scan result(if any) to cfg80211 database
21899 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021900int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021901{
21902 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21903 hdd_adapter_t *pAdapter;
21904 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21905 VOS_STATUS status = VOS_STATUS_SUCCESS;
21906
21907 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021908
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021909 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021910 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021911 return 0;
21912 }
21913
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021914 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21915 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021916
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021917 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021918 {
21919 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21920 "%s: Resume SoftAP", __func__);
21921 hdd_set_wlan_suspend_mode(false);
21922 }
21923
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021924 spin_lock(&pHddCtx->schedScan_lock);
21925 pHddCtx->isWiphySuspended = FALSE;
21926 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21927 {
21928 spin_unlock(&pHddCtx->schedScan_lock);
21929 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21930 "%s: Return resume is not due to PNO indication", __func__);
21931 return 0;
21932 }
21933 // Reset flag to avoid updatating cfg80211 data old results again
21934 pHddCtx->isSchedScanUpdatePending = FALSE;
21935 spin_unlock(&pHddCtx->schedScan_lock);
21936
21937 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21938
21939 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21940 {
21941 pAdapter = pAdapterNode->pAdapter;
21942 if ( (NULL != pAdapter) &&
21943 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21944 {
21945 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021946 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21948 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021949 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021950 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021951 {
21952 /* Acquire wakelock to handle the case where APP's tries to
21953 * suspend immediately after updating the scan results. Whis
21954 * results in app's is in suspended state and not able to
21955 * process the connect request to AP
21956 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021957 hdd_prevent_suspend_timeout(2000,
21958 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021959 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021960 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021961
21962 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21963 "%s : cfg80211 scan result database updated", __func__);
21964
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021965 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021966 return 0;
21967
21968 }
21969 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21970 pAdapterNode = pNext;
21971 }
21972
21973 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21974 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021975 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021976 return 0;
21977}
21978
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021979int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21980{
21981 int ret;
21982
21983 vos_ssr_protect(__func__);
21984 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
21985 vos_ssr_unprotect(__func__);
21986
21987 return ret;
21988}
21989
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021990/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021991 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021992 * this is called when cfg80211 driver suspends
21993 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021994int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021995 struct cfg80211_wowlan *wow)
21996{
21997 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021998 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021999
22000 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022001
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022002 ret = wlan_hdd_validate_context(pHddCtx);
22003 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022004 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022005 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022006 }
22007
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053022008 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053022009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22010 "%s: Suspend SoftAP", __func__);
22011 hdd_set_wlan_suspend_mode(true);
22012 }
22013
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022014
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022015 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
22016 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
22017 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022018 pHddCtx->isWiphySuspended = TRUE;
22019
22020 EXIT();
22021
22022 return 0;
22023}
22024
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022025int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
22026 struct cfg80211_wowlan *wow)
22027{
22028 int ret;
22029
22030 vos_ssr_protect(__func__);
22031 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
22032 vos_ssr_unprotect(__func__);
22033
22034 return ret;
22035}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022036
22037#ifdef FEATURE_OEM_DATA_SUPPORT
22038static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022039 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022040{
22041 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22042
22043 ENTER();
22044
22045 if (wlan_hdd_validate_context(pHddCtx)) {
22046 return;
22047 }
22048 if (!pMsg)
22049 {
22050 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
22051 return;
22052 }
22053
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022054 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022055
22056 EXIT();
22057 return;
22058
22059}
22060
22061void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022062 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022063{
22064 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22065
22066 ENTER();
22067
22068 if (wlan_hdd_validate_context(pHddCtx)) {
22069 return;
22070 }
22071
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022072 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022073
22074 switch(evType) {
22075 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022076 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022077 break;
22078 default:
22079 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
22080 break;
22081 }
22082 EXIT();
22083}
22084#endif
22085
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022086#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22087 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022088/**
22089 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
22090 * @wiphy: Pointer to wiphy
22091 * @wdev: Pointer to wireless device structure
22092 *
22093 * This function is used to abort an ongoing scan
22094 *
22095 * Return: None
22096 */
22097static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22098 struct wireless_dev *wdev)
22099{
22100 struct net_device *dev = wdev->netdev;
22101 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22102 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
22103 int ret;
22104
22105 ENTER();
22106
22107 if (NULL == adapter) {
22108 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
22109 return;
22110 }
22111
22112 ret = wlan_hdd_validate_context(hdd_ctx);
22113 if (0 != ret)
22114 return;
22115
22116 wlan_hdd_scan_abort(adapter);
22117
22118 return;
22119}
22120
22121/**
22122 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
22123 * @wiphy: Pointer to wiphy
22124 * @wdev: Pointer to wireless device structure
22125 *
22126 * Return: None
22127 */
22128void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22129 struct wireless_dev *wdev)
22130{
22131 vos_ssr_protect(__func__);
22132 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
22133 vos_ssr_unprotect(__func__);
22134
22135 return;
22136}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022137#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022138
Abhishek Singh936c6932017-11-07 17:28:23 +053022139#ifdef CHANNEL_SWITCH_SUPPORTED
22140/**
22141 * __wlan_hdd_cfg80211_channel_switch()- function to switch
22142 * channel in SAP/GO
22143 * @wiphy: wiphy pointer
22144 * @dev: dev pointer.
22145 * @csa_params: Change channel params
22146 *
22147 * This function is called to switch channel in SAP/GO
22148 *
22149 * Return: 0 if success else return non zero
22150 */
22151static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22152 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22153{
22154 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22155 hdd_context_t *hdd_ctx;
22156 uint8_t channel;
22157 int ret;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022158 ptSapContext sap_ctx;
Abhishek Singh936c6932017-11-07 17:28:23 +053022159 v_CONTEXT_t vos_ctx;
22160
22161 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
22162
22163 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
22164 ret = wlan_hdd_validate_context(hdd_ctx);
22165 if (ret)
22166 return ret;
22167
22168 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
22169 if (!vos_ctx) {
22170 hddLog(LOGE, FL("Vos ctx is null"));
22171 return -EINVAL;
22172 }
22173
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022174 if (WLAN_HDD_SOFTAP != adapter->device_mode)
Abhishek Singh936c6932017-11-07 17:28:23 +053022175 return -ENOTSUPP;
22176
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022177 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
22178 if (!sap_ctx) {
22179 hddLog(LOGE, FL("sap_ctx is NULL"));
22180 return -EINVAL;
22181 }
22182
22183 ret = wlansap_chk_n_set_chan_change_in_progress(sap_ctx);
22184 if (ret)
22185 return ret;
22186
22187 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
22188
Abhishek Singh936c6932017-11-07 17:28:23 +053022189 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053022190 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053022191
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022192 if (ret) {
22193 wlansap_reset_chan_change_in_progress(sap_ctx);
22194 complete(&sap_ctx->ecsa_info.chan_switch_comp);
22195 }
22196
Abhishek Singh936c6932017-11-07 17:28:23 +053022197 return ret;
22198}
22199
22200/**
22201 * wlan_hdd_cfg80211_channel_switch()- function to switch
22202 * channel in SAP/GO
22203 * @wiphy: wiphy pointer
22204 * @dev: dev pointer.
22205 * @csa_params: Change channel params
22206 *
22207 * This function is called to switch channel in SAP/GO
22208 *
22209 * Return: 0 if success else return non zero
22210 */
22211static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22212 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22213{
22214 int ret;
22215
22216 vos_ssr_protect(__func__);
22217 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
22218 vos_ssr_unprotect(__func__);
22219
22220 return ret;
22221}
22222#endif
22223
Jeff Johnson295189b2012-06-20 16:38:30 -070022224/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053022225static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070022226{
22227 .add_virtual_intf = wlan_hdd_add_virtual_intf,
22228 .del_virtual_intf = wlan_hdd_del_virtual_intf,
22229 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
22230 .change_station = wlan_hdd_change_station,
22231#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
22232 .add_beacon = wlan_hdd_cfg80211_add_beacon,
22233 .del_beacon = wlan_hdd_cfg80211_del_beacon,
22234 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022235#else
22236 .start_ap = wlan_hdd_cfg80211_start_ap,
22237 .change_beacon = wlan_hdd_cfg80211_change_beacon,
22238 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070022239#endif
22240 .change_bss = wlan_hdd_cfg80211_change_bss,
22241 .add_key = wlan_hdd_cfg80211_add_key,
22242 .get_key = wlan_hdd_cfg80211_get_key,
22243 .del_key = wlan_hdd_cfg80211_del_key,
22244 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022245#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070022246 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022247#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022248 .scan = wlan_hdd_cfg80211_scan,
22249 .connect = wlan_hdd_cfg80211_connect,
22250 .disconnect = wlan_hdd_cfg80211_disconnect,
22251 .join_ibss = wlan_hdd_cfg80211_join_ibss,
22252 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
22253 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
22254 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
22255 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070022256 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
22257 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053022258 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070022259#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
22260 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
22261 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
22262 .set_txq_params = wlan_hdd_set_txq_params,
22263#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022264 .get_station = wlan_hdd_cfg80211_get_station,
22265 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
22266 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022267 .add_station = wlan_hdd_cfg80211_add_station,
22268#ifdef FEATURE_WLAN_LFR
22269 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
22270 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
22271 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
22272#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070022273#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
22274 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
22275#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080022276#ifdef FEATURE_WLAN_TDLS
22277 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
22278 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
22279#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053022280#ifdef WLAN_FEATURE_GTK_OFFLOAD
22281 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
22282#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053022283#ifdef FEATURE_WLAN_SCAN_PNO
22284 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
22285 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
22286#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022287 .resume = wlan_hdd_cfg80211_resume_wlan,
22288 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053022289 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070022290#ifdef WLAN_NL80211_TESTMODE
22291 .testmode_cmd = wlan_hdd_cfg80211_testmode,
22292#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022293 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022294#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22295 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022296 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022297#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053022298#ifdef CHANNEL_SWITCH_SUPPORTED
22299 .channel_switch = wlan_hdd_cfg80211_channel_switch,
22300#endif
22301
Jeff Johnson295189b2012-06-20 16:38:30 -070022302};
22303