blob: c7b3e2e495f4d236591785f3b20709478c750a5f [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
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307822#define PARAM_FORCE_RSN_IE \
7823 QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307824/*
7825 * hdd_set_qpower() - Process the qpower command and invoke the SME api
7826 * @hdd_ctx: hdd context
7827 * @enable: Value received in the command, 1 for disable and 2 for enable
7828 *
7829 * Return: void
7830 */
7831static void hdd_set_qpower(hdd_context_t *hdd_ctx, uint8_t enable)
7832{
7833 if (!hdd_ctx) {
7834 hddLog(LOGE, "hdd_ctx NULL");
7835 return;
7836 }
7837
7838 sme_set_qpower(hdd_ctx->hHal, enable);
7839}
7840
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307841/**
7842 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7843 * vendor command
7844 *
7845 * @wiphy: wiphy device pointer
7846 * @wdev: wireless device pointer
7847 * @data: Vendor command data buffer
7848 * @data_len: Buffer length
7849 *
7850 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7851 *
7852 * Return: EOK or other error codes.
7853 */
7854
7855static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7856 struct wireless_dev *wdev,
7857 const void *data,
7858 int data_len)
7859{
7860 struct net_device *dev = wdev->netdev;
7861 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7862 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7863 hdd_station_ctx_t *pHddStaCtx;
7864 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7865 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307866 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307867 eHalStatus status;
7868 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307869 uint8_t hb_thresh_val;
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307870 uint8_t qpower;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307871
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307872 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7873 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7874 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307875 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7876 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7877 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307878 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7879 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307880 [PARAM_FORCE_RSN_IE] = {.type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307881 };
7882
7883 ENTER();
7884
7885 if (VOS_FTM_MODE == hdd_get_conparam()) {
7886 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7887 return -EINVAL;
7888 }
7889
7890 ret_val = wlan_hdd_validate_context(pHddCtx);
7891 if (ret_val) {
7892 return ret_val;
7893 }
7894
7895 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7896
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307897 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7898 hddLog(LOGE, FL("Invalid ATTR"));
7899 return -EINVAL;
7900 }
7901
7902 /* check the Wifi Capability */
7903 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7904 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7905 {
7906 hddLog(VOS_TRACE_LEVEL_ERROR,
7907 FL("WIFICONFIG not supported by Firmware"));
7908 return -EINVAL;
7909 }
7910
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307911 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7912 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7913 modifyRoamParamsReq.value =
7914 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7915
7916 if (eHAL_STATUS_SUCCESS !=
7917 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7918 {
7919 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7920 ret_val = -EINVAL;
7921 }
7922 return ret_val;
7923 }
7924
7925 /* Moved this down in order to provide provision to set beacon
7926 * miss penalty count irrespective of connection state.
7927 */
7928 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7929 hddLog(LOGE, FL("Not in Connected state!"));
7930 return -ENOTSUPP;
7931 }
7932
7933 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307934
7935 if (!pReq) {
7936 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7937 "%s: Not able to allocate memory for tSetWifiConfigParams",
7938 __func__);
7939 return eHAL_STATUS_E_MALLOC_FAILED;
7940 }
7941
7942 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7943
7944 pReq->sessionId = pAdapter->sessionId;
7945 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7946
7947 if (tb[PARAM_MODULATED_DTIM]) {
7948 pReq->paramValue = nla_get_u32(
7949 tb[PARAM_MODULATED_DTIM]);
7950 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7951 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307952 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307953 hdd_set_pwrparams(pHddCtx);
7954 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7955 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7956
7957 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7958 iw_full_power_cbfn, pAdapter,
7959 eSME_FULL_PWR_NEEDED_BY_HDD);
7960 }
7961 else
7962 {
7963 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7964 }
7965 }
7966
7967 if (tb[PARAM_STATS_AVG_FACTOR]) {
7968 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7969 pReq->paramValue = nla_get_u16(
7970 tb[PARAM_STATS_AVG_FACTOR]);
7971 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7972 pReq->paramType, pReq->paramValue);
7973 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7974
7975 if (eHAL_STATUS_SUCCESS != status)
7976 {
7977 vos_mem_free(pReq);
7978 pReq = NULL;
7979 ret_val = -EPERM;
7980 return ret_val;
7981 }
7982 }
7983
7984
7985 if (tb[PARAM_GUARD_TIME]) {
7986 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7987 pReq->paramValue = nla_get_u32(
7988 tb[PARAM_GUARD_TIME]);
7989 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7990 pReq->paramType, pReq->paramValue);
7991 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7992
7993 if (eHAL_STATUS_SUCCESS != status)
7994 {
7995 vos_mem_free(pReq);
7996 pReq = NULL;
7997 ret_val = -EPERM;
7998 return ret_val;
7999 }
8000
8001 }
8002
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05308003 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
8004 hb_thresh_val = nla_get_u8(
8005 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
8006
8007 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
8008 hb_thresh_val);
8009 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
8010 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
8011 NULL, eANI_BOOLEAN_FALSE);
8012
8013 status = sme_update_hb_threshold(
8014 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
8015 WNI_CFG_HEART_BEAT_THRESHOLD,
8016 hb_thresh_val, eCSR_BAND_24);
8017 if (eHAL_STATUS_SUCCESS != status) {
8018 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
8019 vos_mem_free(pReq);
8020 pReq = NULL;
8021 return -EPERM;
8022 }
8023 }
8024
8025 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
8026 hb_thresh_val = nla_get_u8(
8027 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
8028
8029 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
8030 hb_thresh_val);
8031 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
8032 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
8033 NULL, eANI_BOOLEAN_FALSE);
8034
8035 status = sme_update_hb_threshold(
8036 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
8037 WNI_CFG_HEART_BEAT_THRESHOLD,
8038 hb_thresh_val, eCSR_BAND_5G);
8039 if (eHAL_STATUS_SUCCESS != status) {
8040 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
8041 vos_mem_free(pReq);
8042 pReq = NULL;
8043 return -EPERM;
8044 }
8045 }
8046
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05308047 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]) {
8048 qpower = nla_get_u8(
8049 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]);
8050
8051 if(qpower > 1) {
8052 hddLog(LOGE, "Invalid QPOWER value %d", qpower);
8053 vos_mem_free(pReq);
8054 pReq = NULL;
8055 return -EINVAL;
8056 }
8057 /* FW is expacting qpower as 1 for Disable and 2 for enable */
8058 qpower++;
8059 hdd_set_qpower(pHddCtx, qpower);
8060 }
8061
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05308062 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE] &&
8063 pHddCtx->cfg_ini->force_rsne_override) {
8064 uint8_t force_rsne_override;
8065
8066 force_rsne_override =
8067 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE]);
8068 if (force_rsne_override > 1) {
8069 hddLog(LOGE, "Invalid test_mode %d", force_rsne_override);
8070 ret_val = -EINVAL;
8071 }
8072 pHddCtx->force_rsne_override = force_rsne_override;
8073 hddLog(LOG1, "force_rsne_override - %d",
8074 pHddCtx->force_rsne_override);
8075 }
8076
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308077 EXIT();
8078 return ret_val;
8079}
8080
8081/**
8082 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
8083 * vendor command
8084 *
8085 * @wiphy: wiphy device pointer
8086 * @wdev: wireless device pointer
8087 * @data: Vendor command data buffer
8088 * @data_len: Buffer length
8089 *
8090 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
8091 *
8092 * Return: EOK or other error codes.
8093 */
8094static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
8095 struct wireless_dev *wdev,
8096 const void *data,
8097 int data_len)
8098{
8099 int ret;
8100
8101 vos_ssr_protect(__func__);
8102 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
8103 data, data_len);
8104 vos_ssr_unprotect(__func__);
8105
8106 return ret;
8107}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308108
8109/*
8110 * define short names for the global vendor params
8111 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8112 */
8113#define STATS_SET_INVALID \
8114 QCA_ATTR_NUD_STATS_SET_INVALID
8115#define STATS_SET_START \
8116 QCA_ATTR_NUD_STATS_SET_START
8117#define STATS_GW_IPV4 \
8118 QCA_ATTR_NUD_STATS_GW_IPV4
8119#define STATS_SET_MAX \
8120 QCA_ATTR_NUD_STATS_SET_MAX
8121
8122const struct nla_policy
8123qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
8124{
8125 [STATS_SET_START] = {.type = NLA_FLAG },
8126 [STATS_GW_IPV4] = {.type = NLA_U32 },
8127};
8128
8129/**
8130 * hdd_set_nud_stats_cb() - hdd callback api to get status
8131 * @data: pointer to adapter
8132 * @rsp: status
8133 *
8134 * Return: None
8135 */
8136static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
8137{
8138
8139 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8140
8141 if (NULL == adapter)
8142 return;
8143
8144 if (VOS_STATUS_SUCCESS == rsp) {
8145 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8146 "%s success received STATS_SET_START", __func__);
8147 } else {
8148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8149 "%s STATS_SET_START Failed!!", __func__);
8150 }
8151 return;
8152}
8153
8154/**
8155 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8156 * @wiphy: pointer to wireless wiphy structure.
8157 * @wdev: pointer to wireless_dev structure.
8158 * @data: pointer to apfind configuration data.
8159 * @data_len: the length in byte of apfind data.
8160 *
8161 * This is called when wlan driver needs to send arp stats to
8162 * firmware.
8163 *
8164 * Return: An error code or 0 on success.
8165 */
8166static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8167 struct wireless_dev *wdev,
8168 const void *data, int data_len)
8169{
8170 struct nlattr *tb[STATS_SET_MAX + 1];
8171 struct net_device *dev = wdev->netdev;
8172 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8173 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308174 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308175 setArpStatsParams arp_stats_params;
8176 int err = 0;
8177
8178 ENTER();
8179
8180 err = wlan_hdd_validate_context(hdd_ctx);
8181 if (0 != err)
8182 return err;
8183
8184 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8186 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8187 return -EINVAL;
8188 }
8189
8190 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8191 qca_wlan_vendor_set_nud_stats);
8192 if (err)
8193 {
8194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8195 "%s STATS_SET_START ATTR", __func__);
8196 return err;
8197 }
8198
8199 if (tb[STATS_SET_START])
8200 {
8201 if (!tb[STATS_GW_IPV4]) {
8202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8203 "%s STATS_SET_START CMD", __func__);
8204 return -EINVAL;
8205 }
8206 arp_stats_params.flag = true;
8207 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8208 } else {
8209 arp_stats_params.flag = false;
8210 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308211 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8213 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308214 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8215 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308216
8217 arp_stats_params.pkt_type = 1; // ARP packet type
8218
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308219 if (arp_stats_params.flag) {
8220 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8221 WLANTL_SetARPFWDatapath(pVosContext, true);
8222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8223 "%s Set FW in data path for ARP with tgt IP :%d",
8224 __func__, hdd_ctx->track_arp_ip);
8225 }
8226 else {
8227 WLANTL_SetARPFWDatapath(pVosContext, false);
8228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8229 "%s Remove FW from data path", __func__);
8230 }
8231
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308232 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8233 arp_stats_params.data_ctx = adapter;
8234
8235 if (eHAL_STATUS_SUCCESS !=
8236 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8238 "%s STATS_SET_START CMD Failed!!", __func__);
8239 return -EINVAL;
8240 }
8241
8242 EXIT();
8243
8244 return err;
8245}
8246
8247/**
8248 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8249 * @wiphy: pointer to wireless wiphy structure.
8250 * @wdev: pointer to wireless_dev structure.
8251 * @data: pointer to apfind configuration data.
8252 * @data_len: the length in byte of apfind data.
8253 *
8254 * This is called when wlan driver needs to send arp stats to
8255 * firmware.
8256 *
8257 * Return: An error code or 0 on success.
8258 */
8259static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8260 struct wireless_dev *wdev,
8261 const void *data, int data_len)
8262{
8263 int ret;
8264
8265 vos_ssr_protect(__func__);
8266 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8267 vos_ssr_unprotect(__func__);
8268
8269 return ret;
8270}
8271#undef STATS_SET_INVALID
8272#undef STATS_SET_START
8273#undef STATS_GW_IPV4
8274#undef STATS_SET_MAX
8275
8276/*
8277 * define short names for the global vendor params
8278 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8279 */
8280#define STATS_GET_INVALID \
8281 QCA_ATTR_NUD_STATS_SET_INVALID
8282#define COUNT_FROM_NETDEV \
8283 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8284#define COUNT_TO_LOWER_MAC \
8285 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8286#define RX_COUNT_BY_LOWER_MAC \
8287 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8288#define COUNT_TX_SUCCESS \
8289 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8290#define RSP_RX_COUNT_BY_LOWER_MAC \
8291 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8292#define RSP_RX_COUNT_BY_UPPER_MAC \
8293 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8294#define RSP_COUNT_TO_NETDEV \
8295 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8296#define RSP_COUNT_OUT_OF_ORDER_DROP \
8297 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8298#define AP_LINK_ACTIVE \
8299 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8300#define AP_LINK_DAD \
8301 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8302#define STATS_GET_MAX \
8303 QCA_ATTR_NUD_STATS_GET_MAX
8304
8305const struct nla_policy
8306qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8307{
8308 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8309 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8310 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8311 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8312 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8313 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8314 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8315 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8316 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8317 [AP_LINK_DAD] = {.type = NLA_FLAG },
8318};
8319
8320static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8321{
8322
8323 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308324 hdd_context_t *hdd_ctx;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308325 struct hdd_nud_stats_context *context;
8326 int status;
8327
8328 ENTER();
8329
8330 if (NULL == adapter)
8331 return;
8332
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308333 if (!rsp) {
8334 hddLog(LOGE, FL("data is null"));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308335 return;
8336 }
8337
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308338 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8339 status = wlan_hdd_validate_context(hdd_ctx);
8340 if (0 != status) {
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308341 return;
8342 }
8343
8344 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8345 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8346 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8347 adapter->dad |= rsp->dad;
8348
8349 spin_lock(&hdd_context_lock);
8350 context = &hdd_ctx->nud_stats_context;
8351 complete(&context->response_event);
8352 spin_unlock(&hdd_context_lock);
8353
8354 return;
8355}
8356static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8357 struct wireless_dev *wdev,
8358 const void *data, int data_len)
8359{
8360 int err = 0;
8361 unsigned long rc;
8362 struct hdd_nud_stats_context *context;
8363 struct net_device *dev = wdev->netdev;
8364 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8365 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8366 getArpStatsParams arp_stats_params;
8367 struct sk_buff *skb;
8368
8369 ENTER();
8370
8371 err = wlan_hdd_validate_context(hdd_ctx);
8372 if (0 != err)
8373 return err;
8374
8375 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8376 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8377 arp_stats_params.data_ctx = adapter;
8378
8379 spin_lock(&hdd_context_lock);
8380 context = &hdd_ctx->nud_stats_context;
8381 INIT_COMPLETION(context->response_event);
8382 spin_unlock(&hdd_context_lock);
8383
8384 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8386 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8387 return -EINVAL;
8388 }
8389
8390 if (eHAL_STATUS_SUCCESS !=
8391 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8393 "%s STATS_SET_START CMD Failed!!", __func__);
8394 return -EINVAL;
8395 }
8396
8397 rc = wait_for_completion_timeout(&context->response_event,
8398 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8399 if (!rc)
8400 {
8401 hddLog(LOGE,
8402 FL("Target response timed out request "));
8403 return -ETIMEDOUT;
8404 }
8405
8406 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8407 WLAN_NUD_STATS_LEN);
8408 if (!skb)
8409 {
8410 hddLog(VOS_TRACE_LEVEL_ERROR,
8411 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8412 __func__);
8413 return -ENOMEM;
8414 }
8415
8416 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8417 adapter->hdd_stats.hddArpStats.txCount) ||
8418 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8419 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8420 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8421 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8422 nla_put_u16(skb, COUNT_TX_SUCCESS,
8423 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8424 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8425 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8426 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8427 adapter->hdd_stats.hddArpStats.rxCount) ||
8428 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8429 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8430 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8431 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8432 hddLog(LOGE, FL("nla put fail"));
8433 kfree_skb(skb);
8434 return -EINVAL;
8435 }
8436 if (adapter->con_status)
8437 nla_put_flag(skb, AP_LINK_ACTIVE);
8438 if (adapter->dad)
8439 nla_put_flag(skb, AP_LINK_DAD);
8440
8441 cfg80211_vendor_cmd_reply(skb);
8442 return err;
8443}
8444
8445static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8446 struct wireless_dev *wdev,
8447 const void *data, int data_len)
8448{
8449 int ret;
8450
8451 vos_ssr_protect(__func__);
8452 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8453 vos_ssr_unprotect(__func__);
8454
8455 return ret;
8456}
8457
8458#undef QCA_ATTR_NUD_STATS_SET_INVALID
8459#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8460#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8461#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8462#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8463#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8464#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8465#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8466#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8467#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8468#undef QCA_ATTR_NUD_STATS_GET_MAX
8469
8470
8471
Kapil Guptaee33bf12016-12-20 18:27:37 +05308472#ifdef WLAN_FEATURE_APFIND
8473/**
8474 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8475 * @wiphy: pointer to wireless wiphy structure.
8476 * @wdev: pointer to wireless_dev structure.
8477 * @data: pointer to apfind configuration data.
8478 * @data_len: the length in byte of apfind data.
8479 *
8480 * This is called when wlan driver needs to send APFIND configurations to
8481 * firmware.
8482 *
8483 * Return: An error code or 0 on success.
8484 */
8485static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8486 struct wireless_dev *wdev,
8487 const void *data, int data_len)
8488{
8489 struct sme_ap_find_request_req apfind_req;
8490 VOS_STATUS status;
8491 int ret_val;
8492 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8493
8494 ENTER();
8495
8496 ret_val = wlan_hdd_validate_context(hdd_ctx);
8497 if (ret_val)
8498 return ret_val;
8499
8500 if (VOS_FTM_MODE == hdd_get_conparam()) {
8501 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8502 return -EPERM;
8503 }
8504
8505 apfind_req.request_data_len = data_len;
8506 apfind_req.request_data = data;
8507
8508 status = sme_apfind_set_cmd(&apfind_req);
8509 if (VOS_STATUS_SUCCESS != status) {
8510 ret_val = -EIO;
8511 }
8512 return ret_val;
8513}
8514
8515/**
8516 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8517 * @wiphy: pointer to wireless wiphy structure.
8518 * @wdev: pointer to wireless_dev structure.
8519 * @data: pointer to apfind configuration data.
8520 * @data_len: the length in byte of apfind data.
8521 *
8522 * This is called when wlan driver needs to send APFIND configurations to
8523 * firmware.
8524 *
8525 * Return: An error code or 0 on success.
8526 */
8527static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8528 struct wireless_dev *wdev,
8529 const void *data, int data_len)
8530{
8531 int ret;
8532
8533 vos_ssr_protect(__func__);
8534 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8535 vos_ssr_unprotect(__func__);
8536
8537 return ret;
8538}
8539#endif /* WLAN_FEATURE_APFIND */
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308540
8541/**
8542 * __wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8543 * @wiphy: pointer to wireless wiphy structure.
8544 * @wdev: pointer to wireless_dev structure.
8545 * @data: Pointer to the data to be passed via vendor interface
8546 * @data_len:Length of the data to be passed
8547 *
8548 * This is called by userspace to know the supported logger features
8549 *
8550 * Return: Return the Success or Failure code.
8551 */
8552static int
8553__wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8554 struct wireless_dev *wdev,
8555 const void *data, int data_len)
8556{
8557 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8558 int status;
8559 uint32_t features;
8560 struct sk_buff *reply_skb = NULL;
8561
8562 if (VOS_FTM_MODE == hdd_get_conparam()) {
8563 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8564 return -EINVAL;
8565 }
8566
8567 status = wlan_hdd_validate_context(hdd_ctx);
8568 if (0 != status)
8569 return -EINVAL;
8570
8571 features = 0;
8572
8573 if (hdd_is_memdump_supported())
8574 features |= WIFI_LOGGER_MEMORY_DUMP_SUPPORTED;
8575
8576 if (hdd_ctx->cfg_ini->wlanLoggingEnable &&
8577 hdd_ctx->cfg_ini->enableFatalEvent &&
8578 hdd_ctx->is_fatal_event_log_sup) {
8579 features |= WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED;
8580 features |= WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
8581 }
8582
8583 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8584 sizeof(uint32_t) + NLA_HDRLEN + NLMSG_HDRLEN);
8585 if (!reply_skb) {
8586 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
8587 return -ENOMEM;
8588 }
8589
8590 hddLog(LOG1, FL("Supported logger features: 0x%0x"), features);
8591 if (nla_put_u32(reply_skb, QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED,
8592 features)) {
8593 hddLog(LOGE, FL("nla put fail"));
8594 kfree_skb(reply_skb);
8595 return -EINVAL;
8596 }
8597
8598 return cfg80211_vendor_cmd_reply(reply_skb);
8599}
8600
8601/**
8602 * wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8603 * @wiphy: pointer to wireless wiphy structure.
8604 * @wdev: pointer to wireless_dev structure.
8605 * @data: Pointer to the data to be passed via vendor interface
8606 * @data_len:Length of the data to be passed
8607 *
8608 * This is called by userspace to know the supported logger features
8609 *
8610 * Return: Return the Success or Failure code.
8611 */
8612static int
8613wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8614 struct wireless_dev *wdev,
8615 const void *data, int data_len)
8616{
8617 int ret;
8618
8619 vos_ssr_protect(__func__);
8620 ret = __wlan_hdd_cfg80211_get_logger_supp_feature(wiphy, wdev,
8621 data, data_len);
8622 vos_ssr_unprotect(__func__);
8623
8624 return ret;
8625}
8626
Sunil Duttc69bccb2014-05-26 21:30:20 +05308627const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8628{
Mukul Sharma2a271632014-10-13 14:59:01 +05308629 {
8630 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8631 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8632 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8633 WIPHY_VENDOR_CMD_NEED_NETDEV |
8634 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308635 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308636 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308637
8638 {
8639 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8640 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8641 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8642 WIPHY_VENDOR_CMD_NEED_NETDEV |
8643 WIPHY_VENDOR_CMD_NEED_RUNNING,
8644 .doit = wlan_hdd_cfg80211_nan_request
8645 },
8646
Sunil Duttc69bccb2014-05-26 21:30:20 +05308647#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8648 {
8649 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8650 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8651 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8652 WIPHY_VENDOR_CMD_NEED_NETDEV |
8653 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308654 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308655 },
8656
8657 {
8658 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8659 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8660 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8661 WIPHY_VENDOR_CMD_NEED_NETDEV |
8662 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308663 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308664 },
8665
8666 {
8667 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8668 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8669 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8670 WIPHY_VENDOR_CMD_NEED_NETDEV |
8671 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308672 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308673 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308674#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308675#ifdef WLAN_FEATURE_EXTSCAN
8676 {
8677 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8678 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8679 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8680 WIPHY_VENDOR_CMD_NEED_NETDEV |
8681 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308682 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308683 },
8684 {
8685 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8686 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8687 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8688 WIPHY_VENDOR_CMD_NEED_NETDEV |
8689 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308690 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308691 },
8692 {
8693 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8694 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8695 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8696 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308697 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308698 },
8699 {
8700 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8701 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8702 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8703 WIPHY_VENDOR_CMD_NEED_NETDEV |
8704 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308705 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308706 },
8707 {
8708 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8709 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8710 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8711 WIPHY_VENDOR_CMD_NEED_NETDEV |
8712 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308713 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308714 },
8715 {
8716 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8717 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8718 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8719 WIPHY_VENDOR_CMD_NEED_NETDEV |
8720 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308721 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308722 },
8723 {
8724 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8725 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8726 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8727 WIPHY_VENDOR_CMD_NEED_NETDEV |
8728 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308729 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308730 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308731#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308732/*EXT TDLS*/
8733 {
8734 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8735 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8736 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8737 WIPHY_VENDOR_CMD_NEED_NETDEV |
8738 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308739 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308740 },
8741 {
8742 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8743 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8744 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8745 WIPHY_VENDOR_CMD_NEED_NETDEV |
8746 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308747 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308748 },
8749 {
8750 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8751 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8752 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8753 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308754 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308755 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308756 {
8757 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8758 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8759 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8760 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308761 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308762 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308763 {
8764 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8765 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8766 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8767 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308768 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308769 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308770 {
8771 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8772 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8773 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8774 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308775 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308776 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308777 {
8778 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8779 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8780 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8781 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308782 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308783 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308784 {
8785 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308786 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8787 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8788 WIPHY_VENDOR_CMD_NEED_NETDEV |
8789 WIPHY_VENDOR_CMD_NEED_RUNNING,
8790 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8791 },
8792 {
8793 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308794 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8795 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8796 WIPHY_VENDOR_CMD_NEED_NETDEV |
8797 WIPHY_VENDOR_CMD_NEED_RUNNING,
8798 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308799 },
8800 {
8801 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8802 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8803 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8804 WIPHY_VENDOR_CMD_NEED_NETDEV,
8805 .doit = wlan_hdd_cfg80211_wifi_logger_start
8806 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308807 {
8808 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8809 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8810 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8811 WIPHY_VENDOR_CMD_NEED_NETDEV|
8812 WIPHY_VENDOR_CMD_NEED_RUNNING,
8813 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308814 },
8815 {
8816 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8817 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8818 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8819 WIPHY_VENDOR_CMD_NEED_NETDEV |
8820 WIPHY_VENDOR_CMD_NEED_RUNNING,
8821 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308822 },
8823 {
8824 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8825 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8826 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8827 WIPHY_VENDOR_CMD_NEED_NETDEV |
8828 WIPHY_VENDOR_CMD_NEED_RUNNING,
8829 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308830 },
8831#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8832 {
8833 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8834 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8835 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8836 WIPHY_VENDOR_CMD_NEED_NETDEV |
8837 WIPHY_VENDOR_CMD_NEED_RUNNING,
8838 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308839 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308840#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308841 {
8842 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8843 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8844 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8845 WIPHY_VENDOR_CMD_NEED_NETDEV |
8846 WIPHY_VENDOR_CMD_NEED_RUNNING,
8847 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308848 },
8849 {
8850 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8851 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8852 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8853 WIPHY_VENDOR_CMD_NEED_NETDEV |
8854 WIPHY_VENDOR_CMD_NEED_RUNNING,
8855 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308856 },
8857#ifdef WLAN_FEATURE_APFIND
8858 {
8859 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8860 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8861 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8862 WIPHY_VENDOR_CMD_NEED_NETDEV,
8863 .doit = wlan_hdd_cfg80211_apfind_cmd
8864 },
8865#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308866 {
8867 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8868 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8869 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8870 WIPHY_VENDOR_CMD_NEED_NETDEV |
8871 WIPHY_VENDOR_CMD_NEED_RUNNING,
8872 .doit = wlan_hdd_cfg80211_set_nud_stats
8873 },
8874 {
8875 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8876 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8877 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8878 WIPHY_VENDOR_CMD_NEED_NETDEV |
8879 WIPHY_VENDOR_CMD_NEED_RUNNING,
8880 .doit = wlan_hdd_cfg80211_get_nud_stats
8881 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308882 {
8883 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8884 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8885 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8886 WIPHY_VENDOR_CMD_NEED_NETDEV |
8887 WIPHY_VENDOR_CMD_NEED_RUNNING,
8888 .doit = hdd_cfg80211_get_station_cmd
8889 },
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308890 {
8891 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8892 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET,
8893 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
Hanumanth Reddy Pothula07c95582018-05-23 12:41:22 +05308894 WIPHY_VENDOR_CMD_NEED_NETDEV,
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308895 .doit = wlan_hdd_cfg80211_get_logger_supp_feature
8896 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308897};
8898
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008899/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308900static const
8901struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008902{
8903#ifdef FEATURE_WLAN_CH_AVOID
8904 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308905 .vendor_id = QCA_NL80211_VENDOR_ID,
8906 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008907 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308908#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8909#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8910 {
8911 /* Index = 1*/
8912 .vendor_id = QCA_NL80211_VENDOR_ID,
8913 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8914 },
8915 {
8916 /* Index = 2*/
8917 .vendor_id = QCA_NL80211_VENDOR_ID,
8918 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8919 },
8920 {
8921 /* Index = 3*/
8922 .vendor_id = QCA_NL80211_VENDOR_ID,
8923 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8924 },
8925 {
8926 /* Index = 4*/
8927 .vendor_id = QCA_NL80211_VENDOR_ID,
8928 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8929 },
8930 {
8931 /* Index = 5*/
8932 .vendor_id = QCA_NL80211_VENDOR_ID,
8933 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8934 },
8935 {
8936 /* Index = 6*/
8937 .vendor_id = QCA_NL80211_VENDOR_ID,
8938 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8939 },
8940#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308941#ifdef WLAN_FEATURE_EXTSCAN
8942 {
8943 .vendor_id = QCA_NL80211_VENDOR_ID,
8944 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8945 },
8946 {
8947 .vendor_id = QCA_NL80211_VENDOR_ID,
8948 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8949 },
8950 {
8951 .vendor_id = QCA_NL80211_VENDOR_ID,
8952 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8953 },
8954 {
8955 .vendor_id = QCA_NL80211_VENDOR_ID,
8956 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8957 },
8958 {
8959 .vendor_id = QCA_NL80211_VENDOR_ID,
8960 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8961 },
8962 {
8963 .vendor_id = QCA_NL80211_VENDOR_ID,
8964 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8965 },
8966 {
8967 .vendor_id = QCA_NL80211_VENDOR_ID,
8968 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8969 },
8970 {
8971 .vendor_id = QCA_NL80211_VENDOR_ID,
8972 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8973 },
8974 {
8975 .vendor_id = QCA_NL80211_VENDOR_ID,
8976 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8977 },
8978 {
8979 .vendor_id = QCA_NL80211_VENDOR_ID,
8980 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8981 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308982#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308983/*EXT TDLS*/
8984 {
8985 .vendor_id = QCA_NL80211_VENDOR_ID,
8986 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8987 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308988 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8989 .vendor_id = QCA_NL80211_VENDOR_ID,
8990 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8991 },
8992
Srinivas Dasari030bad32015-02-18 23:23:54 +05308993
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308994 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308995 .vendor_id = QCA_NL80211_VENDOR_ID,
8996 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8997 },
8998
Sushant Kaushik084f6592015-09-10 13:11:56 +05308999 {
9000 .vendor_id = QCA_NL80211_VENDOR_ID,
9001 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05309002 },
9003 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
9004 .vendor_id = QCA_NL80211_VENDOR_ID,
9005 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
9006 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05309007 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
9008 .vendor_id = QCA_NL80211_VENDOR_ID,
9009 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
9010 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05309011 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
9012 .vendor_id = QCA_NL80211_VENDOR_ID,
9013 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
9014 },
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05309015 [QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
9016 .vendor_id = QCA_NL80211_VENDOR_ID,
9017 .subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
9018 },
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +05309019 [QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX] = {
9020 .vendor_id = QCA_NL80211_VENDOR_ID,
9021 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
9022 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009023};
9024
Jeff Johnson295189b2012-06-20 16:38:30 -07009025/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309026 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309027 * This function is called by hdd_wlan_startup()
9028 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309029 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07009030 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309031struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07009032{
9033 struct wiphy *wiphy;
9034 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309035 /*
9036 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07009037 */
9038 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
9039
9040 if (!wiphy)
9041 {
9042 /* Print error and jump into err label and free the memory */
9043 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
9044 return NULL;
9045 }
9046
Sunil Duttc69bccb2014-05-26 21:30:20 +05309047
Jeff Johnson295189b2012-06-20 16:38:30 -07009048 return wiphy;
9049}
9050
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309051#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
9052 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
9053/**
9054 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
9055 * @wiphy: pointer to wiphy
9056 * @config: pointer to config
9057 *
9058 * Return: None
9059 */
9060static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
9061 hdd_config_t *config)
9062{
9063 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
9064 if (config->max_sched_scan_plan_interval)
9065 wiphy->max_sched_scan_plan_interval =
9066 config->max_sched_scan_plan_interval;
9067 if (config->max_sched_scan_plan_iterations)
9068 wiphy->max_sched_scan_plan_iterations =
9069 config->max_sched_scan_plan_iterations;
9070}
9071#else
9072static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
9073 hdd_config_t *config)
9074{
9075}
9076#endif
9077
Jeff Johnson295189b2012-06-20 16:38:30 -07009078/*
9079 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309080 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07009081 * private ioctl to change the band value
9082 */
9083int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
9084{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309085 int i, j;
9086 eNVChannelEnabledType channelEnabledState;
9087
Jeff Johnsone7245742012-09-05 17:12:55 -07009088 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309089
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309090 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009091 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309092
9093 if (NULL == wiphy->bands[i])
9094 {
9095 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
9096 __func__, i);
9097 continue;
9098 }
9099
9100 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9101 {
9102 struct ieee80211_supported_band *band = wiphy->bands[i];
9103
9104 channelEnabledState = vos_nv_getChannelEnabledState(
9105 band->channels[j].hw_value);
9106
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309107 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309108 {
Abhishek Singh678227a2014-11-04 10:52:38 +05309109 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309110 continue;
9111 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309112 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309113 {
9114 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9115 continue;
9116 }
9117
9118 if (NV_CHANNEL_DISABLE == channelEnabledState ||
9119 NV_CHANNEL_INVALID == channelEnabledState)
9120 {
9121 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9122 }
9123 else if (NV_CHANNEL_DFS == channelEnabledState)
9124 {
9125 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9126 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
9127 }
9128 else
9129 {
9130 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
9131 |IEEE80211_CHAN_RADAR);
9132 }
9133 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009134 }
9135 return 0;
9136}
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309137
9138/**
9139 * hdd_add_channel_switch_support()- Adds Channel Switch flag if supported
9140 * @wiphy: Pointer to the wiphy.
9141 *
9142 * This Function adds Channel Switch support flag, if channel switch is
9143 * supported by kernel.
9144 * Return: void.
9145 */
9146#ifdef CHANNEL_SWITCH_SUPPORTED
9147static inline
9148void hdd_add_channel_switch_support(struct wiphy *wiphy)
9149{
9150 wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
9151 wiphy->max_num_csa_counters = WLAN_HDD_MAX_NUM_CSA_COUNTERS;
9152}
9153#else
9154static inline
9155void hdd_add_channel_switch_support(struct wiphy *wiphy)
9156{
9157}
9158#endif
9159
Jeff Johnson295189b2012-06-20 16:38:30 -07009160/*
9161 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309162 * This function is called by hdd_wlan_startup()
9163 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07009164 * This function is used to initialize and register wiphy structure.
9165 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309166int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009167 struct wiphy *wiphy,
9168 hdd_config_t *pCfg
9169 )
9170{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309171 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309172 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9173
Jeff Johnsone7245742012-09-05 17:12:55 -07009174 ENTER();
9175
Jeff Johnson295189b2012-06-20 16:38:30 -07009176 /* Now bind the underlying wlan device with wiphy */
9177 set_wiphy_dev(wiphy, dev);
9178
9179 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009180
Kiet Lam6c583332013-10-14 05:37:09 +05309181#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009182 /* the flag for the other case would be initialzed in
9183 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05309184#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9185 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
9186#else
Amar Singhal0a402232013-10-11 20:57:16 -07009187 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05309188#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05309189#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009190
Amar Singhalfddc28c2013-09-05 13:03:40 -07009191 /* This will disable updating of NL channels from passive to
9192 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309193#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9194 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
9195#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07009196 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309197#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07009198
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309199#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
9200 wiphy->wowlan = &wowlan_support_cfg80211_init;
9201#else
Nachiket Kukade1e1b90e2018-05-10 15:26:13 +05309202 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
9203 WIPHY_WOWLAN_MAGIC_PKT;
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309204 wiphy->wowlan.n_patterns = WOWL_MAX_PTRNS_ALLOWED;
9205 wiphy->wowlan.pattern_min_len = 1;
9206 wiphy->wowlan.pattern_max_len = WOWL_PTRN_MAX_SIZE;
9207#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009208
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009209#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009210 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
9211 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
9212 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07009213 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309214#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05309215 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309216#else
9217 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
9218#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009219#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009220
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009221#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009222 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08009223#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009224 || pCfg->isFastRoamIniFeatureEnabled
9225#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009226#ifdef FEATURE_WLAN_ESE
9227 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009228#endif
9229 )
9230 {
9231 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
9232 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08009233#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009234#ifdef FEATURE_WLAN_TDLS
9235 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
9236 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
9237#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309238#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05309239 if (pCfg->configPNOScanSupport)
9240 {
9241 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
9242 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
9243 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
9244 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
9245 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309246#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009247
Abhishek Singh10d85972015-04-17 10:27:23 +05309248#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9249 wiphy->features |= NL80211_FEATURE_HT_IBSS;
9250#endif
9251
Amar Singhalfddc28c2013-09-05 13:03:40 -07009252#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009253 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
9254 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07009255 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009256 driver need to determine what to do with both
9257 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07009258
9259 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07009260#else
9261 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009262#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009263
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309264 wiphy->max_scan_ssids = MAX_SCAN_SSID;
9265
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05309266 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07009267
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309268 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
9269
Jeff Johnson295189b2012-06-20 16:38:30 -07009270 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05309271 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
9272 | BIT(NL80211_IFTYPE_ADHOC)
9273 | BIT(NL80211_IFTYPE_P2P_CLIENT)
9274 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309275 | BIT(NL80211_IFTYPE_AP)
9276 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07009277
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309278 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009279 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309280#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9281 if( pCfg->enableMCC )
9282 {
9283 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309284 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009285
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309286 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309287 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009288
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309289 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309290 wiphy->iface_combinations = wlan_hdd_iface_combination;
9291 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009292#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309293 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009294
Jeff Johnson295189b2012-06-20 16:38:30 -07009295 /* Before registering we need to update the ht capabilitied based
9296 * on ini values*/
9297 if( !pCfg->ShortGI20MhzEnable )
9298 {
9299 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
9300 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07009301 }
9302
9303 if( !pCfg->ShortGI40MhzEnable )
9304 {
9305 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9306 }
9307
9308 if( !pCfg->nChannelBondingMode5GHz )
9309 {
9310 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9311 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309312 /*
9313 * In case of static linked driver at the time of driver unload,
9314 * module exit doesn't happens. Module cleanup helps in cleaning
9315 * of static memory.
9316 * If driver load happens statically, at the time of driver unload,
9317 * wiphy flags don't get reset because of static memory.
9318 * It's better not to store channel in static memory.
9319 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309320 wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9321 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309322 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309323 if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309324 {
9325 hddLog(VOS_TRACE_LEVEL_ERROR,
9326 FL("Not enough memory to allocate channels"));
9327 return -ENOMEM;
9328 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309329 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309330 &hdd_channels_2_4_GHZ[0],
9331 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009332
Agrawal Ashish97dec502015-11-26 20:20:58 +05309333 if (true == hdd_is_5g_supported(pHddCtx))
9334 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309335 wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9336 wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309337 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309338 if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309339 {
9340 hddLog(VOS_TRACE_LEVEL_ERROR,
9341 FL("Not enough memory to allocate channels"));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309342 vos_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
9343 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
Agrawal Ashish97dec502015-11-26 20:20:58 +05309344 return -ENOMEM;
9345 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309346 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309347 &hdd_channels_5_GHZ[0],
9348 sizeof(hdd_channels_5_GHZ));
9349 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309350
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309351 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309352 {
9353
9354 if (NULL == wiphy->bands[i])
9355 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309356 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309357 __func__, i);
9358 continue;
9359 }
9360
9361 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9362 {
9363 struct ieee80211_supported_band *band = wiphy->bands[i];
9364
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309365 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309366 {
9367 // Enable social channels for P2P
9368 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9369 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9370 else
9371 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9372 continue;
9373 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309374 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309375 {
9376 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9377 continue;
9378 }
9379 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009380 }
9381 /*Initialise the supported cipher suite details*/
9382 wiphy->cipher_suites = hdd_cipher_suites;
9383 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9384
9385 /*signal strength in mBm (100*dBm) */
9386 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9387
9388#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309389 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009390#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009391
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309392 hdd_add_channel_switch_support(wiphy);
Sunil Duttc69bccb2014-05-26 21:30:20 +05309393 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9394 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009395 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9396 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9397
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309398 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
9399
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309400 EXIT();
9401 return 0;
9402}
9403
9404/* In this function we are registering wiphy. */
9405int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9406{
9407 ENTER();
9408 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009409 if (0 > wiphy_register(wiphy))
9410 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309411 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009412 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9413 return -EIO;
9414 }
9415
9416 EXIT();
9417 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309418}
Jeff Johnson295189b2012-06-20 16:38:30 -07009419
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309420/* In this function we are updating channel list when,
9421 regulatory domain is FCC and country code is US.
9422 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9423 As per FCC smart phone is not a indoor device.
9424 GO should not opeate on indoor channels */
9425void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9426{
9427 int j;
9428 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9429 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9430 //Default counrtycode from NV at the time of wiphy initialization.
9431 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9432 &defaultCountryCode[0]))
9433 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009434 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309435 }
9436 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9437 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309438 if (NULL == wiphy->bands[HDD_NL80211_BAND_5GHZ])
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309439 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309440 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[HDD_NL80211_BAND_5GHZ] is NULL",__func__ );
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309441 return;
9442 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309443 for (j = 0; j < wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels; j++)
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309444 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309445 struct ieee80211_supported_band *band = wiphy->bands[HDD_NL80211_BAND_5GHZ];
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309446 // Mark UNII -1 band channel as passive
9447 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9448 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9449 }
9450 }
9451}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309452/* This function registers for all frame which supplicant is interested in */
9453void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009454{
Jeff Johnson295189b2012-06-20 16:38:30 -07009455 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9456 /* Register for all P2P action, public action etc frames */
9457 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009458 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309459 /* Register frame indication call back */
9460 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009461 /* Right now we are registering these frame when driver is getting
9462 initialized. Once we will move to 2.6.37 kernel, in which we have
9463 frame register ops, we will move this code as a part of that */
9464 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309465 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009466 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9467
9468 /* GAS Initial Response */
9469 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9470 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309471
Jeff Johnson295189b2012-06-20 16:38:30 -07009472 /* GAS Comeback Request */
9473 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9474 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9475
9476 /* GAS Comeback Response */
9477 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9478 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9479
9480 /* P2P Public Action */
9481 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309482 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009483 P2P_PUBLIC_ACTION_FRAME_SIZE );
9484
9485 /* P2P Action */
9486 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9487 (v_U8_t*)P2P_ACTION_FRAME,
9488 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009489
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309490 /* WNM BSS Transition Request frame */
9491 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9492 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9493 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009494
9495 /* WNM-Notification */
9496 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9497 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9498 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009499}
9500
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309501void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009502{
Jeff Johnson295189b2012-06-20 16:38:30 -07009503 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9504 /* Register for all P2P action, public action etc frames */
9505 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9506
Jeff Johnsone7245742012-09-05 17:12:55 -07009507 ENTER();
9508
Jeff Johnson295189b2012-06-20 16:38:30 -07009509 /* Right now we are registering these frame when driver is getting
9510 initialized. Once we will move to 2.6.37 kernel, in which we have
9511 frame register ops, we will move this code as a part of that */
9512 /* GAS Initial Request */
9513
9514 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9515 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9516
9517 /* GAS Initial Response */
9518 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9519 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309520
Jeff Johnson295189b2012-06-20 16:38:30 -07009521 /* GAS Comeback Request */
9522 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9523 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9524
9525 /* GAS Comeback Response */
9526 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9527 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9528
9529 /* P2P Public Action */
9530 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309531 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009532 P2P_PUBLIC_ACTION_FRAME_SIZE );
9533
9534 /* P2P Action */
9535 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9536 (v_U8_t*)P2P_ACTION_FRAME,
9537 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009538 /* WNM-Notification */
9539 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9540 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9541 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009542}
9543
9544#ifdef FEATURE_WLAN_WAPI
9545void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309546 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009547{
9548 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9549 tCsrRoamSetKey setKey;
9550 v_BOOL_t isConnected = TRUE;
9551 int status = 0;
9552 v_U32_t roamId= 0xFF;
9553 tANI_U8 *pKeyPtr = NULL;
9554 int n = 0;
9555
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309556 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9557 __func__, hdd_device_modetoString(pAdapter->device_mode),
9558 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009559
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309560 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009561 setKey.keyId = key_index; // Store Key ID
9562 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9563 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9564 setKey.paeRole = 0 ; // the PAE role
9565 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9566 {
9567 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9568 }
9569 else
9570 {
9571 isConnected = hdd_connIsConnected(pHddStaCtx);
9572 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9573 }
9574 setKey.keyLength = key_Len;
9575 pKeyPtr = setKey.Key;
9576 memcpy( pKeyPtr, key, key_Len);
9577
Arif Hussain6d2a3322013-11-17 19:50:10 -08009578 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009579 __func__, key_Len);
9580 for (n = 0 ; n < key_Len; n++)
9581 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9582 __func__,n,setKey.Key[n]);
9583
9584 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9585 if ( isConnected )
9586 {
9587 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9588 pAdapter->sessionId, &setKey, &roamId );
9589 }
9590 if ( status != 0 )
9591 {
9592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9593 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9594 __LINE__, status );
9595 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9596 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309597 /* Need to clear any trace of key value in the memory.
9598 * Thus zero out the memory even though it is local
9599 * variable.
9600 */
9601 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009602}
9603#endif /* FEATURE_WLAN_WAPI*/
9604
9605#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309606int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009607 beacon_data_t **ppBeacon,
9608 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009609#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309610int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009611 beacon_data_t **ppBeacon,
9612 struct cfg80211_beacon_data *params,
9613 int dtim_period)
9614#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309615{
Jeff Johnson295189b2012-06-20 16:38:30 -07009616 int size;
9617 beacon_data_t *beacon = NULL;
9618 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309619 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9620 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009621
Jeff Johnsone7245742012-09-05 17:12:55 -07009622 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009623 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309624 {
9625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9626 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009627 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309628 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009629
9630 old = pAdapter->sessionCtx.ap.beacon;
9631
9632 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309633 {
9634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9635 FL("session(%d) old and new heads points to NULL"),
9636 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009637 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309638 }
9639
9640 if (params->tail && !params->tail_len)
9641 {
9642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9643 FL("tail_len is zero but tail is not NULL"));
9644 return -EINVAL;
9645 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009646
Jeff Johnson295189b2012-06-20 16:38:30 -07009647#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9648 /* Kernel 3.0 is not updating dtim_period for set beacon */
9649 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309650 {
9651 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9652 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009653 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309654 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009655#endif
9656
Kapil Gupta137ef892016-12-13 19:38:00 +05309657 if (params->head)
9658 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009659 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309660 head = params->head;
9661 } else
9662 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009663 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309664 head = old->head;
9665 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009666
Kapil Gupta137ef892016-12-13 19:38:00 +05309667 if (params->tail || !old)
9668 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009669 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309670 tail = params->tail;
9671 } else
9672 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009673 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309674 tail = old->tail;
9675 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009676
Kapil Gupta137ef892016-12-13 19:38:00 +05309677 if (params->proberesp_ies || !old)
9678 {
9679 proberesp_ies_len = params->proberesp_ies_len;
9680 proberesp_ies = params->proberesp_ies;
9681 } else
9682 {
9683 proberesp_ies_len = old->proberesp_ies_len;
9684 proberesp_ies = old->proberesp_ies;
9685 }
9686
9687 if (params->assocresp_ies || !old)
9688 {
9689 assocresp_ies_len = params->assocresp_ies_len;
9690 assocresp_ies = params->assocresp_ies;
9691 } else
9692 {
9693 assocresp_ies_len = old->assocresp_ies_len;
9694 assocresp_ies = old->assocresp_ies;
9695 }
9696
9697 size = sizeof(beacon_data_t) + head_len + tail_len +
9698 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009699
9700 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009701 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309702 {
9703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9704 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009705 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309706 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009707
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009708#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309709 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009710 beacon->dtim_period = params->dtim_period;
9711 else
9712 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009713#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309714 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009715 beacon->dtim_period = dtim_period;
9716 else
9717 beacon->dtim_period = old->dtim_period;
9718#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309719
Jeff Johnson295189b2012-06-20 16:38:30 -07009720 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9721 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309722 beacon->proberesp_ies = beacon->tail + tail_len;
9723 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9724
Jeff Johnson295189b2012-06-20 16:38:30 -07009725 beacon->head_len = head_len;
9726 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309727 beacon->proberesp_ies_len = proberesp_ies_len;
9728 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009729
c_manjee527ecac2017-01-25 12:25:27 +05309730 if (head && head_len)
9731 memcpy(beacon->head, head, head_len);
9732 if (tail && tail_len)
9733 memcpy(beacon->tail, tail, tail_len);
9734 if (proberesp_ies && proberesp_ies_len)
9735 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9736 if (assocresp_ies && assocresp_ies_len)
9737 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009738
9739 *ppBeacon = beacon;
9740
9741 kfree(old);
9742
9743 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009744}
Jeff Johnson295189b2012-06-20 16:38:30 -07009745
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309746v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9747#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9748 const v_U8_t *pIes,
9749#else
9750 v_U8_t *pIes,
9751#endif
9752 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009753{
9754 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309755 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009756 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309757
Jeff Johnson295189b2012-06-20 16:38:30 -07009758 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309759 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009760 elem_id = ptr[0];
9761 elem_len = ptr[1];
9762 left -= 2;
9763 if(elem_len > left)
9764 {
9765 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009766 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009767 eid,elem_len,left);
9768 return NULL;
9769 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309770 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009771 {
9772 return ptr;
9773 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309774
Jeff Johnson295189b2012-06-20 16:38:30 -07009775 left -= elem_len;
9776 ptr += (elem_len + 2);
9777 }
9778 return NULL;
9779}
9780
Jeff Johnson295189b2012-06-20 16:38:30 -07009781/* Check if rate is 11g rate or not */
9782static int wlan_hdd_rate_is_11g(u8 rate)
9783{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009784 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009785 u8 i;
9786 for (i = 0; i < 8; i++)
9787 {
9788 if(rate == gRateArray[i])
9789 return TRUE;
9790 }
9791 return FALSE;
9792}
9793
9794/* Check for 11g rate and set proper 11g only mode */
9795static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9796 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9797{
9798 u8 i, num_rates = pIe[0];
9799
9800 pIe += 1;
9801 for ( i = 0; i < num_rates; i++)
9802 {
9803 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9804 {
9805 /* If rate set have 11g rate than change the mode to 11G */
9806 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9807 if (pIe[i] & BASIC_RATE_MASK)
9808 {
9809 /* If we have 11g rate as basic rate, it means mode
9810 is 11g only mode.
9811 */
9812 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9813 *pCheckRatesfor11g = FALSE;
9814 }
9815 }
9816 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9817 {
9818 *require_ht = TRUE;
9819 }
9820 }
9821 return;
9822}
9823
9824static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9825{
9826 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9827 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9828 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9829 u8 checkRatesfor11g = TRUE;
9830 u8 require_ht = FALSE;
9831 u8 *pIe=NULL;
9832
9833 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9834
9835 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9836 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9837 if (pIe != NULL)
9838 {
9839 pIe += 1;
9840 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9841 &pConfig->SapHw_mode);
9842 }
9843
9844 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9845 WLAN_EID_EXT_SUPP_RATES);
9846 if (pIe != NULL)
9847 {
9848
9849 pIe += 1;
9850 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9851 &pConfig->SapHw_mode);
9852 }
9853
9854 if( pConfig->channel > 14 )
9855 {
9856 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9857 }
9858
9859 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9860 WLAN_EID_HT_CAPABILITY);
9861
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309862 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009863 {
9864 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9865 if(require_ht)
9866 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9867 }
9868}
9869
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309870static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9871 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9872{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009873 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309874 v_U8_t *pIe = NULL;
9875 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9876
9877 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9878 pBeacon->tail, pBeacon->tail_len);
9879
9880 if (pIe)
9881 {
9882 ielen = pIe[1] + 2;
9883 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9884 {
9885 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9886 }
9887 else
9888 {
9889 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9890 return -EINVAL;
9891 }
9892 *total_ielen += ielen;
9893 }
9894 return 0;
9895}
9896
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009897static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9898 v_U8_t *genie, v_U8_t *total_ielen)
9899{
9900 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9901 int left = pBeacon->tail_len;
9902 v_U8_t *ptr = pBeacon->tail;
9903 v_U8_t elem_id, elem_len;
9904 v_U16_t ielen = 0;
9905
9906 if ( NULL == ptr || 0 == left )
9907 return;
9908
9909 while (left >= 2)
9910 {
9911 elem_id = ptr[0];
9912 elem_len = ptr[1];
9913 left -= 2;
9914 if (elem_len > left)
9915 {
9916 hddLog( VOS_TRACE_LEVEL_ERROR,
9917 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9918 elem_id, elem_len, left);
9919 return;
9920 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309921 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009922 {
9923 /* skipping the VSIE's which we don't want to include or
9924 * it will be included by existing code
9925 */
9926 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9927#ifdef WLAN_FEATURE_WFD
9928 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9929#endif
9930 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9931 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9932 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9933 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9934 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9935 {
9936 ielen = ptr[1] + 2;
9937 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9938 {
9939 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9940 *total_ielen += ielen;
9941 }
9942 else
9943 {
9944 hddLog( VOS_TRACE_LEVEL_ERROR,
9945 "IE Length is too big "
9946 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9947 elem_id, elem_len, *total_ielen);
9948 }
9949 }
9950 }
9951
9952 left -= elem_len;
9953 ptr += (elem_len + 2);
9954 }
9955 return;
9956}
9957
Kapil Gupta137ef892016-12-13 19:38:00 +05309958int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009959{
9960 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309961 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009962 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009963 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309964 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009965
9966 genie = vos_mem_malloc(MAX_GENIE_LEN);
9967
9968 if(genie == NULL) {
9969
9970 return -ENOMEM;
9971 }
9972
Kapil Gupta137ef892016-12-13 19:38:00 +05309973 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309974 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9975 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009976 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309977 hddLog(LOGE,
9978 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309979 ret = -EINVAL;
9980 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009981 }
9982
9983#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309984 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9985 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9986 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309987 hddLog(LOGE,
9988 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309989 ret = -EINVAL;
9990 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009991 }
9992#endif
9993
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309994 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9995 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009996 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309997 hddLog(LOGE,
9998 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309999 ret = -EINVAL;
10000 goto done;
10001 }
10002
10003 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
10004 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -070010005 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -070010006 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010007
10008 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10009 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
10010 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
10011 {
10012 hddLog(LOGE,
10013 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010014 ret = -EINVAL;
10015 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010016 }
10017
10018 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10019 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10020 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10021 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10022 ==eHAL_STATUS_FAILURE)
10023 {
10024 hddLog(LOGE,
10025 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010026 ret = -EINVAL;
10027 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010028 }
10029
10030 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +053010031 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010032 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010033 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -070010034 u8 probe_rsp_ie_len[3] = {0};
10035 u8 counter = 0;
10036 /* Check Probe Resp Length if it is greater then 255 then Store
10037 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
10038 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
10039 Store More then 255 bytes into One Variable.
10040 */
10041 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
10042 {
10043 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
10044 {
10045 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
10046 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
10047 }
10048 else
10049 {
10050 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
10051 rem_probe_resp_ie_len = 0;
10052 }
10053 }
10054
10055 rem_probe_resp_ie_len = 0;
10056
10057 if (probe_rsp_ie_len[0] > 0)
10058 {
10059 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10060 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
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[0], NULL,
10064 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10065 {
10066 hddLog(LOGE,
10067 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 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[0];
10072 }
10073
10074 if (probe_rsp_ie_len[1] > 0)
10075 {
10076 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10077 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
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[1], NULL,
10081 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10082 {
10083 hddLog(LOGE,
10084 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 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[1];
10089 }
10090
10091 if (probe_rsp_ie_len[2] > 0)
10092 {
10093 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10094 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +053010095 (tANI_U8*)&pBeacon->
10096 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010097 probe_rsp_ie_len[2], NULL,
10098 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10099 {
10100 hddLog(LOGE,
10101 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010102 ret = -EINVAL;
10103 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010104 }
10105 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10106 }
10107
10108 if (probe_rsp_ie_len[1] == 0 )
10109 {
10110 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10111 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10112 eANI_BOOLEAN_FALSE) )
10113 {
10114 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010115 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010116 }
10117 }
10118
10119 if (probe_rsp_ie_len[2] == 0 )
10120 {
10121 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10122 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10123 eANI_BOOLEAN_FALSE) )
10124 {
10125 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010126 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010127 }
10128 }
10129
10130 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10131 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10132 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10133 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10134 == eHAL_STATUS_FAILURE)
10135 {
10136 hddLog(LOGE,
10137 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010138 ret = -EINVAL;
10139 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010140 }
10141 }
10142 else
10143 {
10144 // Reset WNI_CFG_PROBE_RSP Flags
10145 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
10146
10147 hddLog(VOS_TRACE_LEVEL_INFO,
10148 "%s: No Probe Response IE received in set beacon",
10149 __func__);
10150 }
10151
10152 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +053010153 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010154 {
10155 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +053010156 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
10157 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -070010158 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10159 {
10160 hddLog(LOGE,
10161 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010162 ret = -EINVAL;
10163 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010164 }
10165
10166 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10167 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
10168 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10169 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10170 == eHAL_STATUS_FAILURE)
10171 {
10172 hddLog(LOGE,
10173 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010174 ret = -EINVAL;
10175 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010176 }
10177 }
10178 else
10179 {
10180 hddLog(VOS_TRACE_LEVEL_INFO,
10181 "%s: No Assoc Response IE received in set beacon",
10182 __func__);
10183
10184 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10185 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10186 eANI_BOOLEAN_FALSE) )
10187 {
10188 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010189 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010190 }
10191 }
10192
Jeff Johnsone7245742012-09-05 17:12:55 -070010193done:
Jeff Johnson295189b2012-06-20 16:38:30 -070010194 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010195 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010196}
Jeff Johnson295189b2012-06-20 16:38:30 -070010197
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010198/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010199 * FUNCTION: wlan_hdd_validate_operation_channel
10200 * called by wlan_hdd_cfg80211_start_bss() and
10201 * wlan_hdd_cfg80211_set_channel()
10202 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010203 * channel list.
10204 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -070010205VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010206{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010207
Jeff Johnson295189b2012-06-20 16:38:30 -070010208 v_U32_t num_ch = 0;
10209 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10210 u32 indx = 0;
10211 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010212 v_U8_t fValidChannel = FALSE, count = 0;
10213 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010214
Jeff Johnson295189b2012-06-20 16:38:30 -070010215 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10216
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010217 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010218 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010219 /* Validate the channel */
10220 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010221 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010222 if ( channel == rfChannels[count].channelNum )
10223 {
10224 fValidChannel = TRUE;
10225 break;
10226 }
10227 }
10228 if (fValidChannel != TRUE)
10229 {
10230 hddLog(VOS_TRACE_LEVEL_ERROR,
10231 "%s: Invalid Channel [%d]", __func__, channel);
10232 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010233 }
10234 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010235 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010236 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010237 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10238 valid_ch, &num_ch))
10239 {
10240 hddLog(VOS_TRACE_LEVEL_ERROR,
10241 "%s: failed to get valid channel list", __func__);
10242 return VOS_STATUS_E_FAILURE;
10243 }
10244 for (indx = 0; indx < num_ch; indx++)
10245 {
10246 if (channel == valid_ch[indx])
10247 {
10248 break;
10249 }
10250 }
10251
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010252 if (indx >= num_ch)
10253 {
10254 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10255 {
10256 eCsrBand band;
10257 unsigned int freq;
10258
10259 sme_GetFreqBand(hHal, &band);
10260
10261 if (eCSR_BAND_5G == band)
10262 {
10263#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10264 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10265 {
10266 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010267 HDD_NL80211_BAND_2GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010268 }
10269 else
10270 {
10271 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010272 HDD_NL80211_BAND_5GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010273 }
10274#else
10275 freq = ieee80211_channel_to_frequency(channel);
10276#endif
10277 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
10278 return VOS_STATUS_SUCCESS;
10279 }
10280 }
10281
10282 hddLog(VOS_TRACE_LEVEL_ERROR,
10283 "%s: Invalid Channel [%d]", __func__, channel);
10284 return VOS_STATUS_E_FAILURE;
10285 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010286 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010287
Jeff Johnson295189b2012-06-20 16:38:30 -070010288 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010289
Jeff Johnson295189b2012-06-20 16:38:30 -070010290}
10291
Viral Modi3a32cc52013-02-08 11:14:52 -080010292/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010293 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -080010294 * This function is used to set the channel number
10295 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010296static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -080010297 struct ieee80211_channel *chan,
10298 enum nl80211_channel_type channel_type
10299 )
10300{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010301 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -080010302 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -070010303 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -080010304 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010305 hdd_context_t *pHddCtx;
10306 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010307
10308 ENTER();
10309
10310 if( NULL == dev )
10311 {
10312 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010313 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010314 return -ENODEV;
10315 }
10316 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010317
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010318 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10319 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10320 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010321 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010322 "%s: device_mode = %s (%d) freq = %d", __func__,
10323 hdd_device_modetoString(pAdapter->device_mode),
10324 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010325
10326 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10327 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010328 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010329 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010330 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010331 }
10332
10333 /*
10334 * Do freq to chan conversion
10335 * TODO: for 11a
10336 */
10337
10338 channel = ieee80211_frequency_to_channel(freq);
10339
10340 /* Check freq range */
10341 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10342 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10343 {
10344 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010345 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010346 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10347 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10348 return -EINVAL;
10349 }
10350
10351 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10352
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010353 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10354 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010355 {
10356 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10357 {
10358 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010359 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010360 return -EINVAL;
10361 }
10362 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10363 "%s: set channel to [%d] for device mode =%d",
10364 __func__, channel,pAdapter->device_mode);
10365 }
10366 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010367 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010368 )
10369 {
10370 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10371 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10372 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10373
10374 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10375 {
10376 /* Link is up then return cant set channel*/
10377 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010378 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010379 return -EINVAL;
10380 }
10381
10382 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10383 pHddStaCtx->conn_info.operationChannel = channel;
10384 pRoamProfile->ChannelInfo.ChannelList =
10385 &pHddStaCtx->conn_info.operationChannel;
10386 }
10387 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010388 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010389 )
10390 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010391 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10392 {
10393 if(VOS_STATUS_SUCCESS !=
10394 wlan_hdd_validate_operation_channel(pAdapter,channel))
10395 {
10396 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010397 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010398 return -EINVAL;
10399 }
10400 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10401 }
10402 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010403 {
10404 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10405
10406 /* If auto channel selection is configured as enable/ 1 then ignore
10407 channel set by supplicant
10408 */
10409 if ( cfg_param->apAutoChannelSelection )
10410 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010411 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10412 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010413 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010414 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10415 __func__, hdd_device_modetoString(pAdapter->device_mode),
10416 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010417 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010418 else
10419 {
10420 if(VOS_STATUS_SUCCESS !=
10421 wlan_hdd_validate_operation_channel(pAdapter,channel))
10422 {
10423 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010424 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010425 return -EINVAL;
10426 }
10427 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10428 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010429 }
10430 }
10431 else
10432 {
10433 hddLog(VOS_TRACE_LEVEL_FATAL,
10434 "%s: Invalid device mode failed to set valid channel", __func__);
10435 return -EINVAL;
10436 }
10437 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010438 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010439}
10440
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010441static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10442 struct net_device *dev,
10443 struct ieee80211_channel *chan,
10444 enum nl80211_channel_type channel_type
10445 )
10446{
10447 int ret;
10448
10449 vos_ssr_protect(__func__);
10450 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10451 vos_ssr_unprotect(__func__);
10452
10453 return ret;
10454}
10455
Anurag Chouhan83026002016-12-13 22:46:21 +053010456#ifdef DHCP_SERVER_OFFLOAD
10457void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10458 VOS_STATUS status)
10459{
10460 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10461
10462 ENTER();
10463
10464 if (NULL == adapter)
10465 {
10466 hddLog(VOS_TRACE_LEVEL_ERROR,
10467 "%s: adapter is NULL",__func__);
10468 return;
10469 }
10470
10471 adapter->dhcp_status.dhcp_offload_status = status;
10472 vos_event_set(&adapter->dhcp_status.vos_event);
10473 return;
10474}
10475
10476/**
10477 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10478 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010479 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010480 *
10481 * Return: None
10482 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010483VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10484 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010485{
10486 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10487 sir_dhcp_srv_offload_info dhcp_srv_info;
10488 tANI_U8 num_entries = 0;
10489 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10490 tANI_U8 num;
10491 tANI_U32 temp;
10492 VOS_STATUS ret;
10493
10494 ENTER();
10495
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010496 if (!re_init) {
10497 ret = wlan_hdd_validate_context(hdd_ctx);
10498 if (0 != ret)
10499 return VOS_STATUS_E_INVAL;
10500 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010501
10502 /* Prepare the request to send to SME */
10503 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10504 if (NULL == dhcp_srv_info) {
10505 hddLog(VOS_TRACE_LEVEL_ERROR,
10506 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10507 return VOS_STATUS_E_NOMEM;
10508 }
10509
10510 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10511
10512 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10513 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10514 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10515 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10516 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10517 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10518
10519 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10520 srv_ip,
10521 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010522 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010523 if (num_entries != IPADDR_NUM_ENTRIES) {
10524 hddLog(VOS_TRACE_LEVEL_ERROR,
10525 "%s: incorrect IP address (%s) assigned for DHCP server!",
10526 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10527 vos_mem_free(dhcp_srv_info);
10528 return VOS_STATUS_E_FAILURE;
10529 }
10530
10531 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10532 hddLog(VOS_TRACE_LEVEL_ERROR,
10533 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10534 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10535 vos_mem_free(dhcp_srv_info);
10536 return VOS_STATUS_E_FAILURE;
10537 }
10538
10539 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10540 hddLog(VOS_TRACE_LEVEL_ERROR,
10541 "%s: invalid IP address (%s)! The last field must be less than 100!",
10542 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10543 vos_mem_free(dhcp_srv_info);
10544 return VOS_STATUS_E_FAILURE;
10545 }
10546
10547 for (num = 0; num < num_entries; num++) {
10548 temp = srv_ip[num];
10549 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10550 }
10551
10552 if (eHAL_STATUS_SUCCESS !=
10553 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10554 hddLog(VOS_TRACE_LEVEL_ERROR,
10555 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10556 vos_mem_free(dhcp_srv_info);
10557 return VOS_STATUS_E_FAILURE;
10558 }
10559
10560 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10561 "%s: enable DHCP Server offload successfully!", __func__);
10562
10563 vos_mem_free(dhcp_srv_info);
10564 return 0;
10565}
10566#endif /* DHCP_SERVER_OFFLOAD */
10567
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010568/*
10569 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10570 * @wiphy_chan: wiphy channel number
10571 * @rfChannel: channel hw value
10572 * @disable: Disable/enable the flags
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010573 * @hdd_ctx: The HDD context handler
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010574 *
10575 * Modify wiphy flags and cds state if channel is indoor.
10576 *
10577 * Return: void
10578 */
10579void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010580 v_U32_t rfChannel, bool disable, hdd_context_t *hdd_ctx)
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010581{
10582 v_U32_t channelLoop;
10583 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10584
10585 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10586
10587 if (rfChannels[channelLoop].channelNum == rfChannel) {
10588 channelEnum = (eRfChannels)channelLoop;
10589 break;
10590 }
10591 }
10592
10593 if (INVALID_RF_CHANNEL == channelEnum)
10594 return;
10595
10596 if (disable) {
10597 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10598 wiphy_chan->flags |=
10599 IEEE80211_CHAN_DISABLED;
10600 regChannels[channelEnum].enabled =
10601 NV_CHANNEL_DISABLE;
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010602 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as DISABLE",
10603 channelEnum);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010604 }
10605 } else {
10606 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10607 wiphy_chan->flags &=
10608 ~IEEE80211_CHAN_DISABLED;
10609 /*
10610 * Indoor channels are marked as DFS
10611 * during regulatory processing
10612 */
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010613 if ((wiphy_chan->flags & (IEEE80211_CHAN_RADAR |
10614 IEEE80211_CHAN_PASSIVE_SCAN)) ||
10615 ((hdd_ctx->cfg_ini->indoor_channel_support == false)
10616 && (wiphy_chan->flags &
10617 IEEE80211_CHAN_INDOOR_ONLY))) {
10618 regChannels[channelEnum].enabled = NV_CHANNEL_DFS;
10619 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as DFS",
10620 channelEnum);
10621 } else {
10622 regChannels[channelEnum].enabled =
10623 NV_CHANNEL_ENABLE;
10624 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as ENABLE",
10625 channelEnum);
10626 }
10627 }
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010628
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010629 }
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010630}
10631
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010632void hdd_update_indoor_channel(hdd_context_t *hdd_ctx, bool disable)
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010633{
10634 int band_num;
10635 int chan_num;
10636 v_U32_t rfChannel;
10637 struct ieee80211_channel *wiphy_chan;
10638 struct wiphy *wiphy;
10639
10640 ENTER();
10641 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10642
10643 wiphy = hdd_ctx->wiphy;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010644 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010645
10646 if (wiphy->bands[band_num] == NULL)
10647 continue;
10648
10649 for (chan_num = 0;
10650 chan_num < wiphy->bands[band_num]->n_channels;
10651 chan_num++) {
10652
10653 wiphy_chan =
10654 &(wiphy->bands[band_num]->channels[chan_num]);
10655 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10656
10657 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010658 disable, hdd_ctx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010659 }
10660 }
10661 EXIT();
10662}
10663
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010664int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10665{
Dundi Raviteja49de66b2018-07-27 12:22:57 +053010666 eHalStatus status;
10667 int result = 0;
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010668 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10669 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10670 long ret;
10671 eConnectionState prev_conn_state;
10672 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
10673
10674 ENTER();
10675
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010676 /* Indicate sme of disconnect so that in progress connection or preauth
10677 * can be aborted
10678 */
10679 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10680 pAdapter->sessionId);
10681 pHddCtx->isAmpAllowed = VOS_TRUE;
10682
10683 /* Need to apply spin lock before decreasing active sessions
10684 * as there can be chance for double decrement if context switch
10685 * Calls hdd_DisConnectHandler.
10686 */
10687
10688 prev_conn_state = pHddStaCtx->conn_info.connState;
10689
10690 spin_lock_bh(&pAdapter->lock_for_active_session);
10691 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10692 {
10693 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10694 }
10695 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10696 spin_unlock_bh(&pAdapter->lock_for_active_session);
10697 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
10698
10699 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10700 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10701
10702 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10703
10704 /*
10705 * stop tx queues before deleting STA/BSS context from the firmware.
10706 * tx has to be disabled because the firmware can get busy dropping
10707 * the tx frames after BSS/STA has been deleted and will not send
10708 * back a response resulting in WDI timeout
10709 */
10710 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10711 netif_tx_disable(pAdapter->dev);
10712 netif_carrier_off(pAdapter->dev);
10713
10714 wlan_hdd_check_and_stop_mon(pAdapter, true);
10715
10716 /*issue disconnect*/
10717 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10718 pAdapter->sessionId, reason);
10719 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
10720 prev_conn_state != eConnectionState_Connecting)
10721 {
10722 hddLog(LOG1,
10723 FL("status = %d, already disconnected"), status);
10724 result = 0;
10725 /*
10726 * Wait here instead of returning directly. This will block the
10727 * next connect command and allow processing of the disconnect
10728 * in SME else we might hit some race conditions leading to SME
10729 * and HDD out of sync. As disconnect is already in progress,
10730 * wait here for 1 sec instead of 5 sec.
10731 */
10732 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
10733 goto wait_for_disconnect;
10734 }
10735 /*
10736 * Wait here instead of returning directly, this will block the next
10737 * connect command and allow processing of the scan for ssid and
10738 * the previous connect command in CSR. Else we might hit some
10739 * race conditions leading to SME and HDD out of sync.
10740 */
10741 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10742 {
10743 hddLog(LOG1,
10744 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
10745 }
10746 else if ( 0 != status )
10747 {
10748 hddLog(LOGE,
10749 FL("csrRoamDisconnect failure, returned %d"),
10750 (int)status);
10751 result = -EINVAL;
10752 goto disconnected;
10753 }
10754wait_for_disconnect:
10755 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
10756 msecs_to_jiffies(wait_time));
10757 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
10758 {
10759 hddLog(LOGE,
10760 "%s: Failed to disconnect, timed out", __func__);
10761 result = -ETIMEDOUT;
10762 }
10763disconnected:
10764 hddLog(LOG1,
10765 FL("Set HDD connState to eConnectionState_NotConnected"));
10766 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10767#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
10768 /* Sending disconnect event to userspace for kernel version < 3.11
10769 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
10770 */
10771 hddLog(LOG1, FL("Send disconnected event to userspace"));
10772
10773 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
10774 WLAN_REASON_UNSPECIFIED);
10775#endif
10776
10777 EXIT();
10778 return result;
10779}
10780
10781/*
10782 * hdd_check_and_disconnect_sta_on_invalid_channel() - Disconnect STA if it is
10783 * on indoor channel
10784 * @hdd_ctx: pointer to hdd context
10785 *
10786 * STA should be disconnected before starting the SAP if it is on indoor
10787 * channel.
10788 *
10789 * Return: void
10790 */
10791void hdd_check_and_disconnect_sta_on_invalid_channel(hdd_context_t *hdd_ctx)
10792{
10793
10794 hdd_adapter_t *sta_adapter;
10795 tANI_U8 sta_chan;
10796
10797 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
10798
10799 if (!sta_chan) {
10800 hddLog(LOG1, FL("STA not connected"));
10801 return;
10802 }
10803
10804 hddLog(LOG1, FL("STA connected on chan %hu"), sta_chan);
10805
10806 if (sme_IsChannelValid(hdd_ctx->hHal, sta_chan)) {
10807 hddLog(LOG1, FL("STA connected on chan %hu and it is valid"),
10808 sta_chan);
10809 return;
10810 }
10811
10812 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
10813
10814 if (!sta_adapter) {
10815 hddLog(LOG1, FL("STA adapter doesn't exist"));
10816 return;
10817 }
10818
10819 hddLog(LOG1, FL("chan %hu not valid, issue disconnect"), sta_chan);
10820 /* Issue Disconnect request */
10821 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10822}
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010823
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010824int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx)
10825{
10826 struct hdd_cache_channels *cache_chann;
10827 struct wiphy *wiphy;
10828 int freq, status, rfChannel;
10829 int i, band_num, channel_num;
10830 struct ieee80211_channel *wiphy_channel;
10831
10832 ENTER();
10833
10834 if (!hdd_ctx) {
10835 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10836 return -EINVAL;
10837 }
10838
10839 wiphy = hdd_ctx->wiphy;
10840
10841 mutex_lock(&hdd_ctx->cache_channel_lock);
10842
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010843 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010844
10845 if (!cache_chann || !cache_chann->num_channels) {
10846 hddLog(VOS_TRACE_LEVEL_INFO,
10847 "%s channel list is NULL or num channels are zero",
10848 __func__);
10849 mutex_unlock(&hdd_ctx->cache_channel_lock);
10850 return -EINVAL;
10851 }
10852
10853 for (i = 0; i < cache_chann->num_channels; i++) {
10854 status = hdd_wlan_get_freq(
10855 cache_chann->channel_info[i].channel_num,
10856 &freq);
10857
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010858 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
10859 band_num++) {
Dundi Raviteja1d019fd2018-09-23 18:18:22 +053010860 if (!wiphy->bands[band_num])
10861 continue;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010862 for (channel_num = 0; channel_num <
10863 wiphy->bands[band_num]->n_channels;
10864 channel_num++) {
10865 wiphy_channel = &(wiphy->bands[band_num]->
10866 channels[channel_num]);
10867 if (wiphy_channel->center_freq == freq) {
10868 rfChannel = wiphy_channel->hw_value;
10869 /*
10870 *Restore the orginal states
10871 *of the channels
10872 */
10873 vos_nv_set_channel_state(
10874 rfChannel,
10875 cache_chann->
10876 channel_info[i].reg_status);
10877 wiphy_channel->flags =
10878 cache_chann->
10879 channel_info[i].wiphy_status;
10880 break;
10881 }
10882 }
10883 if (channel_num < wiphy->bands[band_num]->n_channels)
10884 break;
10885 }
10886 }
10887
10888 mutex_unlock(&hdd_ctx->cache_channel_lock);
10889
10890 status = sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10891 if (status)
10892 hddLog(VOS_TRACE_LEVEL_ERROR, "Can't Restore channel list");
10893 EXIT();
10894
10895 return 0;
10896}
10897
10898/*
10899 * wlan_hdd_disable_channels() - Cache the the channels
10900 * and current state of the channels from the channel list
10901 * received in the command and disable the channels on the
10902 * wiphy and NV table.
10903 * @hdd_ctx: Pointer to hdd context
10904 *
10905 * @return: 0 on success, Error code on failure
10906 */
10907
10908static int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx)
10909{
10910 struct hdd_cache_channels *cache_chann;
10911 struct wiphy *wiphy;
10912 int freq, status, rfChannel;
10913 int i, band_num, band_ch_num;
10914 struct ieee80211_channel *wiphy_channel;
10915
10916 if (!hdd_ctx) {
10917 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10918 return -EINVAL;
10919 }
10920
10921 wiphy = hdd_ctx->wiphy;
10922
10923 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010924 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010925
10926 if (!cache_chann || !cache_chann->num_channels) {
10927 hddLog(VOS_TRACE_LEVEL_INFO,
10928 "%s channel list is NULL or num channels are zero",
10929 __func__);
10930 mutex_unlock(&hdd_ctx->cache_channel_lock);
10931 return -EINVAL;
10932 }
10933
10934 for (i = 0; i < cache_chann->num_channels; i++) {
10935 status = hdd_wlan_get_freq(
10936 cache_chann->channel_info[i].channel_num,
10937 &freq);
10938
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010939 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010940 band_num++) {
Dundi Raviteja1d019fd2018-09-23 18:18:22 +053010941 if (!wiphy->bands[band_num])
10942 continue;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010943 for (band_ch_num = 0; band_ch_num <
10944 wiphy->bands[band_num]->n_channels;
10945 band_ch_num++) {
10946 wiphy_channel = &(wiphy->bands[band_num]->
10947 channels[band_ch_num]);
10948 if (wiphy_channel->center_freq == freq) {
10949 rfChannel = wiphy_channel->hw_value;
10950 /*
10951 * Cache the current states of
10952 * the channels
10953 */
10954 cache_chann->
10955 channel_info[i].reg_status =
10956 vos_nv_getChannelEnabledState(
10957 rfChannel);
10958
10959 cache_chann->
10960 channel_info[i].wiphy_status =
10961 wiphy_channel->flags;
10962 hddLog(VOS_TRACE_LEVEL_INFO,
10963 "Disable channel %d reg_stat %d wiphy_stat 0x%x",
10964 cache_chann->
10965 channel_info[i].channel_num,
10966 cache_chann->
10967 channel_info[i].reg_status,
10968 wiphy_channel->flags);
10969
10970 vos_nv_set_channel_state(
10971 rfChannel,
10972 NV_CHANNEL_DISABLE);
10973 wiphy_channel->flags |=
10974 IEEE80211_CHAN_DISABLED;
10975 break;
10976 }
10977 }
10978 if (band_ch_num < wiphy->bands[band_num]->n_channels)
10979 break;
10980 }
10981 }
10982
10983 mutex_unlock(&hdd_ctx->cache_channel_lock);
10984 sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10985 return 0;
10986}
10987
Jeff Johnson295189b2012-06-20 16:38:30 -070010988#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10989static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10990 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010991#else
10992static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10993 struct cfg80211_beacon_data *params,
10994 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010995 enum nl80211_hidden_ssid hidden_ssid,
10996 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010997#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010998{
10999 tsap_Config_t *pConfig;
11000 beacon_data_t *pBeacon = NULL;
11001 struct ieee80211_mgmt *pMgmt_frame;
11002 v_U8_t *pIe=NULL;
11003 v_U16_t capab_info;
11004 eCsrAuthType RSNAuthType;
11005 eCsrEncryptionType RSNEncryptType;
11006 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011007 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011008 tpWLAN_SAPEventCB pSapEventCallback;
11009 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070011010 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011011 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011012 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011013 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070011014 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080011015 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Vignesh Viswanathan36575f82018-06-14 16:52:21 +053011016 hdd_adapter_t *sta_adapter;
Peng Xu2446a892014-09-05 17:21:18 +053011017 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070011018 v_BOOL_t MFPCapable = VOS_FALSE;
11019 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011020 v_BOOL_t sapEnable11AC =
11021 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053011022 u_int16_t prev_rsn_length = 0;
11023
Jeff Johnson295189b2012-06-20 16:38:30 -070011024 ENTER();
11025
Nitesh Shah9b066282017-06-06 18:05:52 +053011026 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Vignesh Viswanathan36575f82018-06-14 16:52:21 +053011027
11028 /*
11029 * For STA+SAP concurrency support from GUI, first STA connection gets
11030 * triggered and while it is in progress, SAP start also comes up.
11031 * Once STA association is successful, STA connect event is sent to
11032 * kernel which gets queued in kernel workqueue and supplicant won't
11033 * process M1 received from AP and send M2 until this NL80211_CONNECT
11034 * event is received. Workqueue is not scheduled as RTNL lock is already
11035 * taken by hostapd thread which has issued start_bss command to driver.
11036 * Driver cannot complete start_bss as the pending command at the head
11037 * of the SME command pending list is hw_mode_update for STA session
11038 * which cannot be processed as SME is in WAITforKey state for STA
11039 * interface. The start_bss command for SAP interface is queued behind
11040 * the hw_mode_update command and so it cannot be processed until
11041 * hw_mode_update command is processed. This is causing a deadlock so
11042 * disconnect the STA interface first if connection or key exchange is
11043 * in progress and then start SAP interface.
11044 */
11045 sta_adapter = hdd_get_sta_connection_in_progress(pHddCtx);
11046 if (sta_adapter) {
11047 hddLog(LOG1, FL("Disconnecting STA with session id: %d"),
11048 sta_adapter->sessionId);
11049 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
11050 }
11051
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011052 iniConfig = pHddCtx->cfg_ini;
11053
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011054 /* Mark the indoor channel (passive) to disable */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011055 if (iniConfig->disable_indoor_channel &&
11056 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011057 hdd_update_indoor_channel(pHddCtx, true);
11058
11059 if (!VOS_IS_STATUS_SUCCESS(
11060 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
11061 hdd_update_indoor_channel(pHddCtx, false);
11062 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
11063 FL("Can't start BSS: update channel list failed"));
Bala Venkatesh5c06a252018-07-12 16:08:04 +053011064 ret = eHAL_STATUS_FAILURE;
11065 goto tdls_enable;
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011066 }
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053011067
11068 /* check if STA is on indoor channel */
11069 if (hdd_is_sta_sap_scc_allowed_on_dfs_chan(pHddCtx))
11070 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011071 }
11072
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011073 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
11074 /* Disable the channels received in command SET_DISABLE_CHANNEL_LIST*/
11075 wlan_hdd_disable_channels(pHddCtx);
11076 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
11077 }
11078
Jeff Johnson295189b2012-06-20 16:38:30 -070011079 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
11080
11081 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
11082
11083 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
11084
11085 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
11086
11087 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
11088
11089 //channel is already set in the set_channel Call back
11090 //pConfig->channel = pCommitConfig->channel;
11091
11092 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011093 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070011094 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
11095
11096 pConfig->dtim_period = pBeacon->dtim_period;
11097
Arif Hussain6d2a3322013-11-17 19:50:10 -080011098 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070011099 pConfig->dtim_period);
11100
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080011101 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070011102 {
11103 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011104 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053011105 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
11106 {
11107 tANI_BOOLEAN restartNeeded;
11108 pConfig->ieee80211d = 1;
11109 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
11110 sme_setRegInfo(hHal, pConfig->countryCode);
11111 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
11112 }
11113 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070011114 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070011115 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070011116 pConfig->ieee80211d = 1;
11117 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
11118 sme_setRegInfo(hHal, pConfig->countryCode);
11119 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070011120 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011121 else
11122 {
11123 pConfig->ieee80211d = 0;
11124 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011125 /*
11126 * If auto channel is configured i.e. channel is 0,
11127 * so skip channel validation.
11128 */
11129 if( AUTO_CHANNEL_SELECT != pConfig->channel )
11130 {
11131 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
11132 {
11133 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011134 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011135 ret = -EINVAL;
11136 goto error;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011137 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011138 pConfig->user_config_channel = pConfig->channel;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011139 }
11140 else
11141 {
11142 if(1 != pHddCtx->is_dynamic_channel_range_set)
11143 {
11144 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
11145 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
11146 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
11147 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011148 pHddCtx->is_dynamic_channel_range_set = 0;
11149 pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011150 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011151 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011152 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011153 {
11154 pConfig->ieee80211d = 0;
11155 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011156
11157#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11158 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11159 pConfig->authType = eSAP_OPEN_SYSTEM;
11160 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11161 pConfig->authType = eSAP_SHARED_KEY;
11162 else
11163 pConfig->authType = eSAP_AUTO_SWITCH;
11164#else
11165 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11166 pConfig->authType = eSAP_OPEN_SYSTEM;
11167 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11168 pConfig->authType = eSAP_SHARED_KEY;
11169 else
11170 pConfig->authType = eSAP_AUTO_SWITCH;
11171#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011172
11173 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011174
11175 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070011176 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053011177#ifdef SAP_AUTH_OFFLOAD
11178 /* In case of sap offload, hostapd.conf is configuted with open mode and
11179 * security is configured from ini file. Due to open mode in hostapd.conf
11180 * privacy bit is set to false which will result in not sending,
11181 * data packets as encrypted.
11182 * If enable_sap_auth_offload is enabled in ini and
11183 * sap_auth_offload_sec_type is type of WPA2-PSK,
11184 * driver will set privacy bit to 1.
11185 */
11186 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
11187 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
11188 pConfig->privacy = VOS_TRUE;
11189#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011190
11191 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
11192
11193 /*Set wps station to configured*/
11194 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
11195
11196 if(pIe)
11197 {
11198 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
11199 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011200 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011201 ret = -EINVAL;
11202 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011203 }
11204 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
11205 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070011206 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070011207 /* Check 15 bit of WPS IE as it contain information for wps state
11208 * WPS state
11209 */
11210 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
11211 {
11212 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
11213 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
11214 {
11215 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
11216 }
11217 }
11218 }
11219 else
11220 {
11221 pConfig->wps_state = SAP_WPS_DISABLED;
11222 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011223 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070011224
c_hpothufe599e92014-06-16 11:38:55 +053011225 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11226 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11227 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
11228 eCSR_ENCRYPT_TYPE_NONE;
11229
Jeff Johnson295189b2012-06-20 16:38:30 -070011230 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053011231 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011232 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011233 WLAN_EID_RSN);
11234 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011235 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011236 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011237 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11238 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11239 pConfig->RSNWPAReqIELength);
11240 else
11241 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11242 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011243 /* The actual processing may eventually be more extensive than
11244 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070011245 * by the app.
11246 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011247 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011248 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11249 &RSNEncryptType,
11250 &mcRSNEncryptType,
11251 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011252 &MFPCapable,
11253 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011254 pConfig->RSNWPAReqIE[1]+2,
11255 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011256
11257 if( VOS_STATUS_SUCCESS == status )
11258 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011259 /* Now copy over all the security attributes you have
11260 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011261 * */
11262 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11263 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11264 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11265 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011266 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011267 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011268 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11269 }
11270 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011271
Jeff Johnson295189b2012-06-20 16:38:30 -070011272 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11273 pBeacon->tail, pBeacon->tail_len);
11274
11275 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
11276 {
Kapil Gupta137ef892016-12-13 19:38:00 +053011277 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011278 {
11279 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053011280 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070011281 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011282 if (pConfig->RSNWPAReqIELength <=
11283 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
11284 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
11285 pIe[1] + 2);
11286 else
11287 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11288 pConfig->RSNWPAReqIELength);
11289
Jeff Johnson295189b2012-06-20 16:38:30 -070011290 }
11291 else
11292 {
11293 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011294 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11295 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11296 pConfig->RSNWPAReqIELength);
11297 else
11298 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11299 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011300 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011301 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11302 &RSNEncryptType,
11303 &mcRSNEncryptType,
11304 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011305 &MFPCapable,
11306 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011307 pConfig->RSNWPAReqIE[1]+2,
11308 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011309
11310 if( VOS_STATUS_SUCCESS == status )
11311 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011312 /* Now copy over all the security attributes you have
11313 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011314 * */
11315 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11316 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11317 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11318 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011319 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011320 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011321 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11322 }
11323 }
11324 }
11325
Kapil Gupta137ef892016-12-13 19:38:00 +053011326 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070011327 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011328 ret = -EINVAL;
11329 goto error;
Jeff Johnson4416a782013-03-25 14:17:50 -070011330 }
11331
Jeff Johnson295189b2012-06-20 16:38:30 -070011332 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
11333
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011334#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011335 if (params->ssid != NULL)
11336 {
11337 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
11338 pConfig->SSIDinfo.ssid.length = params->ssid_len;
11339 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11340 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11341 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011342#else
11343 if (ssid != NULL)
11344 {
11345 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
11346 pConfig->SSIDinfo.ssid.length = ssid_len;
11347 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11348 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11349 }
11350#endif
11351
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011352 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070011353 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011354
Jeff Johnson295189b2012-06-20 16:38:30 -070011355 /* default value */
11356 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
11357 pConfig->num_accept_mac = 0;
11358 pConfig->num_deny_mac = 0;
11359
11360 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11361 pBeacon->tail, pBeacon->tail_len);
11362
11363 /* pIe for black list is following form:
11364 type : 1 byte
11365 length : 1 byte
11366 OUI : 4 bytes
11367 acl type : 1 byte
11368 no of mac addr in black list: 1 byte
11369 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011370 */
11371 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011372 {
11373 pConfig->SapMacaddr_acl = pIe[6];
11374 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011375 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011376 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011377 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
11378 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011379 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11380 for (i = 0; i < pConfig->num_deny_mac; i++)
11381 {
11382 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11383 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011384 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011385 }
11386 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11387 pBeacon->tail, pBeacon->tail_len);
11388
11389 /* pIe for white list is following form:
11390 type : 1 byte
11391 length : 1 byte
11392 OUI : 4 bytes
11393 acl type : 1 byte
11394 no of mac addr in white list: 1 byte
11395 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011396 */
11397 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011398 {
11399 pConfig->SapMacaddr_acl = pIe[6];
11400 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011401 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011402 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011403 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
11404 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011405 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11406 for (i = 0; i < pConfig->num_accept_mac; i++)
11407 {
11408 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11409 acl_entry++;
11410 }
11411 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011412
Jeff Johnson295189b2012-06-20 16:38:30 -070011413 wlan_hdd_set_sapHwmode(pHostapdAdapter);
11414
Jeff Johnsone7245742012-09-05 17:12:55 -070011415#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011416 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011417 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
11418 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053011419 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
11420 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011421 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
11422 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011423 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
11424 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070011425 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011426 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070011427 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011428 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011429
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011430 /* If ACS disable and selected channel <= 14
11431 * OR
11432 * ACS enabled and ACS operating band is choosen as 2.4
11433 * AND
11434 * VHT in 2.4G Disabled
11435 * THEN
11436 * Fallback to 11N mode
11437 */
11438 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
11439 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053011440 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011441 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011442 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011443 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
11444 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011445 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
11446 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011447 }
11448#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011449
Jeff Johnson295189b2012-06-20 16:38:30 -070011450 // ht_capab is not what the name conveys,this is used for protection bitmap
11451 pConfig->ht_capab =
11452 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
11453
Kapil Gupta137ef892016-12-13 19:38:00 +053011454 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070011455 {
11456 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011457 ret = -EINVAL;
11458 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011459 }
11460
11461 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011462 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070011463 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
11464 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011465 pConfig->obssProtEnabled =
11466 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070011467
Chet Lanctot8cecea22014-02-11 19:09:36 -080011468#ifdef WLAN_FEATURE_11W
11469 pConfig->mfpCapable = MFPCapable;
11470 pConfig->mfpRequired = MFPRequired;
11471 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
11472 pConfig->mfpCapable, pConfig->mfpRequired);
11473#endif
11474
Arif Hussain6d2a3322013-11-17 19:50:10 -080011475 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070011476 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011477 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
11478 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
11479 (int)pConfig->channel);
11480 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
11481 pConfig->SapHw_mode, pConfig->privacy,
11482 pConfig->authType);
11483 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
11484 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
11485 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
11486 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070011487
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011488 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070011489 {
11490 //Bss already started. just return.
11491 //TODO Probably it should update some beacon params.
11492 hddLog( LOGE, "Bss Already started...Ignore the request");
11493 EXIT();
11494 return 0;
11495 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011496
Agarwal Ashish51325b52014-06-16 16:50:49 +053011497 if (vos_max_concurrent_connections_reached()) {
11498 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011499 ret = -EINVAL;
11500 goto error;
Agarwal Ashish51325b52014-06-16 16:50:49 +053011501 }
11502
Jeff Johnson295189b2012-06-20 16:38:30 -070011503 pConfig->persona = pHostapdAdapter->device_mode;
11504
Peng Xu2446a892014-09-05 17:21:18 +053011505 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
11506 if ( NULL != psmeConfig)
11507 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011508 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053011509 sme_GetConfigParam(hHal, psmeConfig);
11510 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011511#ifdef WLAN_FEATURE_AP_HT40_24G
11512 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11513 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
11514 && pHddCtx->cfg_ini->apHT40_24GEnabled)
11515 {
11516 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
11517 sme_UpdateConfig (hHal, psmeConfig);
11518 }
11519#endif
Peng Xu2446a892014-09-05 17:21:18 +053011520 vos_mem_free(psmeConfig);
11521 }
Peng Xuafc34e32014-09-25 13:23:55 +053011522 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053011523
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011524 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -070011525 pSapEventCallback = hdd_hostapd_SAPEventCB;
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011526
11527 vos_event_reset(&pHostapdState->vosEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -070011528 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
11529 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
11530 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011531 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011532 ret = -EINVAL;
11533 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011534 }
11535
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011536 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070011537 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
11538
11539 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011540
Jeff Johnson295189b2012-06-20 16:38:30 -070011541 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011542 {
11543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011544 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070011545 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011546 VOS_ASSERT(0);
11547 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011548
Jeff Johnson295189b2012-06-20 16:38:30 -070011549 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053011550 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
11551 VOS_STATUS_SUCCESS)
11552 {
11553 hddLog(LOGE,FL("Fail to get Softap sessionID"));
11554 VOS_ASSERT(0);
11555 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053011556 /* Initialize WMM configuation */
11557 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011558 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011559
Anurag Chouhan83026002016-12-13 22:46:21 +053011560#ifdef DHCP_SERVER_OFFLOAD
11561 /* set dhcp server offload */
11562 if (iniConfig->enable_dhcp_srv_offload &&
11563 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011564 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053011565 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053011566 if (!VOS_IS_STATUS_SUCCESS(status))
11567 {
11568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11569 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011570 vos_event_reset(&pHostapdState->vosEvent);
11571 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11572 status = vos_wait_single_event(&pHostapdState->vosEvent,
11573 10000);
11574 if (!VOS_IS_STATUS_SUCCESS(status)) {
11575 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011576 ret = -EINVAL;
11577 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011578 }
11579 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011580 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011581 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
11582 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
11583 {
11584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11585 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
11586 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011587 vos_event_reset(&pHostapdState->vosEvent);
11588 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11589 status = vos_wait_single_event(&pHostapdState->vosEvent,
11590 10000);
11591 if (!VOS_IS_STATUS_SUCCESS(status)) {
11592 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011593 ret = -EINVAL;
11594 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011595 }
11596 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011597 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011598#ifdef MDNS_OFFLOAD
11599 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011600 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011601 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
11602 if (VOS_IS_STATUS_SUCCESS(status))
11603 {
11604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11605 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011606 vos_event_reset(&pHostapdState->vosEvent);
11607 if (VOS_STATUS_SUCCESS ==
11608 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11609 status = vos_wait_single_event(&pHostapdState->vosEvent,
11610 10000);
11611 if (!VOS_IS_STATUS_SUCCESS(status)) {
11612 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011613 ret = -EINVAL;
11614 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011615 }
11616 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011617 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011618 status = vos_wait_single_event(&pHostapdAdapter->
11619 mdns_status.vos_event, 2000);
11620 if (!VOS_IS_STATUS_SUCCESS(status) ||
11621 pHostapdAdapter->mdns_status.mdns_enable_status ||
11622 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
11623 pHostapdAdapter->mdns_status.mdns_resp_status)
11624 {
11625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11626 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
11627 pHostapdAdapter->mdns_status.mdns_enable_status,
11628 pHostapdAdapter->mdns_status.mdns_fqdn_status,
11629 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011630 vos_event_reset(&pHostapdState->vosEvent);
11631 if (VOS_STATUS_SUCCESS ==
11632 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11633 status = vos_wait_single_event(&pHostapdState->vosEvent,
11634 10000);
11635 if (!VOS_IS_STATUS_SUCCESS(status)) {
11636 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011637 ret = -EINVAL;
11638 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011639 }
11640 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011641 }
11642 }
11643#endif /* MDNS_OFFLOAD */
11644 } else {
11645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11646 ("DHCP Disabled ini %d, FW %d"),
11647 iniConfig->enable_dhcp_srv_offload,
11648 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053011649 }
11650#endif /* DHCP_SERVER_OFFLOAD */
11651
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011652#ifdef WLAN_FEATURE_P2P_DEBUG
11653 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
11654 {
11655 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
11656 {
11657 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11658 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011659 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011660 }
11661 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
11662 {
11663 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11664 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011665 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011666 }
11667 }
11668#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053011669 /* Check and restart SAP if it is on Unsafe channel */
11670 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011671
Jeff Johnson295189b2012-06-20 16:38:30 -070011672 pHostapdState->bCommit = TRUE;
11673 EXIT();
11674
11675 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011676error:
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011677 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11678 wlan_hdd_restore_channels(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011679 /* Revert the indoor to passive marking if START BSS fails */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011680 if (iniConfig->disable_indoor_channel &&
11681 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011682 hdd_update_indoor_channel(pHddCtx, false);
11683 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
11684 }
11685
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011686 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
Bala Venkatesh5c06a252018-07-12 16:08:04 +053011687
11688tdls_enable:
11689 if (ret != eHAL_STATUS_SUCCESS)
11690 wlan_hdd_tdls_reenable(pHddCtx);
11691
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011692 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011693}
11694
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011695#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011696static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011697 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011698 struct beacon_parameters *params)
11699{
11700 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011701 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011702 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011703
11704 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011705
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011706 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11707 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11708 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011709 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11710 hdd_device_modetoString(pAdapter->device_mode),
11711 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011712
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011713 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11714 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011715 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011716 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011717 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011718 }
11719
Agarwal Ashish51325b52014-06-16 16:50:49 +053011720 if (vos_max_concurrent_connections_reached()) {
11721 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11722 return -EINVAL;
11723 }
11724
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011725 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011726 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011727 )
11728 {
11729 beacon_data_t *old,*new;
11730
11731 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011732
Jeff Johnson295189b2012-06-20 16:38:30 -070011733 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011734 {
11735 hddLog(VOS_TRACE_LEVEL_WARN,
11736 FL("already beacon info added to session(%d)"),
11737 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011738 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011739 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011740
11741 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11742
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011743 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011744 {
11745 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011746 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011747 return -EINVAL;
11748 }
11749
11750 pAdapter->sessionCtx.ap.beacon = new;
11751
11752 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11753 }
11754
11755 EXIT();
11756 return status;
11757}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011758
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011759static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11760 struct net_device *dev,
11761 struct beacon_parameters *params)
11762{
11763 int ret;
11764
11765 vos_ssr_protect(__func__);
11766 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11767 vos_ssr_unprotect(__func__);
11768
11769 return ret;
11770}
11771
11772static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011773 struct net_device *dev,
11774 struct beacon_parameters *params)
11775{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011776 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011777 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11778 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011779 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011780
11781 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011782
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011783 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11784 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11785 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11786 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11787 __func__, hdd_device_modetoString(pAdapter->device_mode),
11788 pAdapter->device_mode);
11789
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011790 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11791 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011792 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011793 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011794 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011795 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011796
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011797 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011798 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011799 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011800 {
11801 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011802
Jeff Johnson295189b2012-06-20 16:38:30 -070011803 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011804
Jeff Johnson295189b2012-06-20 16:38:30 -070011805 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011806 {
11807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11808 FL("session(%d) old and new heads points to NULL"),
11809 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011810 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011811 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011812
11813 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11814
11815 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011816 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011817 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011818 return -EINVAL;
11819 }
11820
11821 pAdapter->sessionCtx.ap.beacon = new;
11822
11823 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11824 }
11825
11826 EXIT();
11827 return status;
11828}
11829
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011830static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11831 struct net_device *dev,
11832 struct beacon_parameters *params)
11833{
11834 int ret;
11835
11836 vos_ssr_protect(__func__);
11837 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11838 vos_ssr_unprotect(__func__);
11839
11840 return ret;
11841}
11842
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011843#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11844
11845#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011846static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011847 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011848#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011849static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011850 struct net_device *dev)
11851#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011852{
11853 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Vignesh Viswanathan5caacc22018-06-14 17:14:20 +053011854 hdd_adapter_t *staAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011855 hdd_context_t *pHddCtx = NULL;
11856 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011857 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011858 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011859
11860 ENTER();
11861
11862 if (NULL == pAdapter)
11863 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011865 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011866 return -ENODEV;
11867 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011868
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011869 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11870 TRACE_CODE_HDD_CFG80211_STOP_AP,
11871 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011872 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11873 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011874 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011875 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011876 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011877 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011878
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011879 pScanInfo = &pHddCtx->scan_info;
11880
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011881 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11882 __func__, hdd_device_modetoString(pAdapter->device_mode),
11883 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011884
Vignesh Viswanathan5caacc22018-06-14 17:14:20 +053011885 /*
11886 * if a sta connection is in progress in another adapter, disconnect
11887 * the sta and complete the sap operation. sta will reconnect
11888 * after sap stop is done.
11889 */
11890 staAdapter = hdd_get_sta_connection_in_progress(pHddCtx);
11891 if (staAdapter) {
11892 hddLog(LOG1, FL("disconnecting sta with session id: %d"),
11893 staAdapter->sessionId);
11894 wlan_hdd_disconnect(staAdapter, eCSR_DISCONNECT_REASON_DEAUTH);
11895 }
11896
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011897 ret = wlan_hdd_scan_abort(pAdapter);
11898
Girish Gowli4bf7a632014-06-12 13:42:11 +053011899 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011900 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11902 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011903
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011904 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011905 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11907 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011908
Jeff Johnsone7245742012-09-05 17:12:55 -070011909 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011910 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011911 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011912 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011913 }
11914
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011915 /* Delete all associated STAs before stopping AP/P2P GO */
11916 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011917 hdd_hostapd_stop(dev);
11918
Jeff Johnson295189b2012-06-20 16:38:30 -070011919 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011920 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011921 )
11922 {
11923 beacon_data_t *old;
11924
11925 old = pAdapter->sessionCtx.ap.beacon;
11926
11927 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011928 {
11929 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11930 FL("session(%d) beacon data points to NULL"),
11931 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011932 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011933 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011934
Jeff Johnson295189b2012-06-20 16:38:30 -070011935 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011936
11937 mutex_lock(&pHddCtx->sap_lock);
11938 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11939 {
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011940 hdd_hostapd_state_t *pHostapdState =
11941 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11942
Abhishek Singh10e17cf2018-03-12 14:34:22 +053011943 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
11944 hdd_wait_for_ecsa_complete(pHddCtx);
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011945 vos_event_reset(&pHostapdState->vosEvent);
11946
Jeff Johnson4416a782013-03-25 14:17:50 -070011947 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011948 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011949 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11950
11951 if (!VOS_IS_STATUS_SUCCESS(status))
11952 {
11953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011954 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011955 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011956 }
11957 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011958 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011959 /* BSS stopped, clear the active sessions for this device mode */
11960 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011961 }
11962 mutex_unlock(&pHddCtx->sap_lock);
11963
11964 if(status != VOS_STATUS_SUCCESS)
11965 {
11966 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011967 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011968 return -EINVAL;
11969 }
11970
Jeff Johnson4416a782013-03-25 14:17:50 -070011971 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011972 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11973 ==eHAL_STATUS_FAILURE)
11974 {
11975 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011976 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011977 }
11978
Jeff Johnson4416a782013-03-25 14:17:50 -070011979 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011980 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11981 eANI_BOOLEAN_FALSE) )
11982 {
11983 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011984 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011985 }
11986
11987 // Reset WNI_CFG_PROBE_RSP Flags
11988 wlan_hdd_reset_prob_rspies(pAdapter);
11989
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011990 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11991
Jeff Johnson295189b2012-06-20 16:38:30 -070011992 pAdapter->sessionCtx.ap.beacon = NULL;
11993 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011994#ifdef WLAN_FEATURE_P2P_DEBUG
11995 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11996 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11997 {
11998 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11999 "GO got removed");
12000 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
12001 }
12002#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012003 }
12004 EXIT();
12005 return status;
12006}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012007
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012008#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
12009static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
12010 struct net_device *dev)
12011{
12012 int ret;
12013
12014 vos_ssr_protect(__func__);
12015 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
12016 vos_ssr_unprotect(__func__);
12017
12018 return ret;
12019}
12020#else
12021static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
12022 struct net_device *dev)
12023{
12024 int ret;
12025
12026 vos_ssr_protect(__func__);
12027 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
12028 vos_ssr_unprotect(__func__);
12029
12030 return ret;
12031}
12032#endif
12033
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012034#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
12035
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012036static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012037 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012038 struct cfg80211_ap_settings *params)
12039{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012040 hdd_adapter_t *pAdapter;
12041 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012042 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012043
12044 ENTER();
12045
Girish Gowlib143d7a2015-02-18 19:39:55 +053012046 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012047 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012048 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053012049 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012050 return -ENODEV;
12051 }
12052
12053 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12054 if (NULL == pAdapter)
12055 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012057 "%s: HDD adapter is Null", __func__);
12058 return -ENODEV;
12059 }
12060
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012061 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12062 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
12063 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012064 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
12065 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012067 "%s: HDD adapter magic is invalid", __func__);
12068 return -ENODEV;
12069 }
12070
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053012071 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
12072
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012073 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012074 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012075 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012076 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012077 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012078 }
12079
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012080 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
12081 __func__, hdd_device_modetoString(pAdapter->device_mode),
12082 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012083
12084 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012085 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012086 )
12087 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012088 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012089
12090 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012091
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012092 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012093 {
12094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12095 FL("already beacon info added to session(%d)"),
12096 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012097 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012098 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012099
Girish Gowlib143d7a2015-02-18 19:39:55 +053012100#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
12101 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12102 &new,
12103 &params->beacon);
12104#else
12105 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12106 &new,
12107 &params->beacon,
12108 params->dtim_period);
12109#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012110
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012111 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012112 {
12113 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012114 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012115 return -EINVAL;
12116 }
12117 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080012118#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070012119 wlan_hdd_cfg80211_set_channel(wiphy, dev,
12120#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
12121 params->channel, params->channel_type);
12122#else
12123 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
12124#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080012125#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012126 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012127 params->ssid_len, params->hidden_ssid,
12128 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012129 }
12130
12131 EXIT();
12132 return status;
12133}
12134
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012135static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
12136 struct net_device *dev,
12137 struct cfg80211_ap_settings *params)
12138{
12139 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012140
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012141 vos_ssr_protect(__func__);
12142 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
12143 vos_ssr_unprotect(__func__);
12144
12145 return ret;
12146}
12147
12148static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012149 struct net_device *dev,
12150 struct cfg80211_beacon_data *params)
12151{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012152 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012153 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012154 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012155
12156 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012157
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012158 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12159 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
12160 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080012161 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012162 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012163
12164 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12165 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012166 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012167 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012168 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012169 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012170
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012171 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012172 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012173 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012174 {
12175 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012176
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012177 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012178
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012179 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012180 {
12181 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12182 FL("session(%d) beacon data points to NULL"),
12183 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012184 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012185 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012186
12187 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
12188
12189 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012190 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012191 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012192 return -EINVAL;
12193 }
12194
12195 pAdapter->sessionCtx.ap.beacon = new;
12196
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012197 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
12198 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012199 }
12200
12201 EXIT();
12202 return status;
12203}
12204
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012205static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
12206 struct net_device *dev,
12207 struct cfg80211_beacon_data *params)
12208{
12209 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012210
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012211 vos_ssr_protect(__func__);
12212 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
12213 vos_ssr_unprotect(__func__);
12214
12215 return ret;
12216}
12217
12218#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070012219
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012220static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012221 struct net_device *dev,
12222 struct bss_parameters *params)
12223{
12224 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012225 hdd_context_t *pHddCtx;
12226 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012227
12228 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012229
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012230 if (NULL == pAdapter)
12231 {
12232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12233 "%s: HDD adapter is Null", __func__);
12234 return -ENODEV;
12235 }
12236 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012237 ret = wlan_hdd_validate_context(pHddCtx);
12238 if (0 != ret)
12239 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012240 return ret;
12241 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012242 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12243 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
12244 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012245 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12246 __func__, hdd_device_modetoString(pAdapter->device_mode),
12247 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012248
12249 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012250 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012251 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012252 {
12253 /* ap_isolate == -1 means that in change bss, upper layer doesn't
12254 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012255 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070012256 {
12257 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012258 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012259 }
12260
12261 EXIT();
12262 return 0;
12263}
12264
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012265static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
12266 struct net_device *dev,
12267 struct bss_parameters *params)
12268{
12269 int ret;
12270
12271 vos_ssr_protect(__func__);
12272 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
12273 vos_ssr_unprotect(__func__);
12274
12275 return ret;
12276}
Kiet Lam10841362013-11-01 11:36:50 +053012277/* FUNCTION: wlan_hdd_change_country_code_cd
12278* to wait for contry code completion
12279*/
12280void* wlan_hdd_change_country_code_cb(void *pAdapter)
12281{
12282 hdd_adapter_t *call_back_pAdapter = pAdapter;
12283 complete(&call_back_pAdapter->change_country_code);
12284 return NULL;
12285}
12286
Jeff Johnson295189b2012-06-20 16:38:30 -070012287/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012288 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070012289 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
12290 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012291int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012292 struct net_device *ndev,
12293 enum nl80211_iftype type,
12294 u32 *flags,
12295 struct vif_params *params
12296 )
12297{
12298 struct wireless_dev *wdev;
12299 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012300 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012301 tCsrRoamProfile *pRoamProfile = NULL;
12302 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012303 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012304 eMib_dot11DesiredBssType connectedBssType;
12305 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012306 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012307
12308 ENTER();
12309
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012310 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012311 {
12312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12313 "%s: Adapter context is null", __func__);
12314 return VOS_STATUS_E_FAILURE;
12315 }
12316
12317 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12318 if (!pHddCtx)
12319 {
12320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12321 "%s: HDD context is null", __func__);
12322 return VOS_STATUS_E_FAILURE;
12323 }
12324
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012325 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12326 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
12327 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012328 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012329 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012330 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012331 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012332 }
12333
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012334 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12335 __func__, hdd_device_modetoString(pAdapter->device_mode),
12336 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012337
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012338 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
12339 hddLog(VOS_TRACE_LEVEL_FATAL,
12340 "%s: STA + MON is in progress, cannot change interface",
12341 __func__);
12342 }
12343
Agarwal Ashish51325b52014-06-16 16:50:49 +053012344 if (vos_max_concurrent_connections_reached()) {
12345 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12346 return -EINVAL;
12347 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012348 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012349 wdev = ndev->ieee80211_ptr;
12350
12351#ifdef WLAN_BTAMP_FEATURE
12352 if((NL80211_IFTYPE_P2P_CLIENT == type)||
12353 (NL80211_IFTYPE_ADHOC == type)||
12354 (NL80211_IFTYPE_AP == type)||
12355 (NL80211_IFTYPE_P2P_GO == type))
12356 {
12357 pHddCtx->isAmpAllowed = VOS_FALSE;
12358 // stop AMP traffic
12359 status = WLANBAP_StopAmp();
12360 if(VOS_STATUS_SUCCESS != status )
12361 {
12362 pHddCtx->isAmpAllowed = VOS_TRUE;
12363 hddLog(VOS_TRACE_LEVEL_FATAL,
12364 "%s: Failed to stop AMP", __func__);
12365 return -EINVAL;
12366 }
12367 }
12368#endif //WLAN_BTAMP_FEATURE
12369 /* Reset the current device mode bit mask*/
12370 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
12371
Bala Venkatesh5c06a252018-07-12 16:08:04 +053012372 if (((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
12373 (type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO)) ||
12374 type == NL80211_IFTYPE_AP)
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053012375 {
12376 /* Notify Mode change in case of concurrency.
12377 * Below function invokes TDLS teardown Functionality Since TDLS is
12378 * not Supported in case of concurrency i.e Once P2P session
12379 * is detected disable offchannel and teardown TDLS links
12380 */
12381 hddLog(LOG1,
12382 FL("Device mode = %d Interface type = %d"),
12383 pAdapter->device_mode, type);
12384 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
12385 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053012386
Jeff Johnson295189b2012-06-20 16:38:30 -070012387 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012388 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070012389 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012390 )
12391 {
12392 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012393 if (!pWextState)
12394 {
12395 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12396 "%s: pWextState is null", __func__);
12397 return VOS_STATUS_E_FAILURE;
12398 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012399 pRoamProfile = &pWextState->roamProfile;
12400 LastBSSType = pRoamProfile->BSSType;
12401
12402 switch (type)
12403 {
12404 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012405 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012406 hddLog(VOS_TRACE_LEVEL_INFO,
12407 "%s: setting interface Type to INFRASTRUCTURE", __func__);
12408 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012409#ifdef WLAN_FEATURE_11AC
12410 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
12411 {
12412 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
12413 }
12414#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012415 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070012416 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012417 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012418 //Check for sub-string p2p to confirm its a p2p interface
12419 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012420 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053012421#ifdef FEATURE_WLAN_TDLS
12422 mutex_lock(&pHddCtx->tdls_lock);
12423 wlan_hdd_tdls_exit(pAdapter, TRUE);
12424 mutex_unlock(&pHddCtx->tdls_lock);
12425#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012426 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12427 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12428 }
12429 else
12430 {
12431 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012432 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012433 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012434 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053012435
Jeff Johnson295189b2012-06-20 16:38:30 -070012436 case NL80211_IFTYPE_ADHOC:
12437 hddLog(VOS_TRACE_LEVEL_INFO,
12438 "%s: setting interface Type to ADHOC", __func__);
12439 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
12440 pRoamProfile->phyMode =
12441 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070012442 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012443 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053012444 hdd_set_ibss_ops( pAdapter );
12445 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053012446
12447 status = hdd_sta_id_hash_attach(pAdapter);
12448 if (VOS_STATUS_SUCCESS != status) {
12449 hddLog(VOS_TRACE_LEVEL_ERROR,
12450 FL("Failed to initialize hash for IBSS"));
12451 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012452 break;
12453
12454 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012455 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012456 {
12457 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12458 "%s: setting interface Type to %s", __func__,
12459 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
12460
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012461 //Cancel any remain on channel for GO mode
12462 if (NL80211_IFTYPE_P2P_GO == type)
12463 {
12464 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
12465 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053012466 //Disable IMPS & BMPS for SAP/GO
12467 if(VOS_STATUS_E_FAILURE ==
12468 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
12469 {
12470 //Fail to Exit BMPS
12471 VOS_ASSERT(0);
12472 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053012473
12474 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
12475
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012476#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070012477
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012478 /* A Mutex Lock is introduced while changing the mode to
12479 * protect the concurrent access for the Adapters by TDLS
12480 * module.
12481 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012482 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012483#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012484 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053012485 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012486 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070012487 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12488 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012489#ifdef FEATURE_WLAN_TDLS
12490 mutex_unlock(&pHddCtx->tdls_lock);
12491#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012492 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
12493 (pConfig->apRandomBssidEnabled))
12494 {
12495 /* To meet Android requirements create a randomized
12496 MAC address of the form 02:1A:11:Fx:xx:xx */
12497 get_random_bytes(&ndev->dev_addr[3], 3);
12498 ndev->dev_addr[0] = 0x02;
12499 ndev->dev_addr[1] = 0x1A;
12500 ndev->dev_addr[2] = 0x11;
12501 ndev->dev_addr[3] |= 0xF0;
12502 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
12503 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080012504 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
12505 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012506 }
12507
Jeff Johnson295189b2012-06-20 16:38:30 -070012508 hdd_set_ap_ops( pAdapter->dev );
12509
Kiet Lam10841362013-11-01 11:36:50 +053012510 /* This is for only SAP mode where users can
12511 * control country through ini.
12512 * P2P GO follows station country code
12513 * acquired during the STA scanning. */
12514 if((NL80211_IFTYPE_AP == type) &&
12515 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
12516 {
12517 int status = 0;
12518 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
12519 "%s: setting country code from INI ", __func__);
12520 init_completion(&pAdapter->change_country_code);
12521 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
12522 (void *)(tSmeChangeCountryCallback)
12523 wlan_hdd_change_country_code_cb,
12524 pConfig->apCntryCode, pAdapter,
12525 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012526 eSIR_FALSE,
12527 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053012528 if (eHAL_STATUS_SUCCESS == status)
12529 {
12530 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012531 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053012532 &pAdapter->change_country_code,
12533 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012534 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053012535 {
12536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012537 FL("SME Timed out while setting country code %ld"),
12538 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080012539
12540 if (pHddCtx->isLogpInProgress)
12541 {
12542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12543 "%s: LOGP in Progress. Ignore!!!", __func__);
12544 return -EAGAIN;
12545 }
Kiet Lam10841362013-11-01 11:36:50 +053012546 }
12547 }
12548 else
12549 {
12550 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012551 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053012552 return -EINVAL;
12553 }
12554 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053012555 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070012556 if(status != VOS_STATUS_SUCCESS)
12557 {
12558 hddLog(VOS_TRACE_LEVEL_FATAL,
12559 "%s: Error initializing the ap mode", __func__);
12560 return -EINVAL;
12561 }
12562 hdd_set_conparam(1);
12563
Nirav Shah7e3c8132015-06-22 23:51:42 +053012564 status = hdd_sta_id_hash_attach(pAdapter);
12565 if (VOS_STATUS_SUCCESS != status)
12566 {
12567 hddLog(VOS_TRACE_LEVEL_ERROR,
12568 FL("Failed to initialize hash for AP"));
12569 return -EINVAL;
12570 }
12571
Jeff Johnson295189b2012-06-20 16:38:30 -070012572 /*interface type changed update in wiphy structure*/
12573 if(wdev)
12574 {
12575 wdev->iftype = type;
12576 pHddCtx->change_iface = type;
12577 }
12578 else
12579 {
12580 hddLog(VOS_TRACE_LEVEL_ERROR,
12581 "%s: ERROR !!!! Wireless dev is NULL", __func__);
12582 return -EINVAL;
12583 }
12584 goto done;
12585 }
12586
12587 default:
12588 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12589 __func__);
12590 return -EOPNOTSUPP;
12591 }
12592 }
12593 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012594 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070012595 )
12596 {
12597 switch(type)
12598 {
12599 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012600 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012601 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053012602
12603 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012604#ifdef FEATURE_WLAN_TDLS
12605
12606 /* A Mutex Lock is introduced while changing the mode to
12607 * protect the concurrent access for the Adapters by TDLS
12608 * module.
12609 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012610 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012611#endif
c_hpothu002231a2015-02-05 14:58:51 +053012612 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012613 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012614 //Check for sub-string p2p to confirm its a p2p interface
12615 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012616 {
12617 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12618 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12619 }
12620 else
12621 {
12622 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012623 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012624 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053012625
12626 /* set con_mode to STA only when no SAP concurrency mode */
12627 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
12628 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012629 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012630 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
12631 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012632#ifdef FEATURE_WLAN_TDLS
12633 mutex_unlock(&pHddCtx->tdls_lock);
12634#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053012635 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070012636 if( VOS_STATUS_SUCCESS != status )
12637 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070012638 /* In case of JB, for P2P-GO, only change interface will be called,
12639 * This is the right place to enable back bmps_imps()
12640 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012641 if (pHddCtx->hdd_wlan_suspended)
12642 {
12643 hdd_set_pwrparams(pHddCtx);
12644 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012645 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012646 goto done;
12647 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012648 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012649 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012650 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12651 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012652 goto done;
12653 default:
12654 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12655 __func__);
12656 return -EOPNOTSUPP;
12657
12658 }
12659
12660 }
12661 else
12662 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012663 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
12664 __func__, hdd_device_modetoString(pAdapter->device_mode),
12665 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012666 return -EOPNOTSUPP;
12667 }
12668
12669
12670 if(pRoamProfile)
12671 {
12672 if ( LastBSSType != pRoamProfile->BSSType )
12673 {
12674 /*interface type changed update in wiphy structure*/
12675 wdev->iftype = type;
12676
12677 /*the BSS mode changed, We need to issue disconnect
12678 if connected or in IBSS disconnect state*/
12679 if ( hdd_connGetConnectedBssType(
12680 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
12681 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
12682 {
12683 /*need to issue a disconnect to CSR.*/
12684 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12685 if( eHAL_STATUS_SUCCESS ==
12686 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12687 pAdapter->sessionId,
12688 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12689 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012690 ret = wait_for_completion_interruptible_timeout(
12691 &pAdapter->disconnect_comp_var,
12692 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12693 if (ret <= 0)
12694 {
12695 hddLog(VOS_TRACE_LEVEL_ERROR,
12696 FL("wait on disconnect_comp_var failed %ld"), ret);
12697 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012698 }
12699 }
12700 }
12701 }
12702
12703done:
12704 /*set bitmask based on updated value*/
12705 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012706
12707 /* Only STA mode support TM now
12708 * all other mode, TM feature should be disabled */
12709 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12710 (~VOS_STA & pHddCtx->concurrency_mode) )
12711 {
12712 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12713 }
12714
Jeff Johnson295189b2012-06-20 16:38:30 -070012715#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012716 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012717 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012718 {
12719 //we are ok to do AMP
12720 pHddCtx->isAmpAllowed = VOS_TRUE;
12721 }
12722#endif //WLAN_BTAMP_FEATURE
12723 EXIT();
12724 return 0;
12725}
12726
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012727/*
12728 * FUNCTION: wlan_hdd_cfg80211_change_iface
12729 * wrapper function to protect the actual implementation from SSR.
12730 */
12731int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12732 struct net_device *ndev,
12733 enum nl80211_iftype type,
12734 u32 *flags,
12735 struct vif_params *params
12736 )
12737{
12738 int ret;
12739
12740 vos_ssr_protect(__func__);
12741 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12742 vos_ssr_unprotect(__func__);
12743
12744 return ret;
12745}
12746
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012747#ifdef FEATURE_WLAN_TDLS
12748static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012749 struct net_device *dev,
12750#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12751 const u8 *mac,
12752#else
12753 u8 *mac,
12754#endif
12755 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012756{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012757 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012758 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012759 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012760 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012761 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012762 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012763
12764 ENTER();
12765
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012766 if (!dev) {
12767 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12768 return -EINVAL;
12769 }
12770
12771 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12772 if (!pAdapter) {
12773 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12774 return -EINVAL;
12775 }
12776
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012777 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012778 {
12779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12780 "Invalid arguments");
12781 return -EINVAL;
12782 }
Hoonki Lee27511902013-03-14 18:19:06 -070012783
12784 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12785 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12786 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012788 "%s: TDLS mode is disabled OR not enabled in FW."
12789 MAC_ADDRESS_STR " Request declined.",
12790 __func__, MAC_ADDR_ARRAY(mac));
12791 return -ENOTSUPP;
12792 }
12793
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012794 if (pHddCtx->isLogpInProgress)
12795 {
12796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12797 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012798 wlan_hdd_tdls_set_link_status(pAdapter,
12799 mac,
12800 eTDLS_LINK_IDLE,
12801 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012802 return -EBUSY;
12803 }
12804
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012805 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012806 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012807
12808 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012809 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012810 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12811 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012812 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012813 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012814 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012815
12816 /* in add station, we accept existing valid staId if there is */
12817 if ((0 == update) &&
12818 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12819 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012820 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012822 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012823 " link_status %d. staId %d. add station ignored.",
12824 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012825 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012826 return 0;
12827 }
12828 /* in change station, we accept only when staId is valid */
12829 if ((1 == update) &&
12830 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12831 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12832 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012833 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012835 "%s: " MAC_ADDRESS_STR
12836 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012837 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12838 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12839 mutex_unlock(&pHddCtx->tdls_lock);
12840 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012841 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012842 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012843
12844 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012845 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012846 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12848 "%s: " MAC_ADDRESS_STR
12849 " TDLS setup is ongoing. Request declined.",
12850 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012851 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012852 }
12853
12854 /* first to check if we reached to maximum supported TDLS peer.
12855 TODO: for now, return -EPERM looks working fine,
12856 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012857 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12858 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012859 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12861 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012862 " TDLS Max peer already connected. Request declined."
12863 " Num of peers (%d), Max allowed (%d).",
12864 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12865 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012866 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012867 }
12868 else
12869 {
12870 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012871 mutex_lock(&pHddCtx->tdls_lock);
12872 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012873 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012874 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012875 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12877 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12878 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012879 return -EPERM;
12880 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012881 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012882 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012883 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012884 wlan_hdd_tdls_set_link_status(pAdapter,
12885 mac,
12886 eTDLS_LINK_CONNECTING,
12887 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012888
Jeff Johnsond75fe012013-04-06 10:53:06 -070012889 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012890 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012891 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012892 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012893 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012894 if(StaParams->htcap_present)
12895 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012897 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012898 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012899 "ht_capa->extended_capabilities: %0x",
12900 StaParams->HTCap.extendedHtCapInfo);
12901 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012903 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012904 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012905 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012906 if(StaParams->vhtcap_present)
12907 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012909 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12910 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12911 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12912 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012913 {
12914 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012915 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012916 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012918 "[%d]: %x ", i, StaParams->supported_rates[i]);
12919 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012920 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012921 else if ((1 == update) && (NULL == StaParams))
12922 {
12923 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12924 "%s : update is true, but staParams is NULL. Error!", __func__);
12925 return -EPERM;
12926 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012927
12928 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12929
12930 if (!update)
12931 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012932 /*Before adding sta make sure that device exited from BMPS*/
12933 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12934 {
12935 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12936 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12937 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12938 if (status != VOS_STATUS_SUCCESS) {
12939 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12940 }
12941 }
12942
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012943 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012944 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012945 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012946 hddLog(VOS_TRACE_LEVEL_ERROR,
12947 FL("Failed to add TDLS peer STA. Enable Bmps"));
12948 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012949 return -EPERM;
12950 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012951 }
12952 else
12953 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012954 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012955 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012956 if (ret != eHAL_STATUS_SUCCESS) {
12957 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12958 return -EPERM;
12959 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012960 }
12961
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012962 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012963 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12964
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012965 mutex_lock(&pHddCtx->tdls_lock);
12966 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12967
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012968 if ((pTdlsPeer != NULL) &&
12969 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012970 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012971 hddLog(VOS_TRACE_LEVEL_ERROR,
12972 FL("peer link status %u"), pTdlsPeer->link_status);
12973 mutex_unlock(&pHddCtx->tdls_lock);
12974 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012975 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012976 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012977
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012978 if (ret <= 0)
12979 {
12980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12981 "%s: timeout waiting for tdls add station indication %ld",
12982 __func__, ret);
12983 goto error;
12984 }
12985
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012986 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12987 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012989 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012990 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012991 }
12992
12993 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012994
12995error:
Atul Mittal115287b2014-07-08 13:26:33 +053012996 wlan_hdd_tdls_set_link_status(pAdapter,
12997 mac,
12998 eTDLS_LINK_IDLE,
12999 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013000 return -EPERM;
13001
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013002}
13003#endif
13004
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013005VOS_STATUS wlan_hdd_send_sta_authorized_event(
13006 hdd_adapter_t *adapter,
13007 hdd_context_t *hdd_ctx,
13008 const v_MACADDR_t *mac_addr)
13009{
13010 struct sk_buff *vendor_event;
13011 uint32_t sta_flags = 0;
13012 VOS_STATUS status;
13013
13014 ENTER();
13015
13016 if (!hdd_ctx) {
13017 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null"));
13018 return -EINVAL;
13019 }
13020
13021 vendor_event =
13022 cfg80211_vendor_event_alloc(
Ashish Kumar Dhanotiyac99fbef2018-04-11 12:23:32 +053013023 hdd_ctx->wiphy,
13024#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
13025 &adapter->wdev,
13026#endif
13027 sizeof(sta_flags) +
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013028 VOS_MAC_ADDR_SIZE + NLMSG_HDRLEN,
13029 QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX,
13030 GFP_KERNEL);
13031 if (!vendor_event) {
13032 hddLog(VOS_TRACE_LEVEL_ERROR,
13033 FL("cfg80211_vendor_event_alloc failed"));
13034 return -EINVAL;
13035 }
13036
13037 sta_flags |= BIT(NL80211_STA_FLAG_AUTHORIZED);
13038
13039 status = nla_put_u32(vendor_event,
13040 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS,
13041 sta_flags);
13042 if (status) {
13043 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA flag put fails"));
13044 kfree_skb(vendor_event);
13045 return VOS_STATUS_E_FAILURE;
13046 }
13047 status = nla_put(vendor_event,
13048 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_MAC,
13049 VOS_MAC_ADDR_SIZE, mac_addr->bytes);
13050 if (status) {
13051 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA MAC put fails"));
13052 kfree_skb(vendor_event);
13053 return VOS_STATUS_E_FAILURE;
13054 }
13055
13056 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
13057
13058 EXIT();
13059 return 0;
13060}
13061
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013062static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013063 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013064#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13065 const u8 *mac,
13066#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013067 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013068#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013069 struct station_parameters *params)
13070{
13071 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013072 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013073 hdd_context_t *pHddCtx;
13074 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013075 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013076 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013077#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013078 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013079 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013080 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013081 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013082#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013083
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013084 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013085
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013086 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013087 if ((NULL == pAdapter))
13088 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013090 "invalid adapter ");
13091 return -EINVAL;
13092 }
13093
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013094 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13095 TRACE_CODE_HDD_CHANGE_STATION,
13096 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053013097 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013098
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013099 ret = wlan_hdd_validate_context(pHddCtx);
13100 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053013101 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013102 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013103 }
13104
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013105 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13106
13107 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013108 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13110 "invalid HDD station context");
13111 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013112 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013113 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
13114
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013115 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
13116 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070013117 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013118 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070013119 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013120 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070013121 WLANTL_STA_AUTHENTICATED);
13122
Gopichand Nakkala29149562013-05-10 21:43:41 +053013123 if (status != VOS_STATUS_SUCCESS)
13124 {
13125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13126 "%s: Not able to change TL state to AUTHENTICATED", __func__);
13127 return -EINVAL;
13128 }
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013129 status = wlan_hdd_send_sta_authorized_event(pAdapter, pHddCtx,
13130 &STAMacAddress);
13131 if (status != VOS_STATUS_SUCCESS)
13132 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013133 }
13134 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070013135 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
13136 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013137#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013138 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13139 StaParams.capability = params->capability;
13140 StaParams.uapsd_queues = params->uapsd_queues;
13141 StaParams.max_sp = params->max_sp;
13142
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013143 /* Convert (first channel , number of channels) tuple to
13144 * the total list of channels. This goes with the assumption
13145 * that if the first channel is < 14, then the next channels
13146 * are an incremental of 1 else an incremental of 4 till the number
13147 * of channels.
13148 */
13149 if (0 != params->supported_channels_len) {
13150 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013151 for ( i = 0 ; i < params->supported_channels_len
13152 && j < SIR_MAC_MAX_SUPP_CHANNELS; i+=2)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013153 {
13154 int wifi_chan_index;
13155 StaParams.supported_channels[j] = params->supported_channels[i];
13156 wifi_chan_index =
13157 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
13158 no_of_channels = params->supported_channels[i+1];
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013159 for(k=1; k <= no_of_channels
13160 && j < SIR_MAC_MAX_SUPP_CHANNELS - 1; k++)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013161 {
13162 StaParams.supported_channels[j+1] =
13163 StaParams.supported_channels[j] + wifi_chan_index;
13164 j+=1;
13165 }
13166 }
13167 StaParams.supported_channels_len = j;
13168 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053013169 if (params->supported_oper_classes_len >
13170 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
13171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13172 "received oper classes:%d, resetting it to max supported %d",
13173 params->supported_oper_classes_len,
13174 SIR_MAC_MAX_SUPP_OPER_CLASSES);
13175 params->supported_oper_classes_len =
13176 SIR_MAC_MAX_SUPP_OPER_CLASSES;
13177 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013178 vos_mem_copy(StaParams.supported_oper_classes,
13179 params->supported_oper_classes,
13180 params->supported_oper_classes_len);
13181 StaParams.supported_oper_classes_len =
13182 params->supported_oper_classes_len;
13183
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013184 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
13185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13186 "received extn capabilities:%d, resetting it to max supported",
13187 params->ext_capab_len);
13188 params->ext_capab_len = sizeof(StaParams.extn_capability);
13189 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013190 if (0 != params->ext_capab_len)
13191 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013192 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013193
13194 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013195 {
13196 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013197 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013198 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013199
13200 StaParams.supported_rates_len = params->supported_rates_len;
13201
13202 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
13203 * The supported_rates array , for all the structures propogating till Add Sta
13204 * to the firmware has to be modified , if the supplicant (ieee80211) is
13205 * modified to send more rates.
13206 */
13207
13208 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
13209 */
13210 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
13211 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
13212
13213 if (0 != StaParams.supported_rates_len) {
13214 int i = 0;
13215 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
13216 StaParams.supported_rates_len);
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 "Supported Rates with Length %d", StaParams.supported_rates_len);
13219 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013221 "[%d]: %0x", i, StaParams.supported_rates[i]);
13222 }
13223
13224 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013225 {
13226 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013227 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013228 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013229
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013230 if (0 != params->ext_capab_len ) {
13231 /*Define A Macro : TODO Sunil*/
13232 if ((1<<4) & StaParams.extn_capability[3]) {
13233 isBufSta = 1;
13234 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013235 /* TDLS Channel Switching Support */
13236 if ((1<<6) & StaParams.extn_capability[3]) {
13237 isOffChannelSupported = 1;
13238 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013239 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013240
13241 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053013242 (params->ht_capa || params->vht_capa ||
13243 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013244 /* TDLS Peer is WME/QoS capable */
13245 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013246
13247 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13248 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
13249 __func__, isQosWmmSta, StaParams.htcap_present);
13250
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013251 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
13252 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013253 isOffChannelSupported,
13254 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013255
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013256 if (VOS_STATUS_SUCCESS != status) {
13257 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13258 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
13259 return -EINVAL;
13260 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013261 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
13262
13263 if (VOS_STATUS_SUCCESS != status) {
13264 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13265 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
13266 return -EINVAL;
13267 }
13268 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013269#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053013270 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013271 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013272 return status;
13273}
13274
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013275#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13276static int wlan_hdd_change_station(struct wiphy *wiphy,
13277 struct net_device *dev,
13278 const u8 *mac,
13279 struct station_parameters *params)
13280#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013281static int wlan_hdd_change_station(struct wiphy *wiphy,
13282 struct net_device *dev,
13283 u8 *mac,
13284 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013285#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013286{
13287 int ret;
13288
13289 vos_ssr_protect(__func__);
13290 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
13291 vos_ssr_unprotect(__func__);
13292
13293 return ret;
13294}
13295
Jeff Johnson295189b2012-06-20 16:38:30 -070013296/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013297 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013298 * This function is used to initialize the key information
13299 */
13300#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013301static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013302 struct net_device *ndev,
13303 u8 key_index, bool pairwise,
13304 const u8 *mac_addr,
13305 struct key_params *params
13306 )
13307#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013308static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013309 struct net_device *ndev,
13310 u8 key_index, const u8 *mac_addr,
13311 struct key_params *params
13312 )
13313#endif
13314{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013315 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013316 tCsrRoamSetKey setKey;
13317 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013318 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013319 v_U32_t roamId= 0xFF;
13320 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013321 hdd_hostapd_state_t *pHostapdState;
13322 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013323 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013324 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013325 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013326 v_MACADDR_t *peerMacAddr;
13327 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013328 uint8_t staid = HDD_MAX_STA_COUNT;
13329 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013330
13331 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013332
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013333 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13334 TRACE_CODE_HDD_CFG80211_ADD_KEY,
13335 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013336 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13337 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013338 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013339 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013340 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013341 }
13342
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013343 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13344 __func__, hdd_device_modetoString(pAdapter->device_mode),
13345 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013346
13347 if (CSR_MAX_NUM_KEY <= key_index)
13348 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013349 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013350 key_index);
13351
13352 return -EINVAL;
13353 }
13354
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013355 if (CSR_MAX_KEY_LEN < params->key_len)
13356 {
13357 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
13358 params->key_len);
13359
13360 return -EINVAL;
13361 }
13362
Jingxiang Gec438aea2017-10-26 16:44:00 +080013363 if (CSR_MAX_RSC_LEN < params->seq_len)
13364 {
13365 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
13366 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053013367
13368 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080013369 }
13370
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013371 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080013372 "%s: called with key index = %d & key length %d & seq length %d",
13373 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013374
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013375 peerMacAddr = (v_MACADDR_t *)mac_addr;
13376
Jeff Johnson295189b2012-06-20 16:38:30 -070013377 /*extract key idx, key len and key*/
13378 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13379 setKey.keyId = key_index;
13380 setKey.keyLength = params->key_len;
13381 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080013382 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013383
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013384 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013385 {
13386 case WLAN_CIPHER_SUITE_WEP40:
13387 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13388 break;
13389
13390 case WLAN_CIPHER_SUITE_WEP104:
13391 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
13392 break;
13393
13394 case WLAN_CIPHER_SUITE_TKIP:
13395 {
13396 u8 *pKey = &setKey.Key[0];
13397 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
13398
13399 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
13400
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013401 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070013402
13403 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013404 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013405 |--------------|----------|----------|
13406 <---16bytes---><--8bytes--><--8bytes-->
13407
13408 */
13409 /*Sme expects the 32 bytes key to be in the below order
13410
13411 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013412 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013413 |--------------|----------|----------|
13414 <---16bytes---><--8bytes--><--8bytes-->
13415 */
13416 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013417 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070013418
13419 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013420 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013421
13422 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013423 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013424
13425
13426 break;
13427 }
13428
13429 case WLAN_CIPHER_SUITE_CCMP:
13430 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
13431 break;
13432
13433#ifdef FEATURE_WLAN_WAPI
13434 case WLAN_CIPHER_SUITE_SMS4:
13435 {
13436 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13437 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
13438 params->key, params->key_len);
13439 return 0;
13440 }
13441#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013442
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013443#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013444 case WLAN_CIPHER_SUITE_KRK:
13445 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
13446 break;
13447#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013448
13449#ifdef WLAN_FEATURE_11W
13450 case WLAN_CIPHER_SUITE_AES_CMAC:
13451 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070013452 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070013453#endif
13454
Jeff Johnson295189b2012-06-20 16:38:30 -070013455 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013456 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070013457 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013458 status = -EOPNOTSUPP;
13459 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013460 }
13461
13462 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
13463 __func__, setKey.encType);
13464
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013465 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070013466#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13467 (!pairwise)
13468#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013469 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013470#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013471 )
13472 {
13473 /* set group key*/
13474 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13475 "%s- %d: setting Broadcast key",
13476 __func__, __LINE__);
13477 setKey.keyDirection = eSIR_RX_ONLY;
13478 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13479 }
13480 else
13481 {
13482 /* set pairwise key*/
13483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13484 "%s- %d: setting pairwise key",
13485 __func__, __LINE__);
13486 setKey.keyDirection = eSIR_TX_RX;
13487 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013488 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013489 }
13490 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
13491 {
13492 setKey.keyDirection = eSIR_TX_RX;
13493 /*Set the group key*/
13494 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13495 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070013496
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013497 if ( 0 != status )
13498 {
13499 hddLog(VOS_TRACE_LEVEL_ERROR,
13500 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013501 status = -EINVAL;
13502 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013503 }
13504 /*Save the keys here and call sme_RoamSetKey for setting
13505 the PTK after peer joins the IBSS network*/
13506 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
13507 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013508 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013509 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053013510 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
13511 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
13512 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013513 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013514 if( pHostapdState->bssState == BSS_START )
13515 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013516 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13517 vos_status = wlan_hdd_check_ula_done(pAdapter);
13518
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013519 if (peerMacAddr && (pairwise_set_key == true))
13520 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013521
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013522 if ( vos_status != VOS_STATUS_SUCCESS )
13523 {
13524 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13525 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13526 __LINE__, vos_status );
13527
13528 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13529
13530 status = -EINVAL;
13531 goto end;
13532 }
13533
Jeff Johnson295189b2012-06-20 16:38:30 -070013534 status = WLANSAP_SetKeySta( pVosContext, &setKey);
13535
13536 if ( status != eHAL_STATUS_SUCCESS )
13537 {
13538 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13539 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13540 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013541 status = -EINVAL;
13542 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013543 }
13544 }
13545
13546 /* Saving WEP keys */
13547 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
13548 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
13549 {
13550 //Save the wep key in ap context. Issue setkey after the BSS is started.
13551 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13552 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
13553 }
13554 else
13555 {
13556 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013557 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013558 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
13559 }
13560 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013561 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
13562 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013563 {
13564 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13565 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13566
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013567#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13568 if (!pairwise)
13569#else
13570 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
13571#endif
13572 {
13573 /* set group key*/
13574 if (pHddStaCtx->roam_info.deferKeyComplete)
13575 {
13576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13577 "%s- %d: Perform Set key Complete",
13578 __func__, __LINE__);
13579 hdd_PerformRoamSetKeyComplete(pAdapter);
13580 }
13581 }
13582
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013583 if (pairwise_set_key == true)
13584 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013585
Jeff Johnson295189b2012-06-20 16:38:30 -070013586 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
13587
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080013588 pWextState->roamProfile.Keys.defaultIndex = key_index;
13589
13590
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013591 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013592 params->key, params->key_len);
13593
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013594
Jeff Johnson295189b2012-06-20 16:38:30 -070013595 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13596
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013597 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013598 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013599 __func__, setKey.peerMac[0], setKey.peerMac[1],
13600 setKey.peerMac[2], setKey.peerMac[3],
13601 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013602 setKey.keyDirection);
13603
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013604 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053013605
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013606 if ( vos_status != VOS_STATUS_SUCCESS )
13607 {
13608 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013609 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13610 __LINE__, vos_status );
13611
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013612 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013613
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013614 status = -EINVAL;
13615 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013616
13617 }
13618
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013619#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013620 /* The supplicant may attempt to set the PTK once pre-authentication
13621 is done. Save the key in the UMAC and include it in the ADD BSS
13622 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013623 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013624 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013625 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013626 hddLog(VOS_TRACE_LEVEL_INFO_MED,
13627 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013628 status = 0;
13629 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013630 }
13631 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
13632 {
13633 hddLog(VOS_TRACE_LEVEL_ERROR,
13634 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013635 status = -EINVAL;
13636 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013637 }
13638#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070013639
13640 /* issue set key request to SME*/
13641 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13642 pAdapter->sessionId, &setKey, &roamId );
13643
13644 if ( 0 != status )
13645 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013646 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013647 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
13648 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013649 status = -EINVAL;
13650 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013651 }
13652
13653
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013654 /* in case of IBSS as there was no information available about WEP keys during
13655 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070013656 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013657 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
13658 !( ( IW_AUTH_KEY_MGMT_802_1X
13659 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070013660 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
13661 )
13662 &&
13663 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
13664 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
13665 )
13666 )
13667 {
13668 setKey.keyDirection = eSIR_RX_ONLY;
13669 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13670
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013671 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013672 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013673 __func__, setKey.peerMac[0], setKey.peerMac[1],
13674 setKey.peerMac[2], setKey.peerMac[3],
13675 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013676 setKey.keyDirection);
13677
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013678 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013679 pAdapter->sessionId, &setKey, &roamId );
13680
13681 if ( 0 != status )
13682 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013683 hddLog(VOS_TRACE_LEVEL_ERROR,
13684 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013685 __func__, status);
13686 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013687 status = -EINVAL;
13688 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013689 }
13690 }
13691 }
13692
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013693 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013694 for (i = 0; i < params->seq_len; i++) {
13695 rsc_counter |= (params->seq[i] << i*8);
13696 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013697 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
13698 }
13699
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013700end:
13701 /* Need to clear any trace of key value in the memory.
13702 * Thus zero out the memory even though it is local
13703 * variable.
13704 */
13705 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013706 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013707 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013708}
13709
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013710#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13711static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13712 struct net_device *ndev,
13713 u8 key_index, bool pairwise,
13714 const u8 *mac_addr,
13715 struct key_params *params
13716 )
13717#else
13718static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13719 struct net_device *ndev,
13720 u8 key_index, const u8 *mac_addr,
13721 struct key_params *params
13722 )
13723#endif
13724{
13725 int ret;
13726 vos_ssr_protect(__func__);
13727#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13728 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
13729 mac_addr, params);
13730#else
13731 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
13732 params);
13733#endif
13734 vos_ssr_unprotect(__func__);
13735
13736 return ret;
13737}
13738
Jeff Johnson295189b2012-06-20 16:38:30 -070013739/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013740 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013741 * This function is used to get the key information
13742 */
13743#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013744static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013745 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013746 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013747 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013748 const u8 *mac_addr, void *cookie,
13749 void (*callback)(void *cookie, struct key_params*)
13750 )
13751#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013752static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013753 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013754 struct net_device *ndev,
13755 u8 key_index, const u8 *mac_addr, void *cookie,
13756 void (*callback)(void *cookie, struct key_params*)
13757 )
13758#endif
13759{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013760 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013761 hdd_wext_state_t *pWextState = NULL;
13762 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013763 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013764 hdd_context_t *pHddCtx;
13765 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013766
13767 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013768
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013769 if (NULL == pAdapter)
13770 {
13771 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13772 "%s: HDD adapter is Null", __func__);
13773 return -ENODEV;
13774 }
13775
13776 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13777 ret = wlan_hdd_validate_context(pHddCtx);
13778 if (0 != ret)
13779 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013780 return ret;
13781 }
13782
13783 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13784 pRoamProfile = &(pWextState->roamProfile);
13785
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013786 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13787 __func__, hdd_device_modetoString(pAdapter->device_mode),
13788 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013789
Jeff Johnson295189b2012-06-20 16:38:30 -070013790 memset(&params, 0, sizeof(params));
13791
13792 if (CSR_MAX_NUM_KEY <= key_index)
13793 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013795 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013796 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013797
13798 switch(pRoamProfile->EncryptionType.encryptionType[0])
13799 {
13800 case eCSR_ENCRYPT_TYPE_NONE:
13801 params.cipher = IW_AUTH_CIPHER_NONE;
13802 break;
13803
13804 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13805 case eCSR_ENCRYPT_TYPE_WEP40:
13806 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13807 break;
13808
13809 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13810 case eCSR_ENCRYPT_TYPE_WEP104:
13811 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13812 break;
13813
13814 case eCSR_ENCRYPT_TYPE_TKIP:
13815 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13816 break;
13817
13818 case eCSR_ENCRYPT_TYPE_AES:
13819 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13820 break;
13821
13822 default:
13823 params.cipher = IW_AUTH_CIPHER_NONE;
13824 break;
13825 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013826
c_hpothuaaf19692014-05-17 17:01:48 +053013827 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13828 TRACE_CODE_HDD_CFG80211_GET_KEY,
13829 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013830
Jeff Johnson295189b2012-06-20 16:38:30 -070013831 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13832 params.seq_len = 0;
13833 params.seq = NULL;
13834 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13835 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013836 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013837 return 0;
13838}
13839
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013840#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13841static int wlan_hdd_cfg80211_get_key(
13842 struct wiphy *wiphy,
13843 struct net_device *ndev,
13844 u8 key_index, bool pairwise,
13845 const u8 *mac_addr, void *cookie,
13846 void (*callback)(void *cookie, struct key_params*)
13847 )
13848#else
13849static int wlan_hdd_cfg80211_get_key(
13850 struct wiphy *wiphy,
13851 struct net_device *ndev,
13852 u8 key_index, const u8 *mac_addr, void *cookie,
13853 void (*callback)(void *cookie, struct key_params*)
13854 )
13855#endif
13856{
13857 int ret;
13858
13859 vos_ssr_protect(__func__);
13860#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13861 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13862 mac_addr, cookie, callback);
13863#else
13864 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13865 callback);
13866#endif
13867 vos_ssr_unprotect(__func__);
13868
13869 return ret;
13870}
13871
Jeff Johnson295189b2012-06-20 16:38:30 -070013872/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013873 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013874 * This function is used to delete the key information
13875 */
13876#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013877static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013878 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013879 u8 key_index,
13880 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013881 const u8 *mac_addr
13882 )
13883#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013884static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013885 struct net_device *ndev,
13886 u8 key_index,
13887 const u8 *mac_addr
13888 )
13889#endif
13890{
13891 int status = 0;
13892
13893 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013894 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013895 //it is observed that this is invalidating peer
13896 //key index whenever re-key is done. This is affecting data link.
13897 //It should be ok to ignore del_key.
13898#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013899 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13900 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013901 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13902 tCsrRoamSetKey setKey;
13903 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013904
Jeff Johnson295189b2012-06-20 16:38:30 -070013905 ENTER();
13906
13907 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13908 __func__,pAdapter->device_mode);
13909
13910 if (CSR_MAX_NUM_KEY <= key_index)
13911 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013912 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013913 key_index);
13914
13915 return -EINVAL;
13916 }
13917
13918 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13919 setKey.keyId = key_index;
13920
13921 if (mac_addr)
13922 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13923 else
13924 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13925
13926 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13927
13928 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013929 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013930 )
13931 {
13932
13933 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013934 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13935 if( pHostapdState->bssState == BSS_START)
13936 {
13937 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013938
Jeff Johnson295189b2012-06-20 16:38:30 -070013939 if ( status != eHAL_STATUS_SUCCESS )
13940 {
13941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13942 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13943 __LINE__, status );
13944 }
13945 }
13946 }
13947 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013948 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013949 )
13950 {
13951 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13952
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013953 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13954
13955 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013956 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013957 __func__, setKey.peerMac[0], setKey.peerMac[1],
13958 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013959 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013960 if(pAdapter->sessionCtx.station.conn_info.connState ==
13961 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013962 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013963 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013964 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013965
Jeff Johnson295189b2012-06-20 16:38:30 -070013966 if ( 0 != status )
13967 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013968 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013969 "%s: sme_RoamSetKey failure, returned %d",
13970 __func__, status);
13971 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13972 return -EINVAL;
13973 }
13974 }
13975 }
13976#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013977 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013978 return status;
13979}
13980
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013981#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13982static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13983 struct net_device *ndev,
13984 u8 key_index,
13985 bool pairwise,
13986 const u8 *mac_addr
13987 )
13988#else
13989static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13990 struct net_device *ndev,
13991 u8 key_index,
13992 const u8 *mac_addr
13993 )
13994#endif
13995{
13996 int ret;
13997
13998 vos_ssr_protect(__func__);
13999#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14000 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
14001 mac_addr);
14002#else
14003 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
14004#endif
14005 vos_ssr_unprotect(__func__);
14006
14007 return ret;
14008}
14009
Jeff Johnson295189b2012-06-20 16:38:30 -070014010/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014011 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070014012 * This function is used to set the default tx key index
14013 */
14014#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014015static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014016 struct net_device *ndev,
14017 u8 key_index,
14018 bool unicast, bool multicast)
14019#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014020static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014021 struct net_device *ndev,
14022 u8 key_index)
14023#endif
14024{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014025 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014026 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053014027 hdd_wext_state_t *pWextState;
14028 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014029 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014030
14031 ENTER();
14032
Gopichand Nakkala29149562013-05-10 21:43:41 +053014033 if ((NULL == pAdapter))
14034 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014035 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053014036 "invalid adapter");
14037 return -EINVAL;
14038 }
14039
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014040 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14041 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
14042 pAdapter->sessionId, key_index));
14043
Gopichand Nakkala29149562013-05-10 21:43:41 +053014044 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14045 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14046
14047 if ((NULL == pWextState) || (NULL == pHddStaCtx))
14048 {
14049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14050 "invalid Wext state or HDD context");
14051 return -EINVAL;
14052 }
14053
Arif Hussain6d2a3322013-11-17 19:50:10 -080014054 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014055 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014056
Jeff Johnson295189b2012-06-20 16:38:30 -070014057 if (CSR_MAX_NUM_KEY <= key_index)
14058 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014059 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014060 key_index);
14061
14062 return -EINVAL;
14063 }
14064
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014065 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14066 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014067 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014068 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014069 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014070 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014071
Jeff Johnson295189b2012-06-20 16:38:30 -070014072 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070014073 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014074 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014075 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053014076 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080014077 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080014078#ifdef FEATURE_WLAN_WAPI
14079 (eCSR_ENCRYPT_TYPE_WPI !=
14080 pHddStaCtx->conn_info.ucEncryptionType) &&
14081#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014082 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080014083 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070014084 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014085 {
14086 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070014087 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014088
Jeff Johnson295189b2012-06-20 16:38:30 -070014089 tCsrRoamSetKey setKey;
14090 v_U32_t roamId= 0xFF;
14091 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014092
14093 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014094 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014095
Jeff Johnson295189b2012-06-20 16:38:30 -070014096 Keys->defaultIndex = (u8)key_index;
14097 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
14098 setKey.keyId = key_index;
14099 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014100
14101 vos_mem_copy(&setKey.Key[0],
14102 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014103 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014104
Gopichand Nakkala29149562013-05-10 21:43:41 +053014105 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014106
14107 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070014108 &pHddStaCtx->conn_info.bssId[0],
14109 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014110
Gopichand Nakkala29149562013-05-10 21:43:41 +053014111 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
14112 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
14113 eCSR_ENCRYPT_TYPE_WEP104)
14114 {
14115 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
14116 even though ap is configured for WEP-40 encryption. In this canse the key length
14117 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
14118 type(104) and switching encryption type to 40*/
14119 pWextState->roamProfile.EncryptionType.encryptionType[0] =
14120 eCSR_ENCRYPT_TYPE_WEP40;
14121 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
14122 eCSR_ENCRYPT_TYPE_WEP40;
14123 }
14124
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014125 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014126 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014127
Jeff Johnson295189b2012-06-20 16:38:30 -070014128 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014129 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014130 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014131
Jeff Johnson295189b2012-06-20 16:38:30 -070014132 if ( 0 != status )
14133 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014134 hddLog(VOS_TRACE_LEVEL_ERROR,
14135 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014136 status);
14137 return -EINVAL;
14138 }
14139 }
14140 }
14141
14142 /* In SoftAp mode setting key direction for default mode */
14143 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
14144 {
14145 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
14146 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
14147 (eCSR_ENCRYPT_TYPE_AES !=
14148 pWextState->roamProfile.EncryptionType.encryptionType[0])
14149 )
14150 {
14151 /* Saving key direction for default key index to TX default */
14152 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
14153 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
14154 }
14155 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014156 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014157 return status;
14158}
14159
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014160#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14161static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14162 struct net_device *ndev,
14163 u8 key_index,
14164 bool unicast, bool multicast)
14165#else
14166static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14167 struct net_device *ndev,
14168 u8 key_index)
14169#endif
14170{
14171 int ret;
14172 vos_ssr_protect(__func__);
14173#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14174 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
14175 multicast);
14176#else
14177 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
14178#endif
14179 vos_ssr_unprotect(__func__);
14180
14181 return ret;
14182}
14183
Jeff Johnson295189b2012-06-20 16:38:30 -070014184/*
14185 * FUNCTION: wlan_hdd_cfg80211_inform_bss
14186 * This function is used to inform the BSS details to nl80211 interface.
14187 */
14188static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
14189 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
14190{
14191 struct net_device *dev = pAdapter->dev;
14192 struct wireless_dev *wdev = dev->ieee80211_ptr;
14193 struct wiphy *wiphy = wdev->wiphy;
14194 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
14195 int chan_no;
14196 int ie_length;
14197 const char *ie;
14198 unsigned int freq;
14199 struct ieee80211_channel *chan;
14200 int rssi = 0;
14201 struct cfg80211_bss *bss = NULL;
14202
Jeff Johnson295189b2012-06-20 16:38:30 -070014203 if( NULL == pBssDesc )
14204 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014205 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014206 return bss;
14207 }
14208
14209 chan_no = pBssDesc->channelId;
14210 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
14211 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
14212
14213 if( NULL == ie )
14214 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014215 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014216 return bss;
14217 }
14218
14219#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
14220 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
14221 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014222 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014223 }
14224 else
14225 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014226 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014227 }
14228#else
14229 freq = ieee80211_channel_to_frequency(chan_no);
14230#endif
14231
14232 chan = __ieee80211_get_channel(wiphy, freq);
14233
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053014234 if (!chan) {
14235 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
14236 return NULL;
14237 }
14238
Abhishek Singhaee43942014-06-16 18:55:47 +053014239 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070014240
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014241 return cfg80211_inform_bss(wiphy, chan,
14242#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14243 CFG80211_BSS_FTYPE_UNKNOWN,
14244#endif
14245 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014246 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070014247 pBssDesc->capabilityInfo,
14248 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053014249 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070014250}
14251
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014252/*
14253 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
14254 * interface that BSS might have been lost.
14255 * @pAdapter: adaptor
14256 * @bssid: bssid which might have been lost
14257 *
14258 * Return: bss which is unlinked from kernel cache
14259 */
14260struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
14261 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
14262{
14263 struct net_device *dev = pAdapter->dev;
14264 struct wireless_dev *wdev = dev->ieee80211_ptr;
14265 struct wiphy *wiphy = wdev->wiphy;
14266 struct cfg80211_bss *bss = NULL;
14267
Abhishek Singh5a597e62016-12-05 15:16:30 +053014268 bss = hdd_get_bss_entry(wiphy,
14269 NULL, bssid,
14270 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014271 if (bss == NULL) {
14272 hddLog(LOGE, FL("BSS not present"));
14273 } else {
14274 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
14275 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
14276 cfg80211_unlink_bss(wiphy, bss);
14277 }
14278 return bss;
14279}
Jeff Johnson295189b2012-06-20 16:38:30 -070014280
14281
14282/*
14283 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
14284 * This function is used to inform the BSS details to nl80211 interface.
14285 */
14286struct cfg80211_bss*
14287wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
14288 tSirBssDescription *bss_desc
14289 )
14290{
14291 /*
14292 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
14293 already exists in bss data base of cfg80211 for that particular BSS ID.
14294 Using cfg80211_inform_bss_frame to update the bss entry instead of
14295 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
14296 now there is no possibility to get the mgmt(probe response) frame from PE,
14297 converting bss_desc to ieee80211_mgmt(probe response) and passing to
14298 cfg80211_inform_bss_frame.
14299 */
14300 struct net_device *dev = pAdapter->dev;
14301 struct wireless_dev *wdev = dev->ieee80211_ptr;
14302 struct wiphy *wiphy = wdev->wiphy;
14303 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014304#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14305 qcom_ie_age *qie_age = NULL;
14306 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
14307#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014308 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014309#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014310 const char *ie =
14311 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
14312 unsigned int freq;
14313 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014314 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014315 struct cfg80211_bss *bss_status = NULL;
Hanumanth Reddy Pothulae04e06c2018-05-31 14:41:36 +053014316 size_t frame_len = ie_length + offsetof(struct ieee80211_mgmt,
14317 u.probe_resp.variable);
Jeff Johnson295189b2012-06-20 16:38:30 -070014318 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070014319 hdd_context_t *pHddCtx;
14320 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070014321#ifdef WLAN_OPEN_SOURCE
14322 struct timespec ts;
14323#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014324
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014325
Wilson Yangf80a0542013-10-07 13:02:37 -070014326 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14327 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070014328 if (0 != status)
14329 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014330 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014331 }
14332
Hanumanth Reddy Pothula33548e22018-05-31 13:28:51 +053014333 mgmt = kzalloc(frame_len, GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070014334 if (!mgmt)
14335 {
14336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14337 "%s: memory allocation failed ", __func__);
14338 return NULL;
14339 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014340
Jeff Johnson295189b2012-06-20 16:38:30 -070014341 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014342
14343#ifdef WLAN_OPEN_SOURCE
14344 /* Android does not want the timestamp from the frame.
14345 Instead it wants a monotonic increasing value */
14346 get_monotonic_boottime(&ts);
14347 mgmt->u.probe_resp.timestamp =
14348 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
14349#else
14350 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014351 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
14352 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070014353
14354#endif
14355
Jeff Johnson295189b2012-06-20 16:38:30 -070014356 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
14357 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014358
14359#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14360 /* GPS Requirement: need age ie per entry. Using vendor specific. */
14361 /* Assuming this is the last IE, copy at the end */
14362 ie_length -=sizeof(qcom_ie_age);
14363 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
14364 qie_age->element_id = QCOM_VENDOR_IE_ID;
14365 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
14366 qie_age->oui_1 = QCOM_OUI1;
14367 qie_age->oui_2 = QCOM_OUI2;
14368 qie_age->oui_3 = QCOM_OUI3;
14369 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053014370 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
14371 * bss related timestamp is in units of ms. Due to this when scan results
14372 * are sent to lowi the scan age is high.To address this, send age in units
14373 * of 1/10 ms.
14374 */
14375 qie_age->age = (vos_timer_get_system_time() -
14376 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014377#endif
14378
Jeff Johnson295189b2012-06-20 16:38:30 -070014379 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053014380 if (bss_desc->fProbeRsp)
14381 {
14382 mgmt->frame_control |=
14383 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
14384 }
14385 else
14386 {
14387 mgmt->frame_control |=
14388 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
14389 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014390
14391#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014392 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014393 (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014394 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014395 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014396 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014397 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014398 (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014399
14400 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014401 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014402 }
14403 else
14404 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014405 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
14406 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070014407 kfree(mgmt);
14408 return NULL;
14409 }
14410#else
14411 freq = ieee80211_channel_to_frequency(chan_no);
14412#endif
14413 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014414 /*when the band is changed on the fly using the GUI, three things are done
14415 * 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)
14416 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
14417 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
14418 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
14419 * and discards the channels correponding to previous band and calls back with zero bss results.
14420 * 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
14421 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
14422 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
14423 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
14424 * So drop the bss and continue to next bss.
14425 */
14426 if(chan == NULL)
14427 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053014428 hddLog(VOS_TRACE_LEVEL_ERROR,
14429 FL("chan pointer is NULL, chan_no: %d freq: %d"),
14430 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070014431 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014432 return NULL;
14433 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053014434 /*To keep the rssi icon of the connected AP in the scan window
14435 *and the rssi icon of the wireless networks in sync
14436 * */
14437 if (( eConnectionState_Associated ==
14438 pAdapter->sessionCtx.station.conn_info.connState ) &&
14439 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
14440 pAdapter->sessionCtx.station.conn_info.bssId,
14441 WNI_CFG_BSSID_LEN)) &&
14442 (pHddCtx->hdd_wlan_suspended == FALSE))
14443 {
14444 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
14445 rssi = (pAdapter->rssi * 100);
14446 }
14447 else
14448 {
14449 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
14450 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014451
Nirav Shah20ac06f2013-12-12 18:14:06 +053014452 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053014453 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
14454 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053014455
Jeff Johnson295189b2012-06-20 16:38:30 -070014456 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
14457 frame_len, rssi, GFP_KERNEL);
14458 kfree(mgmt);
14459 return bss_status;
14460}
14461
14462/*
14463 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
14464 * This function is used to update the BSS data base of CFG8011
14465 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014466struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014467 tCsrRoamInfo *pRoamInfo
14468 )
14469{
14470 tCsrRoamConnectedProfile roamProfile;
14471 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14472 struct cfg80211_bss *bss = NULL;
14473
14474 ENTER();
14475
14476 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
14477 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
14478
14479 if (NULL != roamProfile.pBssDesc)
14480 {
Girish Gowlif4b68022014-08-28 23:18:57 +053014481 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14482 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070014483
14484 if (NULL == bss)
14485 {
14486 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
14487 __func__);
14488 }
14489
14490 sme_RoamFreeConnectProfile(hHal, &roamProfile);
14491 }
14492 else
14493 {
14494 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
14495 __func__);
14496 }
14497 return bss;
14498}
14499
14500/*
14501 * FUNCTION: wlan_hdd_cfg80211_update_bss
14502 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014503static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
14504 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070014505 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014506{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014507 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014508 tCsrScanResultInfo *pScanResult;
14509 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014510 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014511 tScanResultHandle pResult;
14512 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014513 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014514 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070014515 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014516
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014517 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14518 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
14519 NO_SESSION, pAdapter->sessionId));
14520
Wilson Yangf80a0542013-10-07 13:02:37 -070014521 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014522 ret = wlan_hdd_validate_context(pHddCtx);
14523 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070014524 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014525 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070014526 }
14527
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014528 if (pAdapter->request != NULL)
14529 {
14530 if ((pAdapter->request->n_ssids == 1)
14531 && (pAdapter->request->ssids != NULL)
14532 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
14533 is_p2p_scan = true;
14534 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014535 /*
14536 * start getting scan results and populate cgf80211 BSS database
14537 */
14538 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
14539
14540 /* no scan results */
14541 if (NULL == pResult)
14542 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014543 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
14544 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014545 wlan_hdd_get_frame_logs(pAdapter,
14546 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070014547 return status;
14548 }
14549
14550 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
14551
14552 while (pScanResult)
14553 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014554 /*
14555 * cfg80211_inform_bss() is not updating ie field of bss entry, if
14556 * entry already exists in bss data base of cfg80211 for that
14557 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
14558 * bss entry instead of cfg80211_inform_bss, But this call expects
14559 * mgmt packet as input. As of now there is no possibility to get
14560 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070014561 * ieee80211_mgmt(probe response) and passing to c
14562 * fg80211_inform_bss_frame.
14563 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014564 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
14565 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
14566 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014567 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14568 continue; //Skip the non p2p bss entries
14569 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014570 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14571 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014572
Jeff Johnson295189b2012-06-20 16:38:30 -070014573
14574 if (NULL == bss_status)
14575 {
14576 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014577 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014578 }
14579 else
14580 {
Yue Maf49ba872013-08-19 12:04:25 -070014581 cfg80211_put_bss(
14582#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
14583 wiphy,
14584#endif
14585 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070014586 }
14587
14588 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14589 }
14590
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014591 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014592 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014593 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014594}
14595
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014596void
14597hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
14598{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014599 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080014600 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014601} /****** end hddPrintMacAddr() ******/
14602
14603void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014604hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014605{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014606 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014607 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014608 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
14609 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
14610 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014611} /****** end hddPrintPmkId() ******/
14612
14613//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
14614//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
14615
14616//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
14617//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
14618
14619#define dump_bssid(bssid) \
14620 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014621 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
14622 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014623 }
14624
14625#define dump_pmkid(pMac, pmkid) \
14626 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014627 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
14628 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014629 }
14630
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070014631#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014632/*
14633 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
14634 * This function is used to notify the supplicant of a new PMKSA candidate.
14635 */
14636int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014637 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014638 int index, bool preauth )
14639{
Jeff Johnsone7245742012-09-05 17:12:55 -070014640#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014641 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014642 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014643
14644 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070014645 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014646
14647 if( NULL == pRoamInfo )
14648 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014649 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014650 return -EINVAL;
14651 }
14652
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014653 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
14654 {
14655 dump_bssid(pRoamInfo->bssid);
14656 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014657 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014658 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014659#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014660 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014661}
14662#endif //FEATURE_WLAN_LFR
14663
Yue Maef608272013-04-08 23:09:17 -070014664#ifdef FEATURE_WLAN_LFR_METRICS
14665/*
14666 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
14667 * 802.11r/LFR metrics reporting function to report preauth initiation
14668 *
14669 */
14670#define MAX_LFR_METRICS_EVENT_LENGTH 100
14671VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
14672 tCsrRoamInfo *pRoamInfo)
14673{
14674 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14675 union iwreq_data wrqu;
14676
14677 ENTER();
14678
14679 if (NULL == pAdapter)
14680 {
14681 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14682 return VOS_STATUS_E_FAILURE;
14683 }
14684
14685 /* create the event */
14686 memset(&wrqu, 0, sizeof(wrqu));
14687 memset(metrics_notification, 0, sizeof(metrics_notification));
14688
14689 wrqu.data.pointer = metrics_notification;
14690 wrqu.data.length = scnprintf(metrics_notification,
14691 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
14692 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14693
14694 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14695
14696 EXIT();
14697
14698 return VOS_STATUS_SUCCESS;
14699}
14700
14701/*
14702 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
14703 * 802.11r/LFR metrics reporting function to report preauth completion
14704 * or failure
14705 */
14706VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
14707 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
14708{
14709 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14710 union iwreq_data wrqu;
14711
14712 ENTER();
14713
14714 if (NULL == pAdapter)
14715 {
14716 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14717 return VOS_STATUS_E_FAILURE;
14718 }
14719
14720 /* create the event */
14721 memset(&wrqu, 0, sizeof(wrqu));
14722 memset(metrics_notification, 0, sizeof(metrics_notification));
14723
14724 scnprintf(metrics_notification, sizeof(metrics_notification),
14725 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
14726 MAC_ADDR_ARRAY(pRoamInfo->bssid));
14727
14728 if (1 == preauth_status)
14729 strncat(metrics_notification, " TRUE", 5);
14730 else
14731 strncat(metrics_notification, " FALSE", 6);
14732
14733 wrqu.data.pointer = metrics_notification;
14734 wrqu.data.length = strlen(metrics_notification);
14735
14736 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14737
14738 EXIT();
14739
14740 return VOS_STATUS_SUCCESS;
14741}
14742
14743/*
14744 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
14745 * 802.11r/LFR metrics reporting function to report handover initiation
14746 *
14747 */
14748VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
14749 tCsrRoamInfo *pRoamInfo)
14750{
14751 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14752 union iwreq_data wrqu;
14753
14754 ENTER();
14755
14756 if (NULL == pAdapter)
14757 {
14758 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14759 return VOS_STATUS_E_FAILURE;
14760 }
14761
14762 /* create the event */
14763 memset(&wrqu, 0, sizeof(wrqu));
14764 memset(metrics_notification, 0, sizeof(metrics_notification));
14765
14766 wrqu.data.pointer = metrics_notification;
14767 wrqu.data.length = scnprintf(metrics_notification,
14768 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14769 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14770
14771 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14772
14773 EXIT();
14774
14775 return VOS_STATUS_SUCCESS;
14776}
14777#endif
14778
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014779
14780/**
14781 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14782 * @scan_req: scan request to be checked
14783 *
14784 * Return: true or false
14785 */
14786#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14787static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14788 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014789 *scan_req, hdd_context_t
14790 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014791{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014792 if (!scan_req || !scan_req->wiphy ||
14793 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014794 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14795 return false;
14796 }
14797 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14798 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14799 return false;
14800 }
14801 return true;
14802}
14803#else
14804static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14805 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014806 *scan_req, hdd_context_t
14807 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014808{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014809 if (!scan_req || !scan_req->wiphy ||
14810 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014811 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14812 return false;
14813 }
14814 return true;
14815}
14816#endif
14817
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014818#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
14819/**
14820 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14821 * @adapter: Pointer to the adapter
14822 * @req : Scan request
14823 * @aborted : true scan aborted false scan success
14824 *
14825 * This function notifies scan done to cfg80211
14826 *
14827 * Return: none
14828 */
14829static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14830 struct cfg80211_scan_request *req,
14831 bool aborted)
14832{
14833 struct cfg80211_scan_info info = {
14834 .aborted = aborted
14835 };
14836
14837 if (adapter->dev->flags & IFF_UP)
14838 cfg80211_scan_done(req, &info);
14839 else
14840 hddLog(LOGW,
14841 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14842}
14843#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14844/**
14845 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14846 * @adapter: Pointer to the adapter
14847 * @req : Scan request
14848 * @aborted : true scan aborted false scan success
14849 *
14850 * This function notifies scan done to cfg80211
14851 *
14852 * Return: none
14853 */
14854static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14855 struct cfg80211_scan_request *req,
14856 bool aborted)
14857{
14858 if (adapter->dev->flags & IFF_UP)
14859 cfg80211_scan_done(req, aborted);
14860 else
14861 hddLog(LOGW,
14862 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14863}
14864#else
14865/**
14866 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14867 * @adapter: Pointer to the adapter
14868 * @req : Scan request
14869 * @aborted : true scan aborted false scan success
14870 *
14871 * This function notifies scan done to cfg80211
14872 *
14873 * Return: none
14874 */
14875static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14876 struct cfg80211_scan_request *req,
14877 bool aborted)
14878{
14879 cfg80211_scan_done(req, aborted);
14880}
14881#endif
14882
Mukul Sharmab392b642017-08-17 17:45:29 +053014883#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014884/*
14885 * FUNCTION: hdd_cfg80211_scan_done_callback
14886 * scanning callback function, called after finishing scan
14887 *
14888 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014889static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014890 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14891{
14892 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014893 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014894 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014895 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014896 struct cfg80211_scan_request *req = NULL;
14897 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014898 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014899 long waitRet = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014900 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014901
14902 ENTER();
14903
c_manjee1b4ab9a2016-10-26 11:36:55 +053014904 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14905 !pAdapter->dev) {
14906 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14907 return 0;
14908 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014909 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014910 if (NULL == pHddCtx) {
14911 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014912 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014913 }
14914
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014915#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014916 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014917 {
14918 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014919 }
14920#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014921 pScanInfo = &pHddCtx->scan_info;
14922
Jeff Johnson295189b2012-06-20 16:38:30 -070014923 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014924 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014925 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014926 __func__, halHandle, pContext, (int) scanId, (int) status);
14927
Kiet Lamac06e2c2013-10-23 16:25:07 +053014928 pScanInfo->mScanPendingCounter = 0;
14929
Jeff Johnson295189b2012-06-20 16:38:30 -070014930 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014931 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014932 &pScanInfo->scan_req_completion_event,
14933 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014934 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014935 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014936 hddLog(VOS_TRACE_LEVEL_ERROR,
14937 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014938 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014939 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014940 }
14941
Yue Maef608272013-04-08 23:09:17 -070014942 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014943 {
14944 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014945 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014946 }
14947
14948 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014949 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014950 {
14951 hddLog(VOS_TRACE_LEVEL_INFO,
14952 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014953 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014954 (int) scanId);
14955 }
14956
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014957#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014958 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014959#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014960 {
14961 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14962 pAdapter);
14963 if (0 > ret)
14964 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014965 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014966
Jeff Johnson295189b2012-06-20 16:38:30 -070014967 /* If any client wait scan result through WEXT
14968 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014969 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014970 {
14971 /* The other scan request waiting for current scan finish
14972 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014973 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014974 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014975 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014976 }
14977 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014978 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014979 {
14980 struct net_device *dev = pAdapter->dev;
14981 union iwreq_data wrqu;
14982 int we_event;
14983 char *msg;
14984
14985 memset(&wrqu, '\0', sizeof(wrqu));
14986 we_event = SIOCGIWSCAN;
14987 msg = NULL;
14988 wireless_send_event(dev, we_event, &wrqu, msg);
14989 }
14990 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014991 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014992
14993 /* Get the Scan Req */
14994 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014995 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014996
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014997 /* Scan is no longer pending */
14998 pScanInfo->mScanPending = VOS_FALSE;
14999
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053015000 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070015001 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053015002#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
15003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053015004 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053015005#endif
15006
15007 if (pAdapter->dev) {
15008 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
15009 pAdapter->dev->name);
15010 }
mukul sharmae7041822015-12-03 15:09:21 +053015011 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070015012 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070015013 }
15014
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015015 /* last_scan_timestamp is used to decide if new scan
15016 * is needed or not on station interface. If last station
15017 * scan time and new station scan time is less then
15018 * last_scan_timestamp ; driver will return cached scan.
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015019 * Also only last_scan_timestamp is updated here last_scan_channellist
15020 * is updated on receiving scan request itself to make sure kernel
15021 * allocated scan request(scan_req) object is not dereferenced here,
15022 * because interface down, where kernel frees scan_req, may happen any
15023 * time while driver is processing scan_done_callback. So it's better
15024 * not to access scan_req in this routine.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015025 */
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015026 if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
15027 if (status == eCSR_SCAN_SUCCESS)
15028 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
15029 else {
15030 vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
15031 sizeof(pHddCtx->scan_info.last_scan_channelList));
15032 pHddCtx->scan_info.last_scan_numChannels = 0;
15033 pScanInfo->last_scan_timestamp = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015034 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015035 }
15036
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070015037 /*
15038 * cfg80211_scan_done informing NL80211 about completion
15039 * of scanning
15040 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015041 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
15042 {
15043 aborted = true;
15044 }
mukul sharmae7041822015-12-03 15:09:21 +053015045
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015046#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015047 if (NET_DEV_IS_IFF_UP(pAdapter) &&
15048 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015049#endif
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015050 hdd_cfg80211_scan_done(pAdapter, req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053015051
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080015052 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070015053
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015054allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015055 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
15056 ) && (pHddCtx->spoofMacAddr.isEnabled
15057 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053015058 /* Generate new random mac addr for next scan */
15059 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053015060
15061 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
15062 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053015063 }
15064
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015065 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015066 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015067
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015068 /* Acquire wakelock to handle the case where APP's tries to suspend
15069 * immediatly after the driver gets connect request(i.e after scan)
15070 * from supplicant, this result in app's is suspending and not able
15071 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015072 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015073
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015074#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015075 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015076#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015077#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015078 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015079#endif
15080
Jeff Johnson295189b2012-06-20 16:38:30 -070015081 EXIT();
15082 return 0;
15083}
15084
15085/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053015086 * FUNCTION: hdd_isConnectionInProgress
15087 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015088 *
15089 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015090v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
15091 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015092{
15093 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15094 hdd_station_ctx_t *pHddStaCtx = NULL;
15095 hdd_adapter_t *pAdapter = NULL;
15096 VOS_STATUS status = 0;
15097 v_U8_t staId = 0;
15098 v_U8_t *staMac = NULL;
15099
15100 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15101
15102 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15103 {
15104 pAdapter = pAdapterNode->pAdapter;
15105
15106 if( pAdapter )
15107 {
15108 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015109 "%s: Adapter with device mode %s (%d) exists",
15110 __func__, hdd_device_modetoString(pAdapter->device_mode),
15111 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015112 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053015113 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15114 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
15115 (eConnectionState_Connecting ==
15116 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
15117 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015118 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015119 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053015120 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015121 if (session_id && reason)
15122 {
15123 *session_id = pAdapter->sessionId;
15124 *reason = eHDD_CONNECTION_IN_PROGRESS;
15125 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015126 return VOS_TRUE;
15127 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015128 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053015129 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015130 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015131 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015132 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015133 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015134 if (session_id && reason)
15135 {
15136 *session_id = pAdapter->sessionId;
15137 *reason = eHDD_REASSOC_IN_PROGRESS;
15138 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015139 return VOS_TRUE;
15140 }
15141 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015142 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15143 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015144 {
15145 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15146 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Vignesh Viswanathan0ac8e562018-06-14 17:24:10 +053015147 sme_is_sta_key_exchange_in_progress(pHddCtx->hHal,
15148 pAdapter->sessionId))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015149 {
15150 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015151 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015152 "%s: client " MAC_ADDRESS_STR
15153 " is in the middle of WPS/EAPOL exchange.", __func__,
15154 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015155 if (session_id && reason)
15156 {
15157 *session_id = pAdapter->sessionId;
15158 *reason = eHDD_EAPOL_IN_PROGRESS;
15159 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015160 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015161 }
15162 }
15163 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
15164 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
15165 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015166 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15167 ptSapContext pSapCtx = NULL;
15168 pSapCtx = VOS_GET_SAP_CB(pVosContext);
15169 if(pSapCtx == NULL){
15170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15171 FL("psapCtx is NULL"));
15172 return VOS_FALSE;
15173 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015174 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
15175 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015176 if ((pSapCtx->aStaInfo[staId].isUsed) &&
15177 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015178 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015179 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015180
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015181 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015182 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
15183 "middle of WPS/EAPOL exchange.", __func__,
15184 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015185 if (session_id && reason)
15186 {
15187 *session_id = pAdapter->sessionId;
15188 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
15189 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015190 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015191 }
15192 }
15193 }
15194 }
15195 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15196 pAdapterNode = pNext;
15197 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015198 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015199}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015200
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015201/**
15202 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
15203 * to the Scan request
15204 * @scanRequest: Pointer to the csr scan request
15205 * @request: Pointer to the scan request from supplicant
15206 *
15207 * Return: None
15208 */
15209#ifdef CFG80211_SCAN_BSSID
15210static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15211 struct cfg80211_scan_request *request)
15212{
15213 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
15214}
15215#else
15216static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15217 struct cfg80211_scan_request *request)
15218{
15219}
15220#endif
15221
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015222/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015223 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070015224 * this scan respond to scan trigger and update cfg80211 scan database
15225 * later, scan dump command can be used to recieve scan results
15226 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015227int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015228#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15229 struct net_device *dev,
15230#endif
15231 struct cfg80211_scan_request *request)
15232{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015233 hdd_adapter_t *pAdapter = NULL;
15234 hdd_context_t *pHddCtx = NULL;
15235 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015236 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015237 tCsrScanRequest scanRequest;
15238 tANI_U8 *channelList = NULL, i;
15239 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015240 int status;
15241 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015242 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015243 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053015244 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015245 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015246 v_U8_t curr_session_id;
15247 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070015248
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015249#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
15250 struct net_device *dev = NULL;
15251 if (NULL == request)
15252 {
15253 hddLog(VOS_TRACE_LEVEL_ERROR,
15254 "%s: scan req param null", __func__);
15255 return -EINVAL;
15256 }
15257 dev = request->wdev->netdev;
15258#endif
15259
15260 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15261 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
15262 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15263
Jeff Johnson295189b2012-06-20 16:38:30 -070015264 ENTER();
15265
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015266 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
15267 __func__, hdd_device_modetoString(pAdapter->device_mode),
15268 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015269
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015270 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015271 if (0 != status)
15272 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015273 return status;
15274 }
15275
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015276 if (NULL == pwextBuf)
15277 {
15278 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
15279 __func__);
15280 return -EIO;
15281 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015282 cfg_param = pHddCtx->cfg_ini;
15283 pScanInfo = &pHddCtx->scan_info;
15284
Jeff Johnson295189b2012-06-20 16:38:30 -070015285#ifdef WLAN_BTAMP_FEATURE
15286 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015287 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070015288 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015289 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015290 "%s: No scanning when AMP is on", __func__);
15291 return -EOPNOTSUPP;
15292 }
15293#endif
15294 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015295 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070015296 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015297 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015298 "%s: Not scanning on device_mode = %s (%d)",
15299 __func__, hdd_device_modetoString(pAdapter->device_mode),
15300 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015301 return -EOPNOTSUPP;
15302 }
15303
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015304 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
15305 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
15306 return -EOPNOTSUPP;
15307 }
15308
Jeff Johnson295189b2012-06-20 16:38:30 -070015309 if (TRUE == pScanInfo->mScanPending)
15310 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015311 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
15312 {
15313 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
15314 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015315 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015316 }
15317
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053015318 // Don't allow scan if PNO scan is going on.
15319 if (pHddCtx->isPnoEnable)
15320 {
15321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15322 FL("pno scan in progress"));
15323 return -EBUSY;
15324 }
15325
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015326 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070015327 //Channel and action frame is pending
15328 //Otherwise Cancel Remain On Channel and allow Scan
15329 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015330 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070015331 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015332 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070015333 return -EBUSY;
15334 }
15335
Jeff Johnson295189b2012-06-20 16:38:30 -070015336 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
15337 {
15338 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080015339 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015340 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015341 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015342 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
15343 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015344 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015345 "%s: MAX TM Level Scan not allowed", __func__);
15346 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015347 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015348 }
15349 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
15350
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015351 /* Check if scan is allowed at this point of time.
15352 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053015353 if (TRUE == pHddCtx->btCoexModeSet)
15354 {
15355 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15356 FL("BTCoex Mode operation in progress"));
15357 return -EBUSY;
15358 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015359 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015360 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015361
15362 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
15363 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
15364 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015365 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
15366 pHddCtx->last_scan_reject_reason != curr_reason ||
15367 !pHddCtx->last_scan_reject_timestamp)
15368 {
15369 pHddCtx->last_scan_reject_session_id = curr_session_id;
15370 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053015371 pHddCtx->last_scan_reject_timestamp =
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015372 jiffies + msecs_to_jiffies(SCAN_REJECT_THRESHOLD_TIME);
Abhishek Singhe4b12562017-06-20 16:53:39 +053015373 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053015374 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053015375 else
15376 {
15377 pHddCtx->scan_reject_cnt++;
15378
Abhishek Singhe4b12562017-06-20 16:53:39 +053015379 if ((pHddCtx->scan_reject_cnt >=
15380 SCAN_REJECT_THRESHOLD) &&
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015381 vos_system_time_after(jiffies,
Abhishek Singh3e500772017-07-17 10:13:43 +053015382 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015383 {
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015384 hddLog(LOGE, FL("Session %d reason %d reject cnt %d reject timestamp %lu jiffies %lu"),
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015385 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015386 pHddCtx->last_scan_reject_timestamp, jiffies);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015387 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015388 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015389 if (pHddCtx->cfg_ini->enableFatalEvent)
15390 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
15391 WLAN_LOG_INDICATOR_HOST_DRIVER,
15392 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
15393 FALSE, FALSE);
15394 else
15395 {
15396 hddLog(LOGE, FL("Triggering SSR"));
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +053015397 vos_wlanRestart(VOS_SCAN_REQ_EXPIRED);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015398 }
15399 }
15400 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015401 return -EBUSY;
15402 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015403 pHddCtx->last_scan_reject_timestamp = 0;
15404 pHddCtx->last_scan_reject_session_id = 0xFF;
15405 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015406 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015407
Jeff Johnson295189b2012-06-20 16:38:30 -070015408 vos_mem_zero( &scanRequest, sizeof(scanRequest));
15409
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015410 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
15411 * Becasue of this, driver is assuming that this is not wildcard scan and so
15412 * is not aging out the scan results.
15413 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053015414 if ((request->ssids) && (request->n_ssids == 1) &&
15415 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015416 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015417 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015418
15419 if ((request->ssids) && (0 < request->n_ssids))
15420 {
15421 tCsrSSIDInfo *SsidInfo;
15422 int j;
15423 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
15424 /* Allocate num_ssid tCsrSSIDInfo structure */
15425 SsidInfo = scanRequest.SSIDs.SSIDList =
15426 ( tCsrSSIDInfo *)vos_mem_malloc(
15427 request->n_ssids*sizeof(tCsrSSIDInfo));
15428
15429 if(NULL == scanRequest.SSIDs.SSIDList)
15430 {
15431 hddLog(VOS_TRACE_LEVEL_ERROR,
15432 "%s: memory alloc failed SSIDInfo buffer", __func__);
15433 return -ENOMEM;
15434 }
15435
15436 /* copy all the ssid's and their length */
15437 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
15438 {
15439 /* get the ssid length */
15440 SsidInfo->SSID.length = request->ssids[j].ssid_len;
15441 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
15442 SsidInfo->SSID.length);
15443 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
15444 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
15445 j, SsidInfo->SSID.ssId);
15446 }
15447 /* set the scan type to active */
15448 scanRequest.scanType = eSIR_ACTIVE_SCAN;
15449 }
15450 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015451 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015452 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15453 TRACE_CODE_HDD_CFG80211_SCAN,
15454 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070015455 /* set the scan type to active */
15456 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070015457 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015458 else
15459 {
15460 /*Set the scan type to default type, in this case it is ACTIVE*/
15461 scanRequest.scanType = pScanInfo->scan_mode;
15462 }
15463 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
15464 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070015465
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015466 csr_scan_request_assign_bssid(&scanRequest, request);
15467
Jeff Johnson295189b2012-06-20 16:38:30 -070015468 /* set BSSType to default type */
15469 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
15470
15471 /*TODO: scan the requested channels only*/
15472
15473 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015474 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070015475 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015476 hddLog(VOS_TRACE_LEVEL_WARN,
15477 "No of Scan Channels exceeded limit: %d", request->n_channels);
15478 request->n_channels = MAX_CHANNEL;
15479 }
15480
15481 hddLog(VOS_TRACE_LEVEL_INFO,
15482 "No of Scan Channels: %d", request->n_channels);
15483
15484
15485 if( request->n_channels )
15486 {
15487 char chList [(request->n_channels*5)+1];
15488 int len;
15489 channelList = vos_mem_malloc( request->n_channels );
15490 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053015491 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015492 hddLog(VOS_TRACE_LEVEL_ERROR,
15493 "%s: memory alloc failed channelList", __func__);
15494 status = -ENOMEM;
15495 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053015496 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015497
15498 for( i = 0, len = 0; i < request->n_channels ; i++ )
15499 {
15500 channelList[i] = request->channels[i]->hw_value;
15501 len += snprintf(chList+len, 5, "%d ", channelList[i]);
15502 }
15503
Nirav Shah20ac06f2013-12-12 18:14:06 +053015504 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015505 "Channel-List: %s ", chList);
15506 }
c_hpothu53512302014-04-15 18:49:53 +053015507
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015508 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
15509 scanRequest.ChannelInfo.ChannelList = channelList;
15510
15511 /* set requestType to full scan */
15512 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
15513
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015514 /* if there is back to back scan happening in driver with in
15515 * nDeferScanTimeInterval interval driver should defer new scan request
15516 * and should provide last cached scan results instead of new channel list.
15517 * This rule is not applicable if scan is p2p scan.
15518 * This condition will work only in case when last request no of channels
15519 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053015520 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053015521 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015522 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015523
Sushant Kaushik86592172015-04-27 16:35:03 +053015524 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
15525 /* if wps ie is NULL , then only defer scan */
15526 if ( pWpsIe == NULL &&
15527 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053015528 {
15529 if ( pScanInfo->last_scan_timestamp !=0 &&
15530 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
15531 {
15532 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
15533 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
15534 vos_mem_compare(pScanInfo->last_scan_channelList,
15535 channelList, pScanInfo->last_scan_numChannels))
15536 {
15537 hddLog(VOS_TRACE_LEVEL_WARN,
15538 " New and old station scan time differ is less then %u",
15539 pHddCtx->cfg_ini->nDeferScanTimeInterval);
15540
15541 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015542 pAdapter);
15543
Agarwal Ashish57e84372014-12-05 18:26:53 +053015544 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015545 "Return old cached scan as all channels and no of channels are same");
15546
Agarwal Ashish57e84372014-12-05 18:26:53 +053015547 if (0 > ret)
15548 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015549
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015550 hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015551
15552 status = eHAL_STATUS_SUCCESS;
15553 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053015554 }
15555 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015556 }
15557
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015558 /* Flush the scan results(only p2p beacons) for STA scan and P2P
15559 * search (Flush on both full scan and social scan but not on single
15560 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
15561 */
15562
15563 /* Supplicant does single channel scan after 8-way handshake
15564 * and in that case driver shoudnt flush scan results. If
15565 * driver flushes the scan results here and unfortunately if
15566 * the AP doesnt respond to our probe req then association
15567 * fails which is not desired
15568 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015569 if ((request->n_ssids == 1)
15570 && (request->ssids != NULL)
15571 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
15572 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015573
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015574 if( is_p2p_scan ||
15575 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015576 {
15577 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
15578 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
15579 pAdapter->sessionId );
15580 }
15581
15582 if( request->ie_len )
15583 {
15584 /* save this for future association (join requires this) */
15585 /*TODO: Array needs to be converted to dynamic allocation,
15586 * as multiple ie.s can be sent in cfg80211_scan_request structure
15587 * CR 597966
15588 */
15589 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
15590 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
15591 pScanInfo->scanAddIE.length = request->ie_len;
15592
15593 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15594 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15595 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015596 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015597 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070015598 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015599 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
15600 memcpy( pwextBuf->roamProfile.addIEScan,
15601 request->ie, request->ie_len);
15602 }
15603 else
15604 {
15605 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
15606 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070015607 }
15608
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015609 }
15610 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
15611 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
15612
15613 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
15614 request->ie_len);
15615 if (pP2pIe != NULL)
15616 {
15617#ifdef WLAN_FEATURE_P2P_DEBUG
15618 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
15619 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
15620 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053015621 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015622 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
15623 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15624 "Go nego completed to Connection is started");
15625 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15626 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053015627 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015628 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
15629 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015630 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015631 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
15632 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15633 "Disconnected state to Connection is started");
15634 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15635 "for 4way Handshake");
15636 }
15637#endif
15638
15639 /* no_cck will be set during p2p find to disable 11b rates */
15640 if(TRUE == request->no_cck)
15641 {
15642 hddLog(VOS_TRACE_LEVEL_INFO,
15643 "%s: This is a P2P Search", __func__);
15644 scanRequest.p2pSearch = 1;
15645
15646 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053015647 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015648 /* set requestType to P2P Discovery */
15649 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
15650 }
15651
15652 /*
15653 Skip Dfs Channel in case of P2P Search
15654 if it is set in ini file
15655 */
15656 if(cfg_param->skipDfsChnlInP2pSearch)
15657 {
15658 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015659 }
15660 else
15661 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015662 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015663 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015664
Agarwal Ashish4f616132013-12-30 23:32:50 +053015665 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015666 }
15667 }
15668
15669 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
15670
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015671#ifdef FEATURE_WLAN_TDLS
15672 /* if tdls disagree scan right now, return immediately.
15673 tdls will schedule the scan when scan is allowed. (return SUCCESS)
15674 or will reject the scan if any TDLS is in progress. (return -EBUSY)
15675 */
15676 status = wlan_hdd_tdls_scan_callback (pAdapter,
15677 wiphy,
15678#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15679 dev,
15680#endif
15681 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015682 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015683 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053015684 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015685 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
15686 "scan rejected %d", __func__, status);
15687 else
15688 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
15689 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015690 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053015691 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015692 }
15693#endif
15694
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015695 /* acquire the wakelock to avoid the apps suspend during the scan. To
15696 * address the following issues.
15697 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
15698 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
15699 * for long time, this result in apps running at full power for long time.
15700 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
15701 * be stuck in full power because of resume BMPS
15702 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015703 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015704
Nirav Shah20ac06f2013-12-12 18:14:06 +053015705 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
15706 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015707 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
15708 scanRequest.requestType, scanRequest.scanType,
15709 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053015710 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
15711
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015712 if (pHddCtx->spoofMacAddr.isEnabled &&
15713 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053015714 {
15715 hddLog(VOS_TRACE_LEVEL_INFO,
15716 "%s: MAC Spoofing enabled for current scan", __func__);
15717 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15718 * to fill TxBds for probe request during current scan
15719 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015720 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053015721 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015722
15723 if(status != VOS_STATUS_SUCCESS)
15724 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015725 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015726 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053015727#ifdef FEATURE_WLAN_TDLS
15728 wlan_hdd_tdls_scan_done_callback(pAdapter);
15729#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015730 goto free_mem;
15731 }
Siddharth Bhal76972212014-10-15 16:22:51 +053015732 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053015733 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070015734 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015735 pAdapter->sessionId, &scanRequest, &scanId,
15736 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070015737
Jeff Johnson295189b2012-06-20 16:38:30 -070015738 if (eHAL_STATUS_SUCCESS != status)
15739 {
15740 hddLog(VOS_TRACE_LEVEL_ERROR,
15741 "%s: sme_ScanRequest returned error %d", __func__, status);
15742 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015743 if(eHAL_STATUS_RESOURCES == status)
15744 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015745 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
15746 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015747 status = -EBUSY;
15748 } else {
15749 status = -EIO;
15750 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015751 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015752
15753#ifdef FEATURE_WLAN_TDLS
15754 wlan_hdd_tdls_scan_done_callback(pAdapter);
15755#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015756 goto free_mem;
15757 }
15758
15759 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015760 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070015761 pAdapter->request = request;
15762 pScanInfo->scanId = scanId;
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015763 pScanInfo->no_cck = request->no_cck;
15764 pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
15765 for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
15766 pHddCtx->scan_info.last_scan_channelList[i] =
15767 request->channels[i]->hw_value;
15768 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015769
15770 complete(&pScanInfo->scan_req_completion_event);
15771
15772free_mem:
15773 if( scanRequest.SSIDs.SSIDList )
15774 {
15775 vos_mem_free(scanRequest.SSIDs.SSIDList);
15776 }
15777
15778 if( channelList )
15779 vos_mem_free( channelList );
15780
15781 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015782 return status;
15783}
15784
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015785int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
15786#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15787 struct net_device *dev,
15788#endif
15789 struct cfg80211_scan_request *request)
15790{
15791 int ret;
15792
15793 vos_ssr_protect(__func__);
15794 ret = __wlan_hdd_cfg80211_scan(wiphy,
15795#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15796 dev,
15797#endif
15798 request);
15799 vos_ssr_unprotect(__func__);
15800
15801 return ret;
15802}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015803
15804void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
15805{
15806 v_U8_t iniDot11Mode =
15807 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
15808 eHddDot11Mode hddDot11Mode = iniDot11Mode;
15809
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015810 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
15811 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015812 switch ( iniDot11Mode )
15813 {
15814 case eHDD_DOT11_MODE_AUTO:
15815 case eHDD_DOT11_MODE_11ac:
15816 case eHDD_DOT11_MODE_11ac_ONLY:
15817#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053015818 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
15819 sme_IsFeatureSupportedByFW(DOT11AC) )
15820 hddDot11Mode = eHDD_DOT11_MODE_11ac;
15821 else
15822 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015823#else
15824 hddDot11Mode = eHDD_DOT11_MODE_11n;
15825#endif
15826 break;
15827 case eHDD_DOT11_MODE_11n:
15828 case eHDD_DOT11_MODE_11n_ONLY:
15829 hddDot11Mode = eHDD_DOT11_MODE_11n;
15830 break;
15831 default:
15832 hddDot11Mode = iniDot11Mode;
15833 break;
15834 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015835#ifdef WLAN_FEATURE_AP_HT40_24G
15836 if (operationChannel > SIR_11B_CHANNEL_END)
15837#endif
15838 {
15839 /* This call decides required channel bonding mode */
15840 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015841 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053015842 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015843 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015844}
15845
Jeff Johnson295189b2012-06-20 16:38:30 -070015846/*
15847 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015848 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015849 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015850int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053015851 const u8 *ssid, size_t ssid_len, const u8 *bssid,
15852 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070015853{
15854 int status = 0;
15855 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080015856 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015857 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015858 v_U32_t roamId;
15859 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070015860 eCsrAuthType RSNAuthType;
15861
15862 ENTER();
15863
15864 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015865 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015866 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015867
15868 status = wlan_hdd_validate_context(pHddCtx);
15869 if (status)
15870 {
Yue Mae36e3552014-03-05 17:06:20 -080015871 return status;
15872 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015873
Jeff Johnson295189b2012-06-20 16:38:30 -070015874 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
15875 {
15876 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
15877 return -EINVAL;
15878 }
15879
Nitesh Shah9b066282017-06-06 18:05:52 +053015880
Jeff Johnson295189b2012-06-20 16:38:30 -070015881 pRoamProfile = &pWextState->roamProfile;
15882
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015883 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070015884 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015885 hdd_station_ctx_t *pHddStaCtx;
15886 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053015887 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015888
Siddharth Bhalda0d1622015-04-24 15:47:49 +053015889 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
15890
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015891 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070015892 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
15893 {
15894 /*QoS not enabled in cfg file*/
15895 pRoamProfile->uapsd_mask = 0;
15896 }
15897 else
15898 {
15899 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015900 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070015901 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
15902 }
15903
15904 pRoamProfile->SSIDs.numOfSSIDs = 1;
15905 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
15906 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015907 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070015908 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
15909 ssid, ssid_len);
15910
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015911 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
15912 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
15913
Jeff Johnson295189b2012-06-20 16:38:30 -070015914 if (bssid)
15915 {
15916 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015917 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015918 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015919 /* Save BSSID in seperate variable as well, as RoamProfile
15920 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070015921 case of join failure we should send valid BSSID to supplicant
15922 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015923 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015924 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015925
Jeff Johnson295189b2012-06-20 16:38:30 -070015926 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015927 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070015928 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015929 /* Store bssid_hint to use in the scan filter. */
15930 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15931 WNI_CFG_BSSID_LEN);
15932 /*
15933 * Save BSSID in seperate variable as well, as RoamProfile
15934 * BSSID is getting zeroed out in the association process. And in
15935 * case of join failure we should send valid BSSID to supplicant
15936 */
15937 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15938 WNI_CFG_BSSID_LEN);
15939 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15940 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015941 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015942
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015943
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015944 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15945 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015946 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15947 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015948 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015949 /*set gen ie*/
15950 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15951 /*set auth*/
15952 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15953 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015954#ifdef FEATURE_WLAN_WAPI
15955 if (pAdapter->wapi_info.nWapiMode)
15956 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015957 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015958 switch (pAdapter->wapi_info.wapiAuthMode)
15959 {
15960 case WAPI_AUTH_MODE_PSK:
15961 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015962 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015963 pAdapter->wapi_info.wapiAuthMode);
15964 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15965 break;
15966 }
15967 case WAPI_AUTH_MODE_CERT:
15968 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015969 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015970 pAdapter->wapi_info.wapiAuthMode);
15971 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15972 break;
15973 }
15974 } // End of switch
15975 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15976 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15977 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015978 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015979 pRoamProfile->AuthType.numEntries = 1;
15980 pRoamProfile->EncryptionType.numEntries = 1;
15981 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15982 pRoamProfile->mcEncryptionType.numEntries = 1;
15983 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15984 }
15985 }
15986#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015987#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015988 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015989 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15990 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
15991 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015992 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
15993 sizeof (tSirGtkOffloadParams));
15994 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015995 }
15996#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015997 pRoamProfile->csrPersona = pAdapter->device_mode;
15998
Jeff Johnson32d95a32012-09-10 13:15:23 -070015999 if( operatingChannel )
16000 {
16001 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
16002 pRoamProfile->ChannelInfo.numOfChannels = 1;
16003 }
Chet Lanctot186b5732013-03-18 10:26:30 -070016004 else
16005 {
16006 pRoamProfile->ChannelInfo.ChannelList = NULL;
16007 pRoamProfile->ChannelInfo.numOfChannels = 0;
16008 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016009 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
16010 {
16011 hdd_select_cbmode(pAdapter,operatingChannel);
16012 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053016013
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016014 /*
16015 * Change conn_state to connecting before sme_RoamConnect(),
16016 * because sme_RoamConnect() has a direct path to call
16017 * hdd_smeRoamCallback(), which will change the conn_state
16018 * If direct path, conn_state will be accordingly changed
16019 * to NotConnected or Associated by either
16020 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
16021 * in sme_RoamCallback()
16022 * if sme_RomConnect is to be queued,
16023 * Connecting state will remain until it is completed.
16024 * If connection state is not changed,
16025 * connection state will remain in eConnectionState_NotConnected state.
16026 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
16027 * if conn state is eConnectionState_NotConnected.
16028 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
16029 * informed of connect result indication which is an issue.
16030 */
16031
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016032 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16033 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053016034 {
16035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016036 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016037 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
16038 eConnectionState_Connecting);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016039 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
16040 hdd_wait_for_ecsa_complete(pHddCtx);
Abhishek Singhf4669da2014-05-26 15:07:49 +053016041 }
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016042
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016043 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070016044 pAdapter->sessionId, pRoamProfile, &roamId);
16045
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016046 if ((eHAL_STATUS_SUCCESS != status) &&
16047 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16048 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016049
16050 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016051 hddLog(VOS_TRACE_LEVEL_ERROR,
16052 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
16053 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016054 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016055 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016056 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016057 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016058
16059 pRoamProfile->ChannelInfo.ChannelList = NULL;
16060 pRoamProfile->ChannelInfo.numOfChannels = 0;
16061
Jeff Johnson295189b2012-06-20 16:38:30 -070016062 }
16063 else
16064 {
16065 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
16066 return -EINVAL;
16067 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080016068 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016069 return status;
16070}
16071
16072/*
16073 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
16074 * This function is used to set the authentication type (OPEN/SHARED).
16075 *
16076 */
16077static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
16078 enum nl80211_auth_type auth_type)
16079{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016080 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016081 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16082
16083 ENTER();
16084
16085 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016086 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070016087 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016088 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016089 hddLog(VOS_TRACE_LEVEL_INFO,
16090 "%s: set authentication type to AUTOSWITCH", __func__);
16091 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
16092 break;
16093
16094 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016095#ifdef WLAN_FEATURE_VOWIFI_11R
16096 case NL80211_AUTHTYPE_FT:
16097#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016098 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016099 "%s: set authentication type to OPEN", __func__);
16100 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
16101 break;
16102
16103 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016104 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016105 "%s: set authentication type to SHARED", __func__);
16106 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
16107 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016108#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016109 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016110 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016111 "%s: set authentication type to CCKM WPA", __func__);
16112 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
16113 break;
16114#endif
16115
16116
16117 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016118 hddLog(VOS_TRACE_LEVEL_ERROR,
16119 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016120 auth_type);
16121 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
16122 return -EINVAL;
16123 }
16124
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016125 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016126 pHddStaCtx->conn_info.authType;
16127 return 0;
16128}
16129
16130/*
16131 * FUNCTION: wlan_hdd_set_akm_suite
16132 * This function is used to set the key mgmt type(PSK/8021x).
16133 *
16134 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016135static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016136 u32 key_mgmt
16137 )
16138{
16139 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16140 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053016141 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016142#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016143#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016144#endif
16145#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016146#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016147#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016148 /*set key mgmt type*/
16149 switch(key_mgmt)
16150 {
16151 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053016152 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016153#ifdef WLAN_FEATURE_VOWIFI_11R
16154 case WLAN_AKM_SUITE_FT_PSK:
16155#endif
16156 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070016157 __func__);
16158 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
16159 break;
16160
16161 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053016162 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016163#ifdef WLAN_FEATURE_VOWIFI_11R
16164 case WLAN_AKM_SUITE_FT_8021X:
16165#endif
16166 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070016167 __func__);
16168 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16169 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016170#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016171#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
16172#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
16173 case WLAN_AKM_SUITE_CCKM:
16174 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
16175 __func__);
16176 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
16177 break;
16178#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070016179#ifndef WLAN_AKM_SUITE_OSEN
16180#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
16181 case WLAN_AKM_SUITE_OSEN:
16182 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
16183 __func__);
16184 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16185 break;
16186#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016187
16188 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016189 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016190 __func__, key_mgmt);
16191 return -EINVAL;
16192
16193 }
16194 return 0;
16195}
16196
16197/*
16198 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016199 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070016200 * (NONE/WEP40/WEP104/TKIP/CCMP).
16201 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016202static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
16203 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070016204 bool ucast
16205 )
16206{
16207 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016208 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016209 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16210
16211 ENTER();
16212
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016213 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016214 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053016215 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070016216 __func__, cipher);
16217 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16218 }
16219 else
16220 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016221
Jeff Johnson295189b2012-06-20 16:38:30 -070016222 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016223 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016224 {
16225 case IW_AUTH_CIPHER_NONE:
16226 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16227 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016228
Jeff Johnson295189b2012-06-20 16:38:30 -070016229 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016230 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070016231 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016232
Jeff Johnson295189b2012-06-20 16:38:30 -070016233 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016234 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070016235 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016236
Jeff Johnson295189b2012-06-20 16:38:30 -070016237 case WLAN_CIPHER_SUITE_TKIP:
16238 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
16239 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016240
Jeff Johnson295189b2012-06-20 16:38:30 -070016241 case WLAN_CIPHER_SUITE_CCMP:
16242 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16243 break;
16244#ifdef FEATURE_WLAN_WAPI
16245 case WLAN_CIPHER_SUITE_SMS4:
16246 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
16247 break;
16248#endif
16249
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016250#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016251 case WLAN_CIPHER_SUITE_KRK:
16252 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
16253 break;
16254#endif
16255 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016256 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016257 __func__, cipher);
16258 return -EOPNOTSUPP;
16259 }
16260 }
16261
16262 if (ucast)
16263 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016264 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016265 __func__, encryptionType);
16266 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16267 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016268 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016269 encryptionType;
16270 }
16271 else
16272 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016273 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016274 __func__, encryptionType);
16275 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
16276 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
16277 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
16278 }
16279
16280 return 0;
16281}
16282
16283
16284/*
16285 * FUNCTION: wlan_hdd_cfg80211_set_ie
16286 * This function is used to parse WPA/RSN IE's.
16287 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016288int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016289#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16290 const u8 *ie,
16291#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016292 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016293#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016294 size_t ie_len
16295 )
16296{
16297 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016298#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16299 const u8 *genie = ie;
16300#else
Jeff Johnson295189b2012-06-20 16:38:30 -070016301 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016302#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016303 v_U16_t remLen = ie_len;
16304#ifdef FEATURE_WLAN_WAPI
16305 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
16306 u16 *tmp;
16307 v_U16_t akmsuiteCount;
16308 int *akmlist;
16309#endif
16310 ENTER();
16311
16312 /* clear previous assocAddIE */
16313 pWextState->assocAddIE.length = 0;
16314 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016315 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016316
16317 while (remLen >= 2)
16318 {
16319 v_U16_t eLen = 0;
16320 v_U8_t elementId;
16321 elementId = *genie++;
16322 eLen = *genie++;
16323 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016324
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053016325 /* Sanity check on eLen */
16326 if (eLen > remLen) {
16327 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
16328 __func__, eLen, elementId);
16329 VOS_ASSERT(0);
16330 return -EINVAL;
16331 }
16332
Arif Hussain6d2a3322013-11-17 19:50:10 -080016333 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070016334 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016335
16336 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070016337 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016338 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016339 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 -070016340 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016341 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016342 "%s: Invalid WPA IE", __func__);
16343 return -EINVAL;
16344 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016345 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070016346 {
16347 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016348 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016349 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016350
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016351 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016352 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016353 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
16354 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016355 VOS_ASSERT(0);
16356 return -ENOMEM;
16357 }
16358 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16359 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16360 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016361
Jeff Johnson295189b2012-06-20 16:38:30 -070016362 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
16363 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16364 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16365 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016366 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
16367 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053016368 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16369 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
16370 __func__, eLen);
16371 VOS_ASSERT(0);
16372 return -EINVAL;
16373 }
16374
Jeff Johnson295189b2012-06-20 16:38:30 -070016375 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
16376 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16377 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
16378 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
16379 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
16380 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016381 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053016382 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070016383 {
16384 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016385 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016386 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016387
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016388 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016389 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016390 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16391 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016392 VOS_ASSERT(0);
16393 return -ENOMEM;
16394 }
16395 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16396 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16397 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016398
Jeff Johnson295189b2012-06-20 16:38:30 -070016399 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16400 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16401 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016402#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016403 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
16404 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016405 /*Consider WFD IE, only for P2P Client */
16406 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
16407 {
16408 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016409 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016410 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016411
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016412 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016413 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016414 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16415 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016416 VOS_ASSERT(0);
16417 return -ENOMEM;
16418 }
16419 // WFD IE is saved to Additional IE ; it should be accumulated to handle
16420 // WPS IE + P2P IE + WFD IE
16421 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16422 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016423
Jeff Johnson295189b2012-06-20 16:38:30 -070016424 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16425 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16426 }
16427#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016428 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016429 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016430 HS20_OUI_TYPE_SIZE)) )
16431 {
16432 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016433 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016434 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016435
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016436 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016437 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016438 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16439 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016440 VOS_ASSERT(0);
16441 return -ENOMEM;
16442 }
16443 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16444 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016445
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016446 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16447 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16448 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016449 /* Appending OSEN Information Element in Assiciation Request */
16450 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
16451 OSEN_OUI_TYPE_SIZE)) )
16452 {
16453 v_U16_t curAddIELen = pWextState->assocAddIE.length;
16454 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
16455 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016456
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016457 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016458 {
16459 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16460 "Need bigger buffer space");
16461 VOS_ASSERT(0);
16462 return -ENOMEM;
16463 }
16464 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16465 pWextState->assocAddIE.length += eLen + 2;
16466
16467 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
16468 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16469 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16470 }
16471
Abhishek Singh4322e622015-06-10 15:42:54 +053016472 /* Update only for WPA IE */
16473 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
16474 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016475
16476 /* populating as ADDIE in beacon frames */
16477 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016478 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016479 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
16480 {
16481 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16482 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
16483 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16484 {
16485 hddLog(LOGE,
16486 "Coldn't pass "
16487 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
16488 }
16489 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
16490 else
16491 hddLog(LOGE,
16492 "Could not pass on "
16493 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
16494
16495 /* IBSS mode doesn't contain params->proberesp_ies still
16496 beaconIE's need to be populated in probe response frames */
16497 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
16498 {
16499 u16 rem_probe_resp_ie_len = eLen + 2;
16500 u8 probe_rsp_ie_len[3] = {0};
16501 u8 counter = 0;
16502
16503 /* Check Probe Resp Length if it is greater then 255 then
16504 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
16505 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
16506 not able Store More then 255 bytes into One Variable */
16507
16508 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
16509 {
16510 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
16511 {
16512 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
16513 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
16514 }
16515 else
16516 {
16517 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
16518 rem_probe_resp_ie_len = 0;
16519 }
16520 }
16521
16522 rem_probe_resp_ie_len = 0;
16523
16524 if (probe_rsp_ie_len[0] > 0)
16525 {
16526 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16527 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
16528 (tANI_U8*)(genie - 2),
16529 probe_rsp_ie_len[0], NULL,
16530 eANI_BOOLEAN_FALSE)
16531 == eHAL_STATUS_FAILURE)
16532 {
16533 hddLog(LOGE,
16534 "Could not pass"
16535 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
16536 }
16537 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
16538 }
16539
16540 if (probe_rsp_ie_len[1] > 0)
16541 {
16542 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16543 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
16544 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16545 probe_rsp_ie_len[1], NULL,
16546 eANI_BOOLEAN_FALSE)
16547 == eHAL_STATUS_FAILURE)
16548 {
16549 hddLog(LOGE,
16550 "Could not pass"
16551 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
16552 }
16553 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
16554 }
16555
16556 if (probe_rsp_ie_len[2] > 0)
16557 {
16558 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16559 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
16560 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16561 probe_rsp_ie_len[2], NULL,
16562 eANI_BOOLEAN_FALSE)
16563 == eHAL_STATUS_FAILURE)
16564 {
16565 hddLog(LOGE,
16566 "Could not pass"
16567 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
16568 }
16569 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
16570 }
16571
16572 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16573 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
16574 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16575 {
16576 hddLog(LOGE,
16577 "Could not pass"
16578 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
16579 }
16580 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016581 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070016582 break;
16583 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053016584 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16585 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
16586 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
16587 VOS_ASSERT(0);
16588 return -EINVAL;
16589 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016590 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
16591 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16592 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
16593 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
16594 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16595 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016596
Abhishek Singhb16f3562016-01-20 11:08:32 +053016597 /* Appending extended capabilities with Interworking or
16598 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016599 *
16600 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016601 * interworkingService or bsstransition bit is set to 1.
16602 * Driver is only interested in interworkingService and
16603 * bsstransition capability from supplicant.
16604 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016605 * required from supplicat, it needs to be handled while
16606 * sending Assoc Req in LIM.
16607 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016608 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016609 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016610 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016611 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016612 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016613
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016614 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016615 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016616 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16617 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016618 VOS_ASSERT(0);
16619 return -ENOMEM;
16620 }
16621 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16622 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016623
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016624 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16625 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16626 break;
16627 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016628#ifdef FEATURE_WLAN_WAPI
16629 case WLAN_EID_WAPI:
16630 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016631 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016632 pAdapter->wapi_info.nWapiMode);
16633 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016634 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016635 akmsuiteCount = WPA_GET_LE16(tmp);
16636 tmp = tmp + 1;
16637 akmlist = (int *)(tmp);
16638 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16639 {
16640 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16641 }
16642 else
16643 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016644 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016645 VOS_ASSERT(0);
16646 return -EINVAL;
16647 }
16648
16649 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16650 {
16651 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016652 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016653 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016654 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016655 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016656 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016657 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016658 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016659 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
16660 }
16661 break;
16662#endif
16663 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016664 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016665 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016666 /* when Unknown IE is received we should break and continue
16667 * to the next IE in the buffer instead we were returning
16668 * so changing this to break */
16669 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016670 }
16671 genie += eLen;
16672 remLen -= eLen;
16673 }
16674 EXIT();
16675 return 0;
16676}
16677
16678/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016679 * FUNCTION: hdd_isWPAIEPresent
16680 * Parse the received IE to find the WPA IE
16681 *
16682 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016683static bool hdd_isWPAIEPresent(
16684#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16685 const u8 *ie,
16686#else
16687 u8 *ie,
16688#endif
16689 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016690{
16691 v_U8_t eLen = 0;
16692 v_U16_t remLen = ie_len;
16693 v_U8_t elementId = 0;
16694
16695 while (remLen >= 2)
16696 {
16697 elementId = *ie++;
16698 eLen = *ie++;
16699 remLen -= 2;
16700 if (eLen > remLen)
16701 {
16702 hddLog(VOS_TRACE_LEVEL_ERROR,
16703 "%s: IE length is wrong %d", __func__, eLen);
16704 return FALSE;
16705 }
16706 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16707 {
16708 /* OUI - 0x00 0X50 0XF2
16709 WPA Information Element - 0x01
16710 WPA version - 0x01*/
16711 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16712 return TRUE;
16713 }
16714 ie += eLen;
16715 remLen -= eLen;
16716 }
16717 return FALSE;
16718}
16719
16720/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016721 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016722 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016723 * parameters during connect operation.
16724 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016725int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016726 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016727 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016728{
16729 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016730 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016731 ENTER();
16732
16733 /*set wpa version*/
16734 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
16735
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016736 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016737 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053016738 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016739 {
16740 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16741 }
16742 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
16743 {
16744 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16745 }
16746 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016747
16748 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016749 pWextState->wpaVersion);
16750
16751 /*set authentication type*/
16752 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
16753
16754 if (0 > status)
16755 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016756 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016757 "%s: failed to set authentication type ", __func__);
16758 return status;
16759 }
16760
16761 /*set key mgmt type*/
16762 if (req->crypto.n_akm_suites)
16763 {
16764 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
16765 if (0 > status)
16766 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016767 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070016768 __func__);
16769 return status;
16770 }
16771 }
16772
16773 /*set pairwise cipher type*/
16774 if (req->crypto.n_ciphers_pairwise)
16775 {
16776 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
16777 req->crypto.ciphers_pairwise[0], true);
16778 if (0 > status)
16779 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016780 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016781 "%s: failed to set unicast cipher type", __func__);
16782 return status;
16783 }
16784 }
16785 else
16786 {
16787 /*Reset previous cipher suite to none*/
16788 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
16789 if (0 > status)
16790 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016791 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016792 "%s: failed to set unicast cipher type", __func__);
16793 return status;
16794 }
16795 }
16796
16797 /*set group cipher type*/
16798 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
16799 false);
16800
16801 if (0 > status)
16802 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016803 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070016804 __func__);
16805 return status;
16806 }
16807
Chet Lanctot186b5732013-03-18 10:26:30 -070016808#ifdef WLAN_FEATURE_11W
16809 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
16810#endif
16811
Jeff Johnson295189b2012-06-20 16:38:30 -070016812 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
16813 if (req->ie_len)
16814 {
16815 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
16816 if ( 0 > status)
16817 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016818 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016819 __func__);
16820 return status;
16821 }
16822 }
16823
16824 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016825 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016826 {
16827 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
16828 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
16829 )
16830 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016831 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070016832 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
16833 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016834 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016835 __func__);
16836 return -EOPNOTSUPP;
16837 }
16838 else
16839 {
16840 u8 key_len = req->key_len;
16841 u8 key_idx = req->key_idx;
16842
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016843 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016844 && (CSR_MAX_NUM_KEY > key_idx)
16845 )
16846 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016847 hddLog(VOS_TRACE_LEVEL_INFO,
16848 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016849 __func__, key_idx, key_len);
16850 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016851 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070016852 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016853 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016854 (u8)key_len;
16855 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
16856 }
16857 }
16858 }
16859 }
16860
16861 return status;
16862}
16863
16864/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016865 * FUNCTION: wlan_hdd_try_disconnect
16866 * This function is used to disconnect from previous
16867 * connection
16868 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053016869int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016870{
16871 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016872 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016873 hdd_station_ctx_t *pHddStaCtx;
16874 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016875 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016876
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016877 ret = wlan_hdd_validate_context(pHddCtx);
16878 if (0 != ret)
16879 {
16880 return ret;
16881 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016882 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16883
16884 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
16885
16886 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
16887 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053016888 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016889 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
16890 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053016891 /* Indicate disconnect to SME so that in-progress connection or preauth
16892 * can be aborted
16893 */
16894 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
16895 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016896 spin_lock_bh(&pAdapter->lock_for_active_session);
16897 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16898 {
16899 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16900 }
16901 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053016902 hdd_connSetConnectionState(pHddStaCtx,
16903 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016904 /* Issue disconnect to CSR */
16905 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016906 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016907 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016908 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16909 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
16910 hddLog(LOG1,
16911 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
16912 } else if ( 0 != status ) {
16913 hddLog(LOGE,
16914 FL("csrRoamDisconnect failure, returned %d"),
16915 (int)status );
16916 result = -EINVAL;
16917 goto disconnected;
16918 }
16919 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016920 &pAdapter->disconnect_comp_var,
16921 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016922 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
16923 hddLog(LOGE,
16924 "%s: Failed to disconnect, timed out", __func__);
16925 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016926 }
16927 }
16928 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
16929 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016930 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016931 &pAdapter->disconnect_comp_var,
16932 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016933 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016934 {
16935 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016936 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016937 }
16938 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016939disconnected:
16940 hddLog(LOG1,
16941 FL("Set HDD connState to eConnectionState_NotConnected"));
16942 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16943 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016944}
16945
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016946/**
16947 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16948 * @adapter: Pointer to the HDD adapter
16949 * @req: Pointer to the structure cfg_connect_params receieved from user space
16950 *
Abhinav Kumar42c34902018-09-27 19:00:35 +053016951 * This function will start reassociation if prev_bssid is set and bssid/
16952 * bssid_hint, channel/channel_hint parameters are present in connect request.
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016953 *
16954 * Return: success if reassociation is happening
16955 * Error code if reassociation is not permitted or not happening
16956 */
16957#ifdef CFG80211_CONNECT_PREV_BSSID
16958static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16959 struct cfg80211_connect_params *req)
16960{
16961 int status = -EPERM;
Abhinav Kumar42c34902018-09-27 19:00:35 +053016962 const uint8_t *bssid = NULL;
16963 uint16_t channel = 0;
16964
16965 if (req->bssid)
16966 bssid = req->bssid;
16967 else if (req->bssid_hint)
16968 bssid = req->bssid_hint;
16969
16970 if (req->channel)
16971 channel = req->channel->hw_value;
16972 else if (req->channel_hint)
16973 channel = req->channel_hint->hw_value;
16974
16975 if (bssid && channel && req->prev_bssid) {
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016976 hddLog(VOS_TRACE_LEVEL_INFO,
16977 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
Abhinav Kumar42c34902018-09-27 19:00:35 +053016978 channel, MAC_ADDR_ARRAY(bssid));
16979 status = hdd_reassoc(adapter, bssid, channel,
16980 CONNECT_CMD_USERSPACE);
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016981 }
16982 return status;
16983}
16984#else
16985static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16986 struct cfg80211_connect_params *req)
16987{
16988 return -EPERM;
16989}
16990#endif
16991
Abhishek Singhe3beee22017-07-31 15:35:40 +053016992/**
16993 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
16994 * connect in HT20 mode
16995 * @hdd_ctx: hdd context
16996 * @adapter: Pointer to the HDD adapter
16997 * @req: Pointer to the structure cfg_connect_params receieved from user space
16998 *
16999 * This function will check if supplicant has indicated to to connect in HT20
17000 * mode. this is currently applicable only for 2.4Ghz mode only.
17001 * if feature is enabled and supplicant indicate HT20 set
17002 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
17003 *
17004 * Return: void
17005 */
17006#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
17007static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
17008 hdd_adapter_t *adapter,
17009 struct cfg80211_connect_params *req)
17010{
17011 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
17012 tCsrRoamProfile *roam_profile;
17013
17014 roam_profile = &wext_state->roamProfile;
17015 roam_profile->force_24ghz_in_ht20 = false;
17016 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
17017 !(req->ht_capa.cap_info &
17018 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
17019 roam_profile->force_24ghz_in_ht20 = true;
17020
17021 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
17022 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
17023}
17024#else
17025static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
17026 hdd_adapter_t *adapter,
17027 struct cfg80211_connect_params *req)
17028{
17029 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
17030 tCsrRoamProfile *roam_profile;
17031
17032 roam_profile = &wext_state->roamProfile;
17033 roam_profile->force_24ghz_in_ht20 = false;
17034}
17035#endif
17036
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017037/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053017038 * FUNCTION: __wlan_hdd_cfg80211_connect
17039 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070017040 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017041static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017042 struct net_device *ndev,
17043 struct cfg80211_connect_params *req
17044 )
17045{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017046 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017047 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053017048#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
17049 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017050 const u8 *bssid_hint = req->bssid_hint;
17051#else
17052 const u8 *bssid_hint = NULL;
17053#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017054 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017055 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053017056 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017057
17058 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017059
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017060 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17061 TRACE_CODE_HDD_CFG80211_CONNECT,
17062 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017063 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017064 "%s: device_mode = %s (%d)", __func__,
17065 hdd_device_modetoString(pAdapter->device_mode),
17066 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017067
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017068 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017069 if (!pHddCtx)
17070 {
17071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17072 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053017073 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017074 }
17075
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017076 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017077 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017078 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017079 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017080 }
17081
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053017082 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
17083 return -EINVAL;
17084
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017085 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
17086 if (0 == status)
17087 return status;
17088
Agarwal Ashish51325b52014-06-16 16:50:49 +053017089
Jeff Johnson295189b2012-06-20 16:38:30 -070017090#ifdef WLAN_BTAMP_FEATURE
17091 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017092 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070017093 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017094 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017095 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080017096 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070017097 }
17098#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017099
17100 //If Device Mode is Station Concurrent Sessions Exit BMps
17101 //P2P Mode will be taken care in Open/close adapter
17102 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053017103 (vos_concurrent_open_sessions_running())) {
17104 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
17105 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017106 }
17107
17108 /*Try disconnecting if already in connected state*/
17109 status = wlan_hdd_try_disconnect(pAdapter);
17110 if ( 0 > status)
17111 {
17112 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17113 " connection"));
17114 return -EALREADY;
17115 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053017116 /* Check for max concurrent connections after doing disconnect if any*/
17117 if (vos_max_concurrent_connections_reached()) {
17118 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17119 return -ECONNREFUSED;
17120 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017121
Jeff Johnson295189b2012-06-20 16:38:30 -070017122 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017123 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070017124
17125 if ( 0 > status)
17126 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017127 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070017128 __func__);
17129 return status;
17130 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053017131
17132 if (pHddCtx->spoofMacAddr.isEnabled)
17133 {
17134 hddLog(VOS_TRACE_LEVEL_INFO,
17135 "%s: MAC Spoofing enabled ", __func__);
17136 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
17137 * to fill TxBds for probe request during SSID scan which may happen
17138 * as part of connect command
17139 */
17140 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
17141 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
17142 if (status != VOS_STATUS_SUCCESS)
17143 return -ECONNREFUSED;
17144 }
17145
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017146 if (req->channel)
17147 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070017148 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017149 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053017150
17151 /* Abort if any scan is going on */
17152 status = wlan_hdd_scan_abort(pAdapter);
17153 if (0 != status)
17154 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
17155
Abhishek Singhe3beee22017-07-31 15:35:40 +053017156 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
17157
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017158 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
17159 req->ssid_len, req->bssid,
17160 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017161
Sushant Kaushikd7083982015-03-18 14:33:24 +053017162 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017163 {
17164 //ReEnable BMPS if disabled
17165 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
17166 (NULL != pHddCtx))
17167 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053017168 if (pHddCtx->hdd_wlan_suspended)
17169 {
17170 hdd_set_pwrparams(pHddCtx);
17171 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017172 //ReEnable Bmps and Imps back
17173 hdd_enable_bmps_imps(pHddCtx);
17174 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053017175 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070017176 return status;
17177 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017178 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017179 EXIT();
17180 return status;
17181}
17182
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017183static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
17184 struct net_device *ndev,
17185 struct cfg80211_connect_params *req)
17186{
17187 int ret;
17188 vos_ssr_protect(__func__);
17189 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
17190 vos_ssr_unprotect(__func__);
17191
17192 return ret;
17193}
Jeff Johnson295189b2012-06-20 16:38:30 -070017194
17195/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017196 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070017197 * This function is used to issue a disconnect request to SME
17198 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017199static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017200 struct net_device *dev,
17201 u16 reason
17202 )
17203{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017204 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017205 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017206 tCsrRoamProfile *pRoamProfile;
17207 hdd_station_ctx_t *pHddStaCtx;
17208 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017209#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017210 tANI_U8 staIdx;
17211#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017212
Jeff Johnson295189b2012-06-20 16:38:30 -070017213 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017214
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017215 if (!pAdapter) {
17216 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17217 return -EINVAL;
17218 }
17219
17220 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17221 if (!pHddStaCtx) {
17222 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
17223 return -EINVAL;
17224 }
17225
17226 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17227 status = wlan_hdd_validate_context(pHddCtx);
17228 if (0 != status)
17229 {
17230 return status;
17231 }
17232
17233 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
17234
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017235 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17236 TRACE_CODE_HDD_CFG80211_DISCONNECT,
17237 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017238 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
17239 __func__, hdd_device_modetoString(pAdapter->device_mode),
17240 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017241
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017242 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
17243 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070017244
Jeff Johnson295189b2012-06-20 16:38:30 -070017245 if (NULL != pRoamProfile)
17246 {
17247 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017248 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
17249 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070017250 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017251 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070017252 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017253 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070017254 switch(reason)
17255 {
17256 case WLAN_REASON_MIC_FAILURE:
17257 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
17258 break;
17259
17260 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
17261 case WLAN_REASON_DISASSOC_AP_BUSY:
17262 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
17263 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
17264 break;
17265
17266 case WLAN_REASON_PREV_AUTH_NOT_VALID:
17267 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053017268 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070017269 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
17270 break;
17271
Jeff Johnson295189b2012-06-20 16:38:30 -070017272 default:
17273 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
17274 break;
17275 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017276 pScanInfo = &pHddCtx->scan_info;
17277 if (pScanInfo->mScanPending)
17278 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017279 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017280 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053017281 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017282 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017283 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053017284 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017285#ifdef FEATURE_WLAN_TDLS
17286 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017287 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017288 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017289 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
17290 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017291 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017292 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017293 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017295 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017296 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017297 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017298 status = sme_DeleteTdlsPeerSta(
17299 WLAN_HDD_GET_HAL_CTX(pAdapter),
17300 pAdapter->sessionId,
17301 mac);
17302 if (status != eHAL_STATUS_SUCCESS) {
17303 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
17304 return -EPERM;
17305 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017306 }
17307 }
17308#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053017309
17310 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
17311 reasonCode,
17312 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017313 status = wlan_hdd_disconnect(pAdapter, reasonCode);
17314 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070017315 {
17316 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017317 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017318 __func__, (int)status );
17319 return -EINVAL;
17320 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017321 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017322 else
17323 {
17324 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
17325 "called while in %d state", __func__,
17326 pHddStaCtx->conn_info.connState);
17327 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017328 }
17329 else
17330 {
17331 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
17332 }
17333
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017334 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017335 return status;
17336}
17337
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017338static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
17339 struct net_device *dev,
17340 u16 reason
17341 )
17342{
17343 int ret;
17344 vos_ssr_protect(__func__);
17345 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
17346 vos_ssr_unprotect(__func__);
17347
17348 return ret;
17349}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017350
Jeff Johnson295189b2012-06-20 16:38:30 -070017351/*
17352 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017353 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070017354 * settings in IBSS mode.
17355 */
17356static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017357 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070017358 struct cfg80211_ibss_params *params
17359 )
17360{
17361 int status = 0;
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017362 tANI_U32 ret;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017363 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070017364 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
17365 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017366
Jeff Johnson295189b2012-06-20 16:38:30 -070017367 ENTER();
17368
17369 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070017370 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070017371
17372 if (params->ie_len && ( NULL != params->ie) )
17373 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017374 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17375 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017376 {
17377 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
17378 encryptionType = eCSR_ENCRYPT_TYPE_AES;
17379 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017380 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017381 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017382 tDot11fIEWPA dot11WPAIE;
17383 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017384 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017385
Wilson Yang00256342013-10-10 23:13:38 -070017386 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017387 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17388 params->ie_len, DOT11F_EID_WPA);
17389 if ( NULL != ie )
17390 {
17391 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
Hanumanth Reddy Pothulad6d2d2c2018-06-27 12:28:12 +053017392
17393 if (ie[1] < DOT11F_IE_WPA_MIN_LEN ||
17394 ie[1] > DOT11F_IE_WPA_MAX_LEN) {
17395 hddLog(LOGE, FL("invalid ie len:%d"), ie[1]);
17396 return -EINVAL;
17397 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017398 // Unpack the WPA IE
17399 //Skip past the EID byte and length byte - and four byte WiFi OUI
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017400 ret = dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017401 &ie[2+4],
17402 ie[1] - 4,
17403 &dot11WPAIE);
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017404 if (DOT11F_FAILED(ret))
17405 {
17406 hddLog(LOGE,
17407 FL("unpack failed status:(0x%08x)"),
17408 ret);
17409 return -EINVAL;
17410 }
17411
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017412 /*Extract the multicast cipher, the encType for unicast
17413 cipher for wpa-none is none*/
17414 encryptionType =
17415 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
17416 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017417 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017418
Jeff Johnson295189b2012-06-20 16:38:30 -070017419 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
17420
17421 if (0 > status)
17422 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017423 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070017424 __func__);
17425 return status;
17426 }
17427 }
17428
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017429 pWextState->roamProfile.AuthType.authType[0] =
17430 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070017431 eCSR_AUTH_TYPE_OPEN_SYSTEM;
Jeff Johnson295189b2012-06-20 16:38:30 -070017432 if (params->privacy)
17433 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017434 /* Security enabled IBSS, At this time there is no information available
17435 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070017436 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017437 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070017438 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017439 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070017440 *enable privacy bit in beacons */
17441
17442 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
17443 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017444 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17445 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070017446 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
17447 pWextState->roamProfile.EncryptionType.numEntries = 1;
17448 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070017449 return status;
17450}
17451
17452/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017453 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017454 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017455 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017456static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017457 struct net_device *dev,
17458 struct cfg80211_ibss_params *params
17459 )
17460{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017461 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017462 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17463 tCsrRoamProfile *pRoamProfile;
17464 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017465 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17466 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017467 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070017468
17469 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017470
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017471 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17472 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
17473 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017474 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017475 "%s: device_mode = %s (%d)", __func__,
17476 hdd_device_modetoString(pAdapter->device_mode),
17477 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017478
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017479 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017480 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017481 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017482 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017483 }
17484
17485 if (NULL == pWextState)
17486 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017487 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017488 __func__);
17489 return -EIO;
17490 }
17491
Agarwal Ashish51325b52014-06-16 16:50:49 +053017492 if (vos_max_concurrent_connections_reached()) {
17493 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17494 return -ECONNREFUSED;
17495 }
17496
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017497 /*Try disconnecting if already in connected state*/
17498 status = wlan_hdd_try_disconnect(pAdapter);
17499 if ( 0 > status)
17500 {
17501 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17502 " IBSS connection"));
17503 return -EALREADY;
17504 }
17505
Jeff Johnson295189b2012-06-20 16:38:30 -070017506 pRoamProfile = &pWextState->roamProfile;
17507
17508 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
17509 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017510 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017511 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017512 return -EINVAL;
17513 }
17514
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017515 /* BSSID is provided by upper layers hence no need to AUTO generate */
17516 if (NULL != params->bssid) {
17517 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17518 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
17519 hddLog (VOS_TRACE_LEVEL_ERROR,
17520 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17521 return -EIO;
17522 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017523 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017524 }
krunal sonie9002db2013-11-25 14:24:17 -080017525 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
17526 {
17527 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17528 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
17529 {
17530 hddLog (VOS_TRACE_LEVEL_ERROR,
17531 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17532 return -EIO;
17533 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017534
17535 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080017536 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017537 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080017538 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017539
Jeff Johnson295189b2012-06-20 16:38:30 -070017540 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070017541 if (NULL !=
17542#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17543 params->chandef.chan)
17544#else
17545 params->channel)
17546#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017547 {
17548 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017549 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17550 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
17551 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17552 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017553
17554 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017555 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070017556 ieee80211_frequency_to_channel(
17557#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17558 params->chandef.chan->center_freq);
17559#else
17560 params->channel->center_freq);
17561#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017562
17563 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17564 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070017565 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017566 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
17567 __func__);
17568 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070017569 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017570
17571 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017572 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017573 if (channelNum == validChan[indx])
17574 {
17575 break;
17576 }
17577 }
17578 if (indx >= numChans)
17579 {
17580 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017581 __func__, channelNum);
17582 return -EINVAL;
17583 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017584 /* Set the Operational Channel */
17585 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
17586 channelNum);
17587 pRoamProfile->ChannelInfo.numOfChannels = 1;
17588 pHddStaCtx->conn_info.operationChannel = channelNum;
17589 pRoamProfile->ChannelInfo.ChannelList =
17590 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070017591 }
17592
17593 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017594 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070017595 if (status < 0)
17596 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017597 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070017598 __func__);
17599 return status;
17600 }
17601
17602 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017603 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053017604 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017605 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017606
17607 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017608 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017609
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017610 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017611 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017612}
17613
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017614static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17615 struct net_device *dev,
17616 struct cfg80211_ibss_params *params
17617 )
17618{
17619 int ret = 0;
17620
17621 vos_ssr_protect(__func__);
17622 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17623 vos_ssr_unprotect(__func__);
17624
17625 return ret;
17626}
17627
Jeff Johnson295189b2012-06-20 16:38:30 -070017628/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017629 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017630 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017631 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017632static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017633 struct net_device *dev
17634 )
17635{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017636 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017637 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17638 tCsrRoamProfile *pRoamProfile;
17639 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017640 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017641 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017642#ifdef WLAN_FEATURE_RMC
17643 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17644#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017645
17646 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017647
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017648 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17649 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17650 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017651 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017652 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017653 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017654 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017655 }
17656
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017657 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17658 hdd_device_modetoString(pAdapter->device_mode),
17659 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017660 if (NULL == pWextState)
17661 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017662 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017663 __func__);
17664 return -EIO;
17665 }
17666
17667 pRoamProfile = &pWextState->roamProfile;
17668
17669 /* Issue disconnect only if interface type is set to IBSS */
17670 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17671 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017672 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017673 __func__);
17674 return -EINVAL;
17675 }
17676
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017677#ifdef WLAN_FEATURE_RMC
17678 /* Clearing add IE of beacon */
17679 if (ccmCfgSetStr(pHddCtx->hHal,
17680 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17681 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17682 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17683 {
17684 hddLog (VOS_TRACE_LEVEL_ERROR,
17685 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17686 return -EINVAL;
17687 }
17688 if (ccmCfgSetInt(pHddCtx->hHal,
17689 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17690 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17691 {
17692 hddLog (VOS_TRACE_LEVEL_ERROR,
17693 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17694 __func__);
17695 return -EINVAL;
17696 }
17697
17698 // Reset WNI_CFG_PROBE_RSP Flags
17699 wlan_hdd_reset_prob_rspies(pAdapter);
17700
17701 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17702 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17703 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17704 {
17705 hddLog (VOS_TRACE_LEVEL_ERROR,
17706 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17707 __func__);
17708 return -EINVAL;
17709 }
17710#endif
17711
Jeff Johnson295189b2012-06-20 16:38:30 -070017712 /* Issue Disconnect request */
17713 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017714 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17715 pAdapter->sessionId,
17716 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17717 if (!HAL_STATUS_SUCCESS(hal_status)) {
17718 hddLog(LOGE,
17719 FL("sme_RoamDisconnect failed hal_status(%d)"),
17720 hal_status);
17721 return -EAGAIN;
17722 }
17723 status = wait_for_completion_timeout(
17724 &pAdapter->disconnect_comp_var,
17725 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17726 if (!status) {
17727 hddLog(LOGE,
17728 FL("wait on disconnect_comp_var failed"));
17729 return -ETIMEDOUT;
17730 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017731
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017732 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017733 return 0;
17734}
17735
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017736static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17737 struct net_device *dev
17738 )
17739{
17740 int ret = 0;
17741
17742 vos_ssr_protect(__func__);
17743 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17744 vos_ssr_unprotect(__func__);
17745
17746 return ret;
17747}
17748
Jeff Johnson295189b2012-06-20 16:38:30 -070017749/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017750 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017751 * This function is used to set the phy parameters
17752 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17753 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017754static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017755 u32 changed)
17756{
17757 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17758 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017759 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017760
17761 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017762
17763 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017764 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17765 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017766
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017767 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017768 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017769 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017770 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017771 }
17772
Jeff Johnson295189b2012-06-20 16:38:30 -070017773 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17774 {
17775 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17776 WNI_CFG_RTS_THRESHOLD_STAMAX :
17777 wiphy->rts_threshold;
17778
17779 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017780 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017781 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017782 hddLog(VOS_TRACE_LEVEL_ERROR,
17783 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017784 __func__, rts_threshold);
17785 return -EINVAL;
17786 }
17787
17788 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17789 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017790 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017791 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017792 hddLog(VOS_TRACE_LEVEL_ERROR,
17793 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017794 __func__, rts_threshold);
17795 return -EIO;
17796 }
17797
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017798 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017799 rts_threshold);
17800 }
17801
17802 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17803 {
17804 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17805 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17806 wiphy->frag_threshold;
17807
17808 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017809 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017810 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017811 hddLog(VOS_TRACE_LEVEL_ERROR,
17812 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017813 frag_threshold);
17814 return -EINVAL;
17815 }
17816
17817 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
17818 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017819 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017820 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017821 hddLog(VOS_TRACE_LEVEL_ERROR,
17822 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017823 __func__, frag_threshold);
17824 return -EIO;
17825 }
17826
17827 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
17828 frag_threshold);
17829 }
17830
17831 if ((changed & WIPHY_PARAM_RETRY_SHORT)
17832 || (changed & WIPHY_PARAM_RETRY_LONG))
17833 {
17834 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
17835 wiphy->retry_short :
17836 wiphy->retry_long;
17837
17838 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17839 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17840 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017841 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017842 __func__, retry_value);
17843 return -EINVAL;
17844 }
17845
17846 if (changed & WIPHY_PARAM_RETRY_SHORT)
17847 {
17848 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17849 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017850 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017851 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017852 hddLog(VOS_TRACE_LEVEL_ERROR,
17853 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017854 __func__, retry_value);
17855 return -EIO;
17856 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017857 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017858 __func__, retry_value);
17859 }
17860 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17861 {
17862 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17863 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017864 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017865 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017866 hddLog(VOS_TRACE_LEVEL_ERROR,
17867 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017868 __func__, retry_value);
17869 return -EIO;
17870 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017871 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017872 __func__, retry_value);
17873 }
17874 }
17875
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017876 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017877 return 0;
17878}
17879
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017880static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17881 u32 changed)
17882{
17883 int ret;
17884
17885 vos_ssr_protect(__func__);
17886 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17887 vos_ssr_unprotect(__func__);
17888
17889 return ret;
17890}
17891
Jeff Johnson295189b2012-06-20 16:38:30 -070017892/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017893 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017894 * This function is used to set the txpower
17895 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017896static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017897#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17898 struct wireless_dev *wdev,
17899#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017900#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017901 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017902#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017903 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017904#endif
17905 int dbm)
17906{
17907 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017908 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017909 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17910 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017911 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017912
17913 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017914
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017915 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17916 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17917 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017918 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017919 if (0 != status)
17920 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017921 return status;
17922 }
17923
17924 hHal = pHddCtx->hHal;
17925
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017926 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17927 dbm, ccmCfgSetCallback,
17928 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017929 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017930 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017931 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17932 return -EIO;
17933 }
17934
17935 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17936 dbm);
17937
17938 switch(type)
17939 {
17940 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17941 /* Fall through */
17942 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17943 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17944 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017945 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17946 __func__);
17947 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017948 }
17949 break;
17950 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017951 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017952 __func__);
17953 return -EOPNOTSUPP;
17954 break;
17955 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017956 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17957 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017958 return -EIO;
17959 }
17960
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017961 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017962 return 0;
17963}
17964
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017965static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17966#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17967 struct wireless_dev *wdev,
17968#endif
17969#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17970 enum tx_power_setting type,
17971#else
17972 enum nl80211_tx_power_setting type,
17973#endif
17974 int dbm)
17975{
17976 int ret;
17977 vos_ssr_protect(__func__);
17978 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17979#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17980 wdev,
17981#endif
17982#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17983 type,
17984#else
17985 type,
17986#endif
17987 dbm);
17988 vos_ssr_unprotect(__func__);
17989
17990 return ret;
17991}
17992
Jeff Johnson295189b2012-06-20 16:38:30 -070017993/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017994 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017995 * This function is used to read the txpower
17996 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017997static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017998#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17999 struct wireless_dev *wdev,
18000#endif
18001 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070018002{
18003
18004 hdd_adapter_t *pAdapter;
18005 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018006 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018007
Jeff Johnsone7245742012-09-05 17:12:55 -070018008 ENTER();
18009
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018010 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018011 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018012 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018013 *dbm = 0;
18014 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018015 }
18016
Jeff Johnson295189b2012-06-20 16:38:30 -070018017 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
18018 if (NULL == pAdapter)
18019 {
18020 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
18021 return -ENOENT;
18022 }
18023
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018024 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18025 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
18026 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070018027 wlan_hdd_get_classAstats(pAdapter);
18028 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
18029
Jeff Johnsone7245742012-09-05 17:12:55 -070018030 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018031 return 0;
18032}
18033
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018034static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
18035#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18036 struct wireless_dev *wdev,
18037#endif
18038 int *dbm)
18039{
18040 int ret;
18041
18042 vos_ssr_protect(__func__);
18043 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
18044#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18045 wdev,
18046#endif
18047 dbm);
18048 vos_ssr_unprotect(__func__);
18049
18050 return ret;
18051}
18052
Dustin Brown8c1d4092017-07-28 18:08:01 +053018053/*
18054 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
18055 * @stats: summary stats to use as a source
18056 * @info: kernel station_info struct to use as a destination
18057 *
18058 * Return: None
18059 */
18060static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
18061 struct station_info *info)
18062{
18063 int i;
18064
18065 info->rx_packets = stats->rx_frm_cnt;
18066 info->tx_packets = 0;
18067 info->tx_retries = 0;
18068 info->tx_failed = 0;
18069
18070 for (i = 0; i < 4; ++i) {
18071 info->tx_packets += stats->tx_frm_cnt[i];
18072 info->tx_retries += stats->multiple_retry_cnt[i];
18073 info->tx_failed += stats->fail_cnt[i];
18074 }
18075
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018076#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18077 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018078 info->filled |= STATION_INFO_TX_PACKETS |
18079 STATION_INFO_TX_RETRIES |
18080 STATION_INFO_TX_FAILED |
18081 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018082#else
18083 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
18084 BIT(NL80211_STA_INFO_TX_RETRIES) |
18085 BIT(NL80211_STA_INFO_TX_FAILED) |
18086 BIT(NL80211_STA_INFO_RX_PACKETS);
18087#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053018088}
18089
18090/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018091 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
18092 * @adapter: sap adapter pointer
18093 * @staid: station id of the client
18094 * @rssi: rssi value to fill
18095 *
18096 * Return: None
18097 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053018098void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018099wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
18100{
18101 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
18102
18103 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
18104}
18105
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018106#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18107 !defined(WITH_BACKPORTS)
18108static inline void wlan_hdd_fill_station_info_signal(struct station_info
18109 *sinfo)
18110{
18111 sinfo->filled |= STATION_INFO_SIGNAL;
18112}
18113#else
18114static inline void wlan_hdd_fill_station_info_signal(struct station_info
18115 *sinfo)
18116{
18117 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
18118}
18119#endif
18120
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018121/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053018122 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
18123 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018124 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053018125 * @info: kernel station_info struct to populate
18126 *
18127 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
18128 * support "station dump" and "station get" for SAP vdevs, even though they
18129 * aren't technically stations.
18130 *
18131 * Return: errno
18132 */
18133static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018134wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
18135#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18136 const u8* mac,
18137#else
18138 u8* mac,
18139#endif
18140 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018141{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018142 v_MACADDR_t *peerMacAddr;
18143 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018144 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018145 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018146
18147 status = wlan_hdd_get_station_stats(adapter);
18148 if (!VOS_IS_STATUS_SUCCESS(status)) {
18149 hddLog(VOS_TRACE_LEVEL_ERROR,
18150 "Failed to get SAP stats; status:%d", status);
18151 return 0;
18152 }
18153
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018154 peerMacAddr = (v_MACADDR_t *)mac;
18155 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
18156 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
18157 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
18158
18159 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
18160 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018161 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018162 }
18163
Dustin Brown8c1d4092017-07-28 18:08:01 +053018164 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
18165
18166 return 0;
18167}
18168
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018169static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018170#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18171 const u8* mac,
18172#else
18173 u8* mac,
18174#endif
18175 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070018176{
18177 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
18178 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18179 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053018180 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018181
18182 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
18183 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070018184
18185 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
18186 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
18187 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
18188 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
18189 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
18190 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
18191 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018192 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018193 tANI_U16 myRate;
18194 tANI_U16 currentRate = 0;
18195 tANI_U8 maxSpeedMCS = 0;
18196 tANI_U8 maxMCSIdx = 0;
18197 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053018198 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070018199 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018200 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018201
Leo Chang6f8870f2013-03-26 18:11:36 -070018202#ifdef WLAN_FEATURE_11AC
18203 tANI_U32 vht_mcs_map;
18204 eDataRate11ACMaxMcs vhtMaxMcs;
18205#endif /* WLAN_FEATURE_11AC */
18206
Jeff Johnsone7245742012-09-05 17:12:55 -070018207 ENTER();
18208
Dustin Brown8c1d4092017-07-28 18:08:01 +053018209 status = wlan_hdd_validate_context(pHddCtx);
18210 if (0 != status)
18211 {
18212 return status;
18213 }
18214
18215 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018216 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053018217
Jeff Johnson295189b2012-06-20 16:38:30 -070018218 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
18219 (0 == ssidlen))
18220 {
18221 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
18222 " Invalid ssidlen, %d", __func__, ssidlen);
18223 /*To keep GUI happy*/
18224 return 0;
18225 }
18226
Mukul Sharma811205f2014-07-09 21:07:30 +053018227 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
18228 {
18229 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18230 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053018231 /* return a cached value */
18232 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053018233 return 0;
18234 }
18235
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053018236 wlan_hdd_get_station_stats(pAdapter);
18237 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018238
Kiet Lam3b17fc82013-09-27 05:24:08 +053018239 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018240 wlan_hdd_get_snr(pAdapter, &snr);
18241 pHddStaCtx->conn_info.signal = sinfo->signal;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018242 pHddStaCtx->cache_conn_info.signal = sinfo->signal;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018243 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018244 pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018245 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053018246
c_hpothu09f19542014-05-30 21:53:31 +053018247 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053018248 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
18249 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053018250 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053018251 {
18252 rate_flags = pAdapter->maxRateFlags;
18253 }
c_hpothu44ff4e02014-05-08 00:13:57 +053018254
Jeff Johnson295189b2012-06-20 16:38:30 -070018255 //convert to the UI units of 100kbps
18256 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
18257
18258#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070018259 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 -070018260 sinfo->signal,
18261 pCfg->reportMaxLinkSpeed,
18262 myRate,
18263 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018264 (int) pCfg->linkSpeedRssiMid,
18265 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070018266 (int) rate_flags,
18267 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070018268#endif //LINKSPEED_DEBUG_ENABLED
18269
Hanumanth Reddy Pothula596b8b32018-05-01 20:17:38 +053018270#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || defined(WITH_BACKPORTS)
18271 /* assume basic BW. anything else will override this later */
18272 sinfo->txrate.bw = RATE_INFO_BW_20;
18273#endif
18274
Jeff Johnson295189b2012-06-20 16:38:30 -070018275 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
18276 {
18277 // we do not want to necessarily report the current speed
18278 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
18279 {
18280 // report the max possible speed
18281 rssidx = 0;
18282 }
18283 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
18284 {
18285 // report the max possible speed with RSSI scaling
18286 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
18287 {
18288 // report the max possible speed
18289 rssidx = 0;
18290 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018291 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070018292 {
18293 // report middle speed
18294 rssidx = 1;
18295 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018296 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
18297 {
18298 // report middle speed
18299 rssidx = 2;
18300 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018301 else
18302 {
18303 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018304 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070018305 }
18306 }
18307 else
18308 {
18309 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
18310 hddLog(VOS_TRACE_LEVEL_ERROR,
18311 "%s: Invalid value for reportMaxLinkSpeed: %u",
18312 __func__, pCfg->reportMaxLinkSpeed);
18313 rssidx = 0;
18314 }
18315
18316 maxRate = 0;
18317
18318 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018319 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
18320 OperationalRates, &ORLeng))
18321 {
18322 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18323 /*To keep GUI happy*/
18324 return 0;
18325 }
18326
Jeff Johnson295189b2012-06-20 16:38:30 -070018327 for (i = 0; i < ORLeng; i++)
18328 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018329 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018330 {
18331 /* Validate Rate Set */
18332 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
18333 {
18334 currentRate = supported_data_rate[j].supported_rate[rssidx];
18335 break;
18336 }
18337 }
18338 /* Update MAX rate */
18339 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18340 }
18341
18342 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018343 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
18344 ExtendedRates, &ERLeng))
18345 {
18346 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18347 /*To keep GUI happy*/
18348 return 0;
18349 }
18350
Jeff Johnson295189b2012-06-20 16:38:30 -070018351 for (i = 0; i < ERLeng; i++)
18352 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018353 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018354 {
18355 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
18356 {
18357 currentRate = supported_data_rate[j].supported_rate[rssidx];
18358 break;
18359 }
18360 }
18361 /* Update MAX rate */
18362 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18363 }
c_hpothu79aab322014-07-14 21:11:01 +053018364
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018365 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053018366 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018367 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053018368 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070018369 {
c_hpothu79aab322014-07-14 21:11:01 +053018370 if (rate_flags & eHAL_TX_RATE_VHT80)
18371 mode = 2;
18372 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
18373 mode = 1;
18374 else
18375 mode = 0;
18376
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018377 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
18378 MCSRates, &MCSLeng))
18379 {
18380 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18381 /*To keep GUI happy*/
18382 return 0;
18383 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018384 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070018385#ifdef WLAN_FEATURE_11AC
18386 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018387 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070018388 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018389 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018390 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070018391 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070018392 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018393 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018394 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018395 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070018396 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018397 maxMCSIdx = 7;
18398 }
18399 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
18400 {
18401 maxMCSIdx = 8;
18402 }
18403 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
18404 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018405 //VHT20 is supporting 0~8
18406 if (rate_flags & eHAL_TX_RATE_VHT20)
18407 maxMCSIdx = 8;
18408 else
18409 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070018410 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018411
c_hpothu79aab322014-07-14 21:11:01 +053018412 if (0 != rssidx)/*check for scaled */
18413 {
18414 //get middle rate MCS index if rssi=1/2
18415 for (i=0; i <= maxMCSIdx; i++)
18416 {
18417 if (sinfo->signal <= rssiMcsTbl[mode][i])
18418 {
18419 maxMCSIdx = i;
18420 break;
18421 }
18422 }
18423 }
18424
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018425 if (rate_flags & eHAL_TX_RATE_VHT80)
18426 {
18427 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
18428 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
18429 }
18430 else if (rate_flags & eHAL_TX_RATE_VHT40)
18431 {
18432 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
18433 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
18434 }
18435 else if (rate_flags & eHAL_TX_RATE_VHT20)
18436 {
18437 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
18438 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
18439 }
18440
Leo Chang6f8870f2013-03-26 18:11:36 -070018441 maxSpeedMCS = 1;
18442 if (currentRate > maxRate)
18443 {
18444 maxRate = currentRate;
18445 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018446
Leo Chang6f8870f2013-03-26 18:11:36 -070018447 }
18448 else
18449#endif /* WLAN_FEATURE_11AC */
18450 {
18451 if (rate_flags & eHAL_TX_RATE_HT40)
18452 {
18453 rateFlag |= 1;
18454 }
18455 if (rate_flags & eHAL_TX_RATE_SGI)
18456 {
18457 rateFlag |= 2;
18458 }
18459
Girish Gowli01abcee2014-07-31 20:18:55 +053018460 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053018461 if (rssidx == 1 || rssidx == 2)
18462 {
18463 //get middle rate MCS index if rssi=1/2
18464 for (i=0; i <= 7; i++)
18465 {
18466 if (sinfo->signal <= rssiMcsTbl[mode][i])
18467 {
18468 temp = i+1;
18469 break;
18470 }
18471 }
18472 }
c_hpothu79aab322014-07-14 21:11:01 +053018473
18474 for (i = 0; i < MCSLeng; i++)
18475 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018476 for (j = 0; j < temp; j++)
18477 {
18478 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
18479 {
18480 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018481 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018482 break;
18483 }
18484 }
18485 if ((j < temp) && (currentRate > maxRate))
18486 {
18487 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070018488 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018489 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018490 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018491 }
18492 }
18493
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018494 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
18495 {
18496 maxRate = myRate;
18497 maxSpeedMCS = 1;
18498 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18499 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018500 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053018501 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070018502 {
18503 maxRate = myRate;
18504 if (rate_flags & eHAL_TX_RATE_LEGACY)
18505 {
18506 maxSpeedMCS = 0;
18507 }
18508 else
18509 {
18510 maxSpeedMCS = 1;
18511 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18512 }
18513 }
18514
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018515 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070018516 {
18517 sinfo->txrate.legacy = maxRate;
18518#ifdef LINKSPEED_DEBUG_ENABLED
18519 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
18520#endif //LINKSPEED_DEBUG_ENABLED
18521 }
18522 else
18523 {
18524 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070018525#ifdef WLAN_FEATURE_11AC
18526 sinfo->txrate.nss = 1;
18527 if (rate_flags & eHAL_TX_RATE_VHT80)
18528 {
18529 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018530#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18531 defined(WITH_BACKPORTS)
18532 sinfo->txrate.bw = RATE_INFO_BW_80;
18533#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018534 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018535#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018536 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018537 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070018538 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018539 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018540#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18541 defined(WITH_BACKPORTS)
18542 sinfo->txrate.bw = RATE_INFO_BW_40;
18543#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018544 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018545#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018546 }
18547 else if (rate_flags & eHAL_TX_RATE_VHT20)
18548 {
18549 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18550 }
18551#endif /* WLAN_FEATURE_11AC */
18552 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
18553 {
18554 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18555 if (rate_flags & eHAL_TX_RATE_HT40)
18556 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018557#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18558 defined(WITH_BACKPORTS)
18559 sinfo->txrate.bw = RATE_INFO_BW_40;
18560#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018561 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018562#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018563 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018564 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018565 if (rate_flags & eHAL_TX_RATE_SGI)
18566 {
18567 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18568 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018569
Jeff Johnson295189b2012-06-20 16:38:30 -070018570#ifdef LINKSPEED_DEBUG_ENABLED
18571 pr_info("Reporting MCS rate %d flags %x\n",
18572 sinfo->txrate.mcs,
18573 sinfo->txrate.flags );
18574#endif //LINKSPEED_DEBUG_ENABLED
18575 }
18576 }
18577 else
18578 {
18579 // report current rate instead of max rate
18580
18581 if (rate_flags & eHAL_TX_RATE_LEGACY)
18582 {
18583 //provide to the UI in units of 100kbps
18584 sinfo->txrate.legacy = myRate;
18585#ifdef LINKSPEED_DEBUG_ENABLED
18586 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
18587#endif //LINKSPEED_DEBUG_ENABLED
18588 }
18589 else
18590 {
18591 //must be MCS
18592 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018593#ifdef WLAN_FEATURE_11AC
18594 sinfo->txrate.nss = 1;
18595 if (rate_flags & eHAL_TX_RATE_VHT80)
18596 {
18597 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18598 }
18599 else
18600#endif /* WLAN_FEATURE_11AC */
18601 {
18602 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18603 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018604 if (rate_flags & eHAL_TX_RATE_SGI)
18605 {
18606 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18607 }
18608 if (rate_flags & eHAL_TX_RATE_HT40)
18609 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018610#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18611 defined(WITH_BACKPORTS)
18612 sinfo->txrate.bw = RATE_INFO_BW_40;
18613#else
Jeff Johnson295189b2012-06-20 16:38:30 -070018614 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018615#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018616 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018617#ifdef WLAN_FEATURE_11AC
18618 else if (rate_flags & eHAL_TX_RATE_VHT80)
18619 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018620#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18621 defined(WITH_BACKPORTS)
18622 sinfo->txrate.bw = RATE_INFO_BW_80;
18623#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018624 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018625#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018626 }
18627#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018628#ifdef LINKSPEED_DEBUG_ENABLED
18629 pr_info("Reporting actual MCS rate %d flags %x\n",
18630 sinfo->txrate.mcs,
18631 sinfo->txrate.flags );
18632#endif //LINKSPEED_DEBUG_ENABLED
18633 }
18634 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018635
18636#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18637 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018638 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018639#else
18640 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18641#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018642
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018643 sinfo->tx_packets =
18644 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18645 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18646 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18647 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18648
18649 sinfo->tx_retries =
18650 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18651 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18652 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18653 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18654
18655 sinfo->tx_failed =
18656 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18657 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18658 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18659 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18660
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018661#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18662 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018663 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018664 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018665 STATION_INFO_TX_PACKETS |
18666 STATION_INFO_TX_RETRIES |
18667 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018668#else
18669 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18670 BIT(NL80211_STA_INFO_TX_PACKETS) |
18671 BIT(NL80211_STA_INFO_TX_RETRIES) |
18672 BIT(NL80211_STA_INFO_TX_FAILED);
18673#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018674
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018675 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018676
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018677 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18678 &sinfo->txrate, sizeof(sinfo->txrate));
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018679 vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate,
18680 &sinfo->txrate, sizeof(sinfo->txrate));
18681
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018682 if (rate_flags & eHAL_TX_RATE_LEGACY)
18683 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18684 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18685 sinfo->rx_packets);
18686 else
18687 hddLog(LOG1,
18688 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18689 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18690 sinfo->tx_packets, sinfo->rx_packets);
18691
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018692 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18693 TRACE_CODE_HDD_CFG80211_GET_STA,
18694 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018695 EXIT();
18696 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018697}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018698#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18699static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18700 const u8* mac, struct station_info *sinfo)
18701#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018702static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18703 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018704#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018705{
18706 int ret;
18707
18708 vos_ssr_protect(__func__);
18709 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18710 vos_ssr_unprotect(__func__);
18711
18712 return ret;
18713}
18714
18715static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018716 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018717{
18718 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018719 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018720 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018721 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018722
Jeff Johnsone7245742012-09-05 17:12:55 -070018723 ENTER();
18724
Jeff Johnson295189b2012-06-20 16:38:30 -070018725 if (NULL == pAdapter)
18726 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018727 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018728 return -ENODEV;
18729 }
18730
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018731 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18732 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18733 pAdapter->sessionId, timeout));
18734
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018735 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018736 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018737 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018738 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018739 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018740 }
18741
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018742 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
18743 (TRUE == pHddCtx->hdd_wlan_suspended) &&
18744 (pHddCtx->cfg_ini->fhostArpOffload) &&
18745 (eConnectionState_Associated ==
18746 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
18747 {
Amar Singhald53568e2013-09-26 11:03:45 -070018748
18749 hddLog(VOS_TRACE_LEVEL_INFO,
18750 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053018751 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018752 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18753 {
18754 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018755 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018756 __func__, vos_status);
18757 }
18758 }
18759
Jeff Johnson295189b2012-06-20 16:38:30 -070018760 /**The get power cmd from the supplicant gets updated by the nl only
18761 *on successful execution of the function call
18762 *we are oppositely mapped w.r.t mode in the driver
18763 **/
18764 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
18765
18766 if (VOS_STATUS_E_FAILURE == vos_status)
18767 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18769 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018770 return -EINVAL;
18771 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018772 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018773 return 0;
18774}
18775
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018776static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
18777 struct net_device *dev, bool mode, int timeout)
18778{
18779 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018780
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018781 vos_ssr_protect(__func__);
18782 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
18783 vos_ssr_unprotect(__func__);
18784
18785 return ret;
18786}
Sushant Kaushik084f6592015-09-10 13:11:56 +053018787
Jeff Johnson295189b2012-06-20 16:38:30 -070018788#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018789static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
18790 struct net_device *netdev,
18791 u8 key_index)
18792{
18793 ENTER();
18794 return 0;
18795}
18796
Jeff Johnson295189b2012-06-20 16:38:30 -070018797static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018798 struct net_device *netdev,
18799 u8 key_index)
18800{
18801 int ret;
18802 vos_ssr_protect(__func__);
18803 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
18804 vos_ssr_unprotect(__func__);
18805 return ret;
18806}
18807#endif //LINUX_VERSION_CODE
18808
18809#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18810static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18811 struct net_device *dev,
18812 struct ieee80211_txq_params *params)
18813{
18814 ENTER();
18815 return 0;
18816}
18817#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18818static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18819 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018820{
Jeff Johnsone7245742012-09-05 17:12:55 -070018821 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070018822 return 0;
18823}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018824#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070018825
18826#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18827static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018828 struct net_device *dev,
18829 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018830{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018831 int ret;
18832
18833 vos_ssr_protect(__func__);
18834 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
18835 vos_ssr_unprotect(__func__);
18836 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018837}
18838#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18839static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
18840 struct ieee80211_txq_params *params)
18841{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018842 int ret;
18843
18844 vos_ssr_protect(__func__);
18845 ret = __wlan_hdd_set_txq_params(wiphy, params);
18846 vos_ssr_unprotect(__func__);
18847 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018848}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018849#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018850
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018851static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018852 struct net_device *dev,
18853 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070018854{
18855 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018856 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018857 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018858 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018859 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018860 v_CONTEXT_t pVosContext = NULL;
18861 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018862
Jeff Johnsone7245742012-09-05 17:12:55 -070018863 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018864
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018865 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070018866 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018867 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018868 return -EINVAL;
18869 }
18870
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018871 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18872 TRACE_CODE_HDD_CFG80211_DEL_STA,
18873 pAdapter->sessionId, pAdapter->device_mode));
18874
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018875 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18876 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018877 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018878 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018879 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018880 }
18881
Jeff Johnson295189b2012-06-20 16:38:30 -070018882 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018883 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018884 )
18885 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018886 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
18887 pSapCtx = VOS_GET_SAP_CB(pVosContext);
18888 if(pSapCtx == NULL){
18889 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18890 FL("psapCtx is NULL"));
18891 return -ENOENT;
18892 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053018893 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
18894 {
18895 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
18896 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
18897 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
18898 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018899 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070018900 {
18901 v_U16_t i;
18902 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
18903 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018904 if ((pSapCtx->aStaInfo[i].isUsed) &&
18905 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070018906 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018907 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018908 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018909 ETHER_ADDR_LEN);
18910
Jeff Johnson295189b2012-06-20 16:38:30 -070018911 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018912 "%s: Delete STA with MAC::"
18913 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018914 __func__,
18915 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18916 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018917 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018918 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018919 }
18920 }
18921 }
18922 else
18923 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018924
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018925 vos_status = hdd_softap_GetStaId(pAdapter,
18926 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018927 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18928 {
18929 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018930 "%s: Skip this DEL STA as this is not used::"
18931 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018932 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018933 return -ENOENT;
18934 }
18935
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018936 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018937 {
18938 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018939 "%s: Skip this DEL STA as deauth is in progress::"
18940 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018941 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018942 return -ENOENT;
18943 }
18944
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018945 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018946
Jeff Johnson295189b2012-06-20 16:38:30 -070018947 hddLog(VOS_TRACE_LEVEL_INFO,
18948 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018949 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018950 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018951 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018952
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018953 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018954 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18955 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018956 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018957 hddLog(VOS_TRACE_LEVEL_INFO,
18958 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018959 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018960 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018961 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018962 return -ENOENT;
18963 }
18964
Jeff Johnson295189b2012-06-20 16:38:30 -070018965 }
18966 }
18967
18968 EXIT();
18969
18970 return 0;
18971}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018972
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018973#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018974int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018975 struct net_device *dev,
18976 struct station_del_parameters *param)
18977#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018978#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018979int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018980 struct net_device *dev, const u8 *mac)
18981#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018982int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018983 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018984#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018985#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018986{
18987 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018988 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018989
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018990 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018991
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018992#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018993 if (NULL == param) {
18994 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018995 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018996 return -EINVAL;
18997 }
18998
18999 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
19000 param->subtype, &delStaParams);
19001
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019002#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053019003 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019004 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019005#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019006 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
19007
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019008 vos_ssr_unprotect(__func__);
19009
19010 return ret;
19011}
19012
19013static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019014 struct net_device *dev,
19015#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19016 const u8 *mac,
19017#else
19018 u8 *mac,
19019#endif
19020 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019021{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019022 hdd_adapter_t *pAdapter;
19023 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019024 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019025#ifdef FEATURE_WLAN_TDLS
19026 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019027
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019028 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019029
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019030 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19031 if (NULL == pAdapter)
19032 {
19033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19034 "%s: Adapter is NULL",__func__);
19035 return -EINVAL;
19036 }
19037 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19038 status = wlan_hdd_validate_context(pHddCtx);
19039 if (0 != status)
19040 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019041 return status;
19042 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019043
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019044 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19045 TRACE_CODE_HDD_CFG80211_ADD_STA,
19046 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019047 mask = params->sta_flags_mask;
19048
19049 set = params->sta_flags_set;
19050
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019052 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
19053 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019054
19055 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
19056 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080019057 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019058 }
19059 }
19060#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019061 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019062 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070019063}
19064
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019065#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19066static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19067 struct net_device *dev, const u8 *mac,
19068 struct station_parameters *params)
19069#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019070static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19071 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019072#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019073{
19074 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019075
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019076 vos_ssr_protect(__func__);
19077 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
19078 vos_ssr_unprotect(__func__);
19079
19080 return ret;
19081}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019082#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070019083
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019084static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070019085 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019086{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019087 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19088 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019089 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019090 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019091 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019092 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070019093
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019094 ENTER();
19095
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019096 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019097 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019098 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019099 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019100 return -EINVAL;
19101 }
19102
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019103 if (!pmksa) {
19104 hddLog(LOGE, FL("pmksa is NULL"));
19105 return -EINVAL;
19106 }
19107
19108 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070019109 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019110 pmksa->bssid, pmksa->pmkid);
19111 return -EINVAL;
19112 }
19113
19114 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
19115 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19116
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019117 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19118 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019119 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019120 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019121 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019122 }
19123
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019124 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019125 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19126
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019127 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
19128 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019129
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019130 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019131 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019132 &pmk_id, 1, FALSE);
19133
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019134 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19135 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
19136 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019137
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019138 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019139 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019140}
19141
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019142static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
19143 struct cfg80211_pmksa *pmksa)
19144{
19145 int ret;
19146
19147 vos_ssr_protect(__func__);
19148 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
19149 vos_ssr_unprotect(__func__);
19150
19151 return ret;
19152}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019153
Wilson Yang6507c4e2013-10-01 20:11:19 -070019154
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019155static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070019156 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019157{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019158 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19159 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019160 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019161 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019162
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019163 ENTER();
19164
Wilson Yang6507c4e2013-10-01 20:11:19 -070019165 /* Validate pAdapter */
19166 if (NULL == pAdapter)
19167 {
19168 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
19169 return -EINVAL;
19170 }
19171
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019172 if (!pmksa) {
19173 hddLog(LOGE, FL("pmksa is NULL"));
19174 return -EINVAL;
19175 }
19176
19177 if (!pmksa->bssid) {
19178 hddLog(LOGE, FL("pmksa->bssid is NULL"));
19179 return -EINVAL;
19180 }
19181
Kiet Lam98c46a12014-10-31 15:34:57 -070019182 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
19183 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19184
Wilson Yang6507c4e2013-10-01 20:11:19 -070019185 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19186 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019187 if (0 != status)
19188 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019189 return status;
19190 }
19191
19192 /*Retrieve halHandle*/
19193 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19194
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019195 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19196 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
19197 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019198 /* Delete the PMKID CSR cache */
19199 if (eHAL_STATUS_SUCCESS !=
19200 sme_RoamDelPMKIDfromCache(halHandle,
19201 pAdapter->sessionId, pmksa->bssid, FALSE)) {
19202 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
19203 MAC_ADDR_ARRAY(pmksa->bssid));
19204 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019205 }
19206
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019207 EXIT();
19208 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019209}
19210
Wilson Yang6507c4e2013-10-01 20:11:19 -070019211
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019212static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
19213 struct cfg80211_pmksa *pmksa)
19214{
19215 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019216
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019217 vos_ssr_protect(__func__);
19218 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
19219 vos_ssr_unprotect(__func__);
19220
19221 return ret;
19222
19223}
19224
19225static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019226{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019227 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19228 tHalHandle halHandle;
19229 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019230 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019231
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019232 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070019233
19234 /* Validate pAdapter */
19235 if (NULL == pAdapter)
19236 {
19237 hddLog(VOS_TRACE_LEVEL_ERROR,
19238 "%s: Invalid Adapter" ,__func__);
19239 return -EINVAL;
19240 }
19241
19242 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19243 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019244 if (0 != status)
19245 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019246 return status;
19247 }
19248
19249 /*Retrieve halHandle*/
19250 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19251
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019252 /* Flush the PMKID cache in CSR */
19253 if (eHAL_STATUS_SUCCESS !=
19254 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
19255 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
19256 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019257 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019258 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080019259 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019260}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019261
19262static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
19263{
19264 int ret;
19265
19266 vos_ssr_protect(__func__);
19267 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
19268 vos_ssr_unprotect(__func__);
19269
19270 return ret;
19271}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019272#endif
19273
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019274#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019275static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19276 struct net_device *dev,
19277 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019278{
19279 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19280 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019281 hdd_context_t *pHddCtx;
19282 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019283
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019284 ENTER();
19285
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019286 if (NULL == pAdapter)
19287 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019288 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019289 return -ENODEV;
19290 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019291 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19292 ret = wlan_hdd_validate_context(pHddCtx);
19293 if (0 != ret)
19294 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019295 return ret;
19296 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019297 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019298 if (NULL == pHddStaCtx)
19299 {
19300 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
19301 return -EINVAL;
19302 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019303
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019304 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19305 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
19306 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019307 // Added for debug on reception of Re-assoc Req.
19308 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
19309 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019310 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019311 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080019312 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019313 }
19314
19315#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080019316 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019317 ftie->ie_len);
19318#endif
19319
19320 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053019321 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
19322 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019323 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019324
19325 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019326 return 0;
19327}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019328
19329static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19330 struct net_device *dev,
19331 struct cfg80211_update_ft_ies_params *ftie)
19332{
19333 int ret;
19334
19335 vos_ssr_protect(__func__);
19336 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
19337 vos_ssr_unprotect(__func__);
19338
19339 return ret;
19340}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019341#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019342
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019343#ifdef FEATURE_WLAN_SCAN_PNO
19344
19345void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
19346 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
19347{
19348 int ret;
19349 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
19350 hdd_context_t *pHddCtx;
19351
Nirav Shah80830bf2013-12-31 16:35:12 +053019352 ENTER();
19353
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019354 if (NULL == pAdapter)
19355 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019357 "%s: HDD adapter is Null", __func__);
19358 return ;
19359 }
19360
19361 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19362 if (NULL == pHddCtx)
19363 {
19364 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19365 "%s: HDD context is Null!!!", __func__);
19366 return ;
19367 }
19368
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019369 spin_lock(&pHddCtx->schedScan_lock);
19370 if (TRUE == pHddCtx->isWiphySuspended)
19371 {
19372 pHddCtx->isSchedScanUpdatePending = TRUE;
19373 spin_unlock(&pHddCtx->schedScan_lock);
19374 hddLog(VOS_TRACE_LEVEL_INFO,
19375 "%s: Update cfg80211 scan database after it resume", __func__);
19376 return ;
19377 }
19378 spin_unlock(&pHddCtx->schedScan_lock);
19379
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019380 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
19381
19382 if (0 > ret)
19383 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053019384 else
19385 {
19386 /* Acquire wakelock to handle the case where APP's tries to suspend
19387 * immediatly after the driver gets connect request(i.e after pno)
19388 * from supplicant, this result in app's is suspending and not able
19389 * to process the connect request to AP */
19390 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
19391 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019392 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19394 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019395}
19396
19397/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019398 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019399 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019400 */
19401static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
19402{
19403 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
19404 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019405 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019406 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19407 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053019408
19409 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
19410 {
19411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19412 "%s: PNO is allowed only in STA interface", __func__);
19413 return eHAL_STATUS_FAILURE;
19414 }
19415
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019416 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
19417
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019418 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053019419 * active sessions. PNO is allowed only in case when sap session
19420 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019421 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019422 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
19423 {
19424 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019425 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019426
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019427 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
19428 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
19429 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
19430 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053019431 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
19432 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053019433 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019434 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019435 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019436 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019437 }
19438 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19439 pAdapterNode = pNext;
19440 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019441 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019442}
19443
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019444void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
19445{
19446 hdd_adapter_t *pAdapter = callbackContext;
19447 hdd_context_t *pHddCtx;
19448
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019449 ENTER();
19450
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019451 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
19452 {
19453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19454 FL("Invalid adapter or adapter has invalid magic"));
19455 return;
19456 }
19457
19458 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19459 if (0 != wlan_hdd_validate_context(pHddCtx))
19460 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019461 return;
19462 }
19463
c_hpothub53c45d2014-08-18 16:53:14 +053019464 if (VOS_STATUS_SUCCESS != status)
19465 {
19466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019467 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053019468 pHddCtx->isPnoEnable = FALSE;
19469 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019470
19471 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
19472 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019473 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019474}
19475
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019476#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
19477 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
19478/**
19479 * hdd_config_sched_scan_plan() - configures the sched scan plans
19480 * from the framework.
19481 * @pno_req: pointer to PNO scan request
19482 * @request: pointer to scan request from framework
19483 *
19484 * Return: None
19485 */
19486static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
19487 struct cfg80211_sched_scan_request *request,
19488 hdd_context_t *hdd_ctx)
19489{
19490 v_U32_t i = 0;
19491
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019492 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019493 for (i = 0; i < request->n_scan_plans; i++)
19494 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019495 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
19496 request->scan_plans[i].iterations;
19497 pno_req->scanTimers.aTimerValues[i].uTimerValue =
19498 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019499 }
19500}
19501#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019502static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019503 struct cfg80211_sched_scan_request *request,
19504 hdd_context_t *hdd_ctx)
19505{
19506 v_U32_t i, temp_int;
19507 /* Driver gets only one time interval which is hardcoded in
19508 * supplicant for 10000ms. Taking power consumption into account 6
19509 * timers will be used, Timervalue is increased exponentially
19510 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
19511 * timer is configurable through INI param gPNOScanTimerRepeatValue.
19512 * If it is set to 0 only one timer will be used and PNO scan cycle
19513 * will be repeated after each interval specified by supplicant
19514 * till PNO is disabled.
19515 */
19516 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019517 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019518 HDD_PNO_SCAN_TIMERS_SET_ONE;
19519 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019520 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019521 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
19522
19523 temp_int = (request->interval)/1000;
19524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19525 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
19526 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019527 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019528 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019529 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019530 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019531 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019532 temp_int *= 2;
19533 }
19534 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019535 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019536}
19537#endif
19538
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019539/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019540 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
19541 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019542 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019543static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019544 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19545{
19546 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019547 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019548 hdd_context_t *pHddCtx;
19549 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019550 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053019551 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
19552 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019553 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
19554 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019555 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019556 hdd_config_t *pConfig = NULL;
19557 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019558
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019559 ENTER();
19560
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019561 if (NULL == pAdapter)
19562 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019564 "%s: HDD adapter is Null", __func__);
19565 return -ENODEV;
19566 }
19567
19568 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019569 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019570
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019571 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019572 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019573 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019574 }
19575
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019576 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019577 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19578 if (NULL == hHal)
19579 {
19580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19581 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019582 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019583 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019584 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19585 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
19586 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019587 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053019588 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019589 {
19590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19591 "%s: aborting the existing scan is unsuccessfull", __func__);
19592 return -EBUSY;
19593 }
19594
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019595 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019596 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019598 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019599 return -EBUSY;
19600 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019601
c_hpothu37f21312014-04-09 21:49:54 +053019602 if (TRUE == pHddCtx->isPnoEnable)
19603 {
19604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19605 FL("already PNO is enabled"));
19606 return -EBUSY;
19607 }
c_hpothu225aa7c2014-10-22 17:45:13 +053019608
19609 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
19610 {
19611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19612 "%s: abort ROC failed ", __func__);
19613 return -EBUSY;
19614 }
19615
c_hpothu37f21312014-04-09 21:49:54 +053019616 pHddCtx->isPnoEnable = TRUE;
19617
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019618 pnoRequest.enable = 1; /*Enable PNO */
19619 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019620
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019621 if (( !pnoRequest.ucNetworksCount ) ||
19622 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019623 {
19624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019625 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019626 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019627 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019628 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019629 goto error;
19630 }
19631
19632 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
19633 {
19634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019635 "%s: Incorrect number of channels %d",
19636 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019637 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019638 goto error;
19639 }
19640
19641 /* Framework provides one set of channels(all)
19642 * common for all saved profile */
19643 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
19644 channels_allowed, &num_channels_allowed))
19645 {
19646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19647 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019648 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019649 goto error;
19650 }
19651 /* Checking each channel against allowed channel list */
19652 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053019653 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019654 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019655 char chList [(request->n_channels*5)+1];
19656 int len;
19657 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019658 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019659 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019660 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019661 if (request->channels[i]->hw_value == channels_allowed[indx])
19662 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019663 if ((!pConfig->enableDFSPnoChnlScan) &&
19664 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
19665 {
19666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19667 "%s : Dropping DFS channel : %d",
19668 __func__,channels_allowed[indx]);
19669 num_ignore_dfs_ch++;
19670 break;
19671 }
19672
Nirav Shah80830bf2013-12-31 16:35:12 +053019673 valid_ch[num_ch++] = request->channels[i]->hw_value;
19674 len += snprintf(chList+len, 5, "%d ",
19675 request->channels[i]->hw_value);
19676 break ;
19677 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019678 }
19679 }
Nirav Shah80830bf2013-12-31 16:35:12 +053019680 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019681
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019682 /*If all channels are DFS and dropped, then ignore the PNO request*/
19683 if (num_ignore_dfs_ch == request->n_channels)
19684 {
19685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19686 "%s : All requested channels are DFS channels", __func__);
19687 ret = -EINVAL;
19688 goto error;
19689 }
19690 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019691
19692 pnoRequest.aNetworks =
19693 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19694 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019695 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019696 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19697 FL("failed to allocate memory aNetworks %u"),
19698 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19699 goto error;
19700 }
19701 vos_mem_zero(pnoRequest.aNetworks,
19702 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19703
19704 /* Filling per profile params */
19705 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
19706 {
19707 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019708 request->match_sets[i].ssid.ssid_len;
19709
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019710 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
19711 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019712 {
19713 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019714 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019715 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019716 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019717 goto error;
19718 }
19719
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019720 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019721 request->match_sets[i].ssid.ssid,
19722 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19724 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019725 i, pnoRequest.aNetworks[i].ssId.ssId);
19726 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
19727 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
19728 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019729
19730 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019731 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
19732 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019733
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019734 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019735 }
19736
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019737 for (i = 0; i < request->n_ssids; i++)
19738 {
19739 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019740 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019741 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019742 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019743 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019744 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019745 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019746 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019747 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019748 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019749 break;
19750 }
19751 j++;
19752 }
19753 }
19754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19755 "Number of hidden networks being Configured = %d",
19756 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080019758 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019759
19760 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19761 if (pnoRequest.p24GProbeTemplate == NULL)
19762 {
19763 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19764 FL("failed to allocate memory p24GProbeTemplate %u"),
19765 SIR_PNO_MAX_PB_REQ_SIZE);
19766 goto error;
19767 }
19768
19769 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19770 if (pnoRequest.p5GProbeTemplate == NULL)
19771 {
19772 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19773 FL("failed to allocate memory p5GProbeTemplate %u"),
19774 SIR_PNO_MAX_PB_REQ_SIZE);
19775 goto error;
19776 }
19777
19778 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19779 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19780
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053019781 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
19782 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019783 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019784 pnoRequest.us24GProbeTemplateLen = request->ie_len;
19785 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
19786 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019787
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019788 pnoRequest.us5GProbeTemplateLen = request->ie_len;
19789 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
19790 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019791 }
19792
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019793 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053019794
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019795 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019796
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019797 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019798 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19799 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019800 pAdapter->pno_req_status = 0;
19801
Nirav Shah80830bf2013-12-31 16:35:12 +053019802 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19803 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019804 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
19805 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053019806
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019807 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019808 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019809 hdd_cfg80211_sched_scan_done_callback, pAdapter);
19810 if (eHAL_STATUS_SUCCESS != status)
19811 {
19812 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019813 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019814 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019815 goto error;
19816 }
19817
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019818 ret = wait_for_completion_timeout(
19819 &pAdapter->pno_comp_var,
19820 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19821 if (0 >= ret)
19822 {
19823 // Did not receive the response for PNO enable in time.
19824 // Assuming the PNO enable was success.
19825 // Returning error from here, because we timeout, results
19826 // in side effect of Wifi (Wifi Setting) not to work.
19827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19828 FL("Timed out waiting for PNO to be Enabled"));
19829 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019830 }
19831
19832 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053019833 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019834
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019835error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19837 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053019838 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019839 if (pnoRequest.aNetworks)
19840 vos_mem_free(pnoRequest.aNetworks);
19841 if (pnoRequest.p24GProbeTemplate)
19842 vos_mem_free(pnoRequest.p24GProbeTemplate);
19843 if (pnoRequest.p5GProbeTemplate)
19844 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019845
19846 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019847 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019848}
19849
19850/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019851 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
19852 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019853 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019854static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
19855 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19856{
19857 int ret;
19858
19859 vos_ssr_protect(__func__);
19860 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
19861 vos_ssr_unprotect(__func__);
19862
19863 return ret;
19864}
19865
19866/*
19867 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
19868 * Function to disable PNO
19869 */
19870static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019871 struct net_device *dev)
19872{
19873 eHalStatus status = eHAL_STATUS_FAILURE;
19874 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19875 hdd_context_t *pHddCtx;
19876 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019877 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019878 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019879
19880 ENTER();
19881
19882 if (NULL == pAdapter)
19883 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019885 "%s: HDD adapter is Null", __func__);
19886 return -ENODEV;
19887 }
19888
19889 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019890
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019891 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019892 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019894 "%s: HDD context is Null", __func__);
19895 return -ENODEV;
19896 }
19897
19898 /* The return 0 is intentional when isLogpInProgress and
19899 * isLoadUnloadInProgress. We did observe a crash due to a return of
19900 * failure in sched_scan_stop , especially for a case where the unload
19901 * of the happens at the same time. The function __cfg80211_stop_sched_scan
19902 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
19903 * success. If it returns a failure , then its next invocation due to the
19904 * clean up of the second interface will have the dev pointer corresponding
19905 * to the first one leading to a crash.
19906 */
19907 if (pHddCtx->isLogpInProgress)
19908 {
19909 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19910 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019911 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019912 return ret;
19913 }
19914
Mihir Shete18156292014-03-11 15:38:30 +053019915 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019916 {
19917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19918 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19919 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019920 }
19921
19922 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19923 if (NULL == hHal)
19924 {
19925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19926 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019927 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019928 }
19929
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019930 pnoRequest.enable = 0; /* Disable PNO */
19931 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019932
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019933 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19934 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19935 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019936
19937 INIT_COMPLETION(pAdapter->pno_comp_var);
19938 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19939 pnoRequest.callbackContext = pAdapter;
19940 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019941 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019942 pAdapter->sessionId,
19943 NULL, pAdapter);
19944 if (eHAL_STATUS_SUCCESS != status)
19945 {
19946 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19947 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019948 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019949 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019950 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019951 ret = wait_for_completion_timeout(
19952 &pAdapter->pno_comp_var,
19953 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19954 if (0 >= ret)
19955 {
19956 // Did not receive the response for PNO disable in time.
19957 // Assuming the PNO disable was success.
19958 // Returning error from here, because we timeout, results
19959 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019961 FL("Timed out waiting for PNO to be disabled"));
19962 ret = 0;
19963 }
19964
19965 ret = pAdapter->pno_req_status;
19966 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019967
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019968error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019969 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019970 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019971
19972 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019973 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019974}
19975
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019976/*
19977 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19978 * NL interface to disable PNO
19979 */
19980static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19981 struct net_device *dev)
19982{
19983 int ret;
19984
19985 vos_ssr_protect(__func__);
19986 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19987 vos_ssr_unprotect(__func__);
19988
19989 return ret;
19990}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019991#endif /*FEATURE_WLAN_SCAN_PNO*/
19992
19993
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019994#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019995#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019996static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19997 struct net_device *dev,
19998 u8 *peer, u8 action_code,
19999 u8 dialog_token,
20000 u16 status_code, u32 peer_capability,
20001 const u8 *buf, size_t len)
20002#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020003#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20004 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020005static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20006 struct net_device *dev,
20007 const u8 *peer, u8 action_code,
20008 u8 dialog_token, u16 status_code,
20009 u32 peer_capability, bool initiator,
20010 const u8 *buf, size_t len)
20011#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20012static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20013 struct net_device *dev,
20014 const u8 *peer, u8 action_code,
20015 u8 dialog_token, u16 status_code,
20016 u32 peer_capability, const u8 *buf,
20017 size_t len)
20018#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20019static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20020 struct net_device *dev,
20021 u8 *peer, u8 action_code,
20022 u8 dialog_token,
20023 u16 status_code, u32 peer_capability,
20024 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020025#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020026static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20027 struct net_device *dev,
20028 u8 *peer, u8 action_code,
20029 u8 dialog_token,
20030 u16 status_code, const u8 *buf,
20031 size_t len)
20032#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020033#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020034{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020035 hdd_adapter_t *pAdapter;
20036 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020037 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070020038 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080020039 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070020040 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020041 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020042 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020043#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020044 u32 peer_capability = 0;
20045#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020046 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020047 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020048 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020049
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020050 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20051 if (NULL == pAdapter)
20052 {
20053 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20054 "%s: Adapter is NULL",__func__);
20055 return -EINVAL;
20056 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020057 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20058 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
20059 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020060
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020061 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020062 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020063 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020064 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020065 "Invalid arguments");
20066 return -EINVAL;
20067 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020068
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020069 if (pHddCtx->isLogpInProgress)
20070 {
20071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20072 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053020073 wlan_hdd_tdls_set_link_status(pAdapter,
20074 peer,
20075 eTDLS_LINK_IDLE,
20076 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020077 return -EBUSY;
20078 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020079
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020080 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
20081 {
20082 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20083 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
20084 return -EAGAIN;
20085 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020086
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020087 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
20088 if (!pHddTdlsCtx) {
20089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20090 "%s: pHddTdlsCtx not valid.", __func__);
Hanumanth Reddy Pothula36dfa522018-03-12 16:42:08 +053020091 return -EINVAL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020092 }
20093
Hoonki Lee27511902013-03-14 18:19:06 -070020094 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020095 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020097 "%s: TDLS mode is disabled OR not enabled in FW."
20098 MAC_ADDRESS_STR " action %d declined.",
20099 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020100 return -ENOTSUPP;
20101 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020102
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020103 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20104
20105 if( NULL == pHddStaCtx )
20106 {
20107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20108 "%s: HDD station context NULL ",__func__);
20109 return -EINVAL;
20110 }
20111
20112 /* STA should be connected and authenticated
20113 * before sending any TDLS frames
20114 */
20115 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
20116 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
20117 {
20118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20119 "STA is not connected or unauthenticated. "
20120 "connState %u, uIsAuthenticated %u",
20121 pHddStaCtx->conn_info.connState,
20122 pHddStaCtx->conn_info.uIsAuthenticated);
20123 return -EAGAIN;
20124 }
20125
Hoonki Lee27511902013-03-14 18:19:06 -070020126 /* other than teardown frame, other mgmt frames are not sent if disabled */
20127 if (SIR_MAC_TDLS_TEARDOWN != action_code)
20128 {
20129 /* if tdls_mode is disabled to respond to peer's request */
20130 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
20131 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020133 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020134 " TDLS mode is disabled. action %d declined.",
20135 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070020136
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020137 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070020138 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053020139
20140 if (vos_max_concurrent_connections_reached())
20141 {
20142 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
20143 return -EINVAL;
20144 }
Hoonki Lee27511902013-03-14 18:19:06 -070020145 }
20146
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020147 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
20148 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053020149 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020150 {
20151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020152 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020153 " TDLS setup is ongoing. action %d declined.",
20154 __func__, MAC_ADDR_ARRAY(peer), action_code);
20155 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020156 }
20157 }
20158
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020159 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
20160 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080020161 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020162 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20163 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020164 {
20165 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
20166 we return error code at 'add_station()'. Hence we have this
20167 check again in addtion to add_station().
20168 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020169 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020170 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20172 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020173 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
20174 __func__, MAC_ADDR_ARRAY(peer), action_code,
20175 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053020176 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080020177 }
20178 else
20179 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020180 /* maximum reached. tweak to send error code to peer and return
20181 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020182 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20184 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020185 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
20186 __func__, MAC_ADDR_ARRAY(peer), status_code,
20187 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070020188 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020189 /* fall through to send setup resp with failure status
20190 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020191 }
20192 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020193 else
20194 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020195 mutex_lock(&pHddCtx->tdls_lock);
20196 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020197 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020198 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020199 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020201 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
20202 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020203 return -EPERM;
20204 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020205 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020206 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020207 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020208
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020209 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020210 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020211 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
20212 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020213
Hoonki Leea34dd892013-02-05 22:56:02 -080020214 /*Except teardown responder will not be used so just make 0*/
20215 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020216 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080020217 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020218
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020219 mutex_lock(&pHddCtx->tdls_lock);
20220 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020221
20222 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
20223 responder = pTdlsPeer->is_responder;
20224 else
Hoonki Leea34dd892013-02-05 22:56:02 -080020225 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020226 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020227 "%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 -070020228 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
20229 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020230 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020231 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080020232 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020233 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020234 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020235
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020236 /* Discard TDLS setup if peer is removed by user app */
20237 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
20238 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20239 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
20240 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
20241
20242 mutex_lock(&pHddCtx->tdls_lock);
20243 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20244 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
20245 mutex_unlock(&pHddCtx->tdls_lock);
20246 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
20247 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
20248 MAC_ADDR_ARRAY(peer), action_code);
20249 return -EINVAL;
20250 }
20251 mutex_unlock(&pHddCtx->tdls_lock);
20252 }
20253
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020254 /* For explicit trigger of DIS_REQ come out of BMPS for
20255 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070020256 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053020257 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020258 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
20259 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070020260 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020261 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020262 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020263 "%s: Sending frame action_code %u.Disable BMPS", __func__,
20264 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020265 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
20266 if (status != VOS_STATUS_SUCCESS) {
20267 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020268 } else {
20269 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020270 }
Hoonki Lee14621352013-04-16 17:51:19 -070020271 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020272 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020273 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020274 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
20275 }
20276 }
Hoonki Lee14621352013-04-16 17:51:19 -070020277 }
20278
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020279 /* make sure doesn't call send_mgmt() while it is pending */
20280 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
20281 {
20282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080020283 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020284 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020285 ret = -EBUSY;
20286 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020287 }
20288
20289 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020290 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
20291
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020292 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
20293 pAdapter->sessionId, peer, action_code, dialog_token,
20294 status_code, peer_capability, (tANI_U8 *)buf, len,
20295 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020296
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020297 if (VOS_STATUS_SUCCESS != status)
20298 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20300 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020301 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020302 ret = -EINVAL;
20303 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020304 }
20305
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020306 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20307 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
20308 WAIT_TIME_TDLS_MGMT);
20309
Hoonki Leed37cbb32013-04-20 00:31:14 -070020310 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
20311 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
20312
20313 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020314 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070020315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070020316 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070020317 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020318 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080020319
20320 if (pHddCtx->isLogpInProgress)
20321 {
20322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20323 "%s: LOGP in Progress. Ignore!!!", __func__);
20324 return -EAGAIN;
20325 }
Abhishek Singh837adf22015-10-01 17:37:37 +053020326 if (rc <= 0)
20327 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
20328 WLAN_LOG_INDICATOR_HOST_DRIVER,
20329 WLAN_LOG_REASON_HDD_TIME_OUT,
20330 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080020331
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020332 ret = -EINVAL;
20333 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020334 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020335 else
20336 {
20337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20338 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
20339 __func__, rc, pAdapter->mgmtTxCompletionStatus);
20340 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020341
Gopichand Nakkala05922802013-03-14 12:23:19 -070020342 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070020343 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020344 ret = max_sta_failed;
20345 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070020346 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020347
Hoonki Leea34dd892013-02-05 22:56:02 -080020348 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
20349 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020350 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20352 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020353 }
20354 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
20355 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020356 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020357 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20358 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020359 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020360
20361 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020362
20363tx_failed:
20364 /* add_station will be called before sending TDLS_SETUP_REQ and
20365 * TDLS_SETUP_RSP and as part of add_station driver will enable
20366 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
20367 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
20368 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
20369 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
20370 */
20371
20372 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20373 (SIR_MAC_TDLS_SETUP_RSP == action_code))
20374 wlan_hdd_tdls_check_bmps(pAdapter);
20375 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020376}
20377
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020378#if TDLS_MGMT_VERSION2
20379static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20380 u8 *peer, u8 action_code, u8 dialog_token,
20381 u16 status_code, u32 peer_capability,
20382 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020383#else /* TDLS_MGMT_VERSION2 */
20384#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20385static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20386 struct net_device *dev,
20387 const u8 *peer, u8 action_code,
20388 u8 dialog_token, u16 status_code,
20389 u32 peer_capability, bool initiator,
20390 const u8 *buf, size_t len)
20391#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20392static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20393 struct net_device *dev,
20394 const u8 *peer, u8 action_code,
20395 u8 dialog_token, u16 status_code,
20396 u32 peer_capability, const u8 *buf,
20397 size_t len)
20398#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20399static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20400 struct net_device *dev,
20401 u8 *peer, u8 action_code,
20402 u8 dialog_token,
20403 u16 status_code, u32 peer_capability,
20404 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020405#else
20406static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20407 u8 *peer, u8 action_code, u8 dialog_token,
20408 u16 status_code, const u8 *buf, size_t len)
20409#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020410#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020411{
20412 int ret;
20413
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020414 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020415#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020416 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20417 dialog_token, status_code,
20418 peer_capability, buf, len);
20419#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020420#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20421 defined(WITH_BACKPORTS)
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,
20424 peer_capability, initiator,
20425 buf, len);
20426#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20427 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20428 dialog_token, status_code,
20429 peer_capability, buf, len);
20430#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20431 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20432 dialog_token, status_code,
20433 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020434#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020435 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20436 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020437#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020438#endif
20439 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020440
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020441 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020442}
Atul Mittal115287b2014-07-08 13:26:33 +053020443
20444int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020445#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20446 const u8 *peer,
20447#else
Atul Mittal115287b2014-07-08 13:26:33 +053020448 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020449#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020450 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053020451 cfg80211_exttdls_callback callback)
20452{
20453
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020454 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053020455 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020456 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053020457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20458 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
20459 __func__, MAC_ADDR_ARRAY(peer));
20460
20461 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20462 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20463
20464 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020465 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20466 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20467 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020468 return -ENOTSUPP;
20469 }
20470
20471 /* To cater the requirement of establishing the TDLS link
20472 * irrespective of the data traffic , get an entry of TDLS peer.
20473 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020474 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020475 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
20476 if (pTdlsPeer == NULL) {
20477 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20478 "%s: peer " MAC_ADDRESS_STR " not existing",
20479 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020480 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020481 return -EINVAL;
20482 }
20483
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020484 /* check FW TDLS Off Channel capability */
20485 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020486 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020487 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020488 {
20489 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
20490 pTdlsPeer->peerParams.global_operating_class =
20491 tdls_peer_params->global_operating_class;
20492 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
20493 pTdlsPeer->peerParams.min_bandwidth_kbps =
20494 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020495 /* check configured channel is valid, non dfs and
20496 * not current operating channel */
20497 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
20498 tdls_peer_params->channel)) &&
20499 (pHddStaCtx) &&
20500 (tdls_peer_params->channel !=
20501 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020502 {
20503 pTdlsPeer->isOffChannelConfigured = TRUE;
20504 }
20505 else
20506 {
20507 pTdlsPeer->isOffChannelConfigured = FALSE;
20508 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20509 "%s: Configured Tdls Off Channel is not valid", __func__);
20510
20511 }
20512 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020513 "%s: tdls_off_channel %d isOffChannelConfigured %d "
20514 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020515 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020516 pTdlsPeer->isOffChannelConfigured,
20517 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020518 }
20519 else
20520 {
20521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020522 "%s: TDLS off channel FW capability %d, "
20523 "host capab %d or Invalid TDLS Peer Params", __func__,
20524 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
20525 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020526 }
20527
Atul Mittal115287b2014-07-08 13:26:33 +053020528 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
20529
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020530 mutex_unlock(&pHddCtx->tdls_lock);
20531
Atul Mittal115287b2014-07-08 13:26:33 +053020532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20533 " %s TDLS Add Force Peer Failed",
20534 __func__);
20535 return -EINVAL;
20536 }
20537 /*EXT TDLS*/
20538
20539 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020540 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20542 " %s TDLS set callback Failed",
20543 __func__);
20544 return -EINVAL;
20545 }
20546
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020547 mutex_unlock(&pHddCtx->tdls_lock);
20548
Atul Mittal115287b2014-07-08 13:26:33 +053020549 return(0);
20550
20551}
20552
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020553int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
20554#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20555 const u8 *peer
20556#else
20557 u8 *peer
20558#endif
20559)
Atul Mittal115287b2014-07-08 13:26:33 +053020560{
20561
20562 hddTdlsPeer_t *pTdlsPeer;
20563 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020564
Atul Mittal115287b2014-07-08 13:26:33 +053020565 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20566 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
20567 __func__, MAC_ADDR_ARRAY(peer));
20568
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020569 if (0 != wlan_hdd_validate_context(pHddCtx)) {
20570 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
20571 return -EINVAL;
20572 }
20573
Atul Mittal115287b2014-07-08 13:26:33 +053020574 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20575 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20576
20577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020578 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20579 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20580 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020581 return -ENOTSUPP;
20582 }
20583
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020584 mutex_lock(&pHddCtx->tdls_lock);
20585 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053020586
20587 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020588 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020589 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020590 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053020591 __func__, MAC_ADDR_ARRAY(peer));
20592 return -EINVAL;
20593 }
20594 else {
20595 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
20596 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020597 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
20598 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020599 /* if channel switch is configured, reset
20600 the channel for this peer */
20601 if (TRUE == pTdlsPeer->isOffChannelConfigured)
20602 {
20603 pTdlsPeer->peerParams.channel = 0;
20604 pTdlsPeer->isOffChannelConfigured = FALSE;
20605 }
Atul Mittal115287b2014-07-08 13:26:33 +053020606 }
20607
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020608 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020609 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020610 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053020611 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020612 }
Atul Mittal115287b2014-07-08 13:26:33 +053020613
20614 /*EXT TDLS*/
20615
20616 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020617 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20619 " %s TDLS set callback Failed",
20620 __func__);
20621 return -EINVAL;
20622 }
Atul Mittal115287b2014-07-08 13:26:33 +053020623
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020624 mutex_unlock(&pHddCtx->tdls_lock);
20625
20626 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053020627}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020628static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020629#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20630 const u8 *peer,
20631#else
20632 u8 *peer,
20633#endif
20634 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020635{
20636 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20637 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020638 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020639 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020640
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020641 ENTER();
20642
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020643 if (!pAdapter) {
20644 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
20645 return -EINVAL;
20646 }
20647
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020648 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20649 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
20650 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020651 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020652 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070020654 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020655 return -EINVAL;
20656 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020657
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020658 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020659 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020660 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020661 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020662 }
20663
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020664
20665 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020666 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020667 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020669 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
20670 "Cannot process TDLS commands",
20671 pHddCtx->cfg_ini->fEnableTDLSSupport,
20672 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020673 return -ENOTSUPP;
20674 }
20675
20676 switch (oper) {
20677 case NL80211_TDLS_ENABLE_LINK:
20678 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020679 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020680 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053020681 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
20682 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053020683 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020684 tANI_U16 numCurrTdlsPeers = 0;
20685 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020686 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020687 tSirMacAddr peerMac;
20688 int channel;
20689 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020690
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20692 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
20693 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020694
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020695 mutex_lock(&pHddCtx->tdls_lock);
20696 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020697 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053020698 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020699 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020700 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20701 " (oper %d) not exsting. ignored",
20702 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20703 return -EINVAL;
20704 }
20705
20706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20707 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20708 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20709 "NL80211_TDLS_ENABLE_LINK");
20710
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020711 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
20712 {
20713 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
20714 MAC_ADDRESS_STR " failed",
20715 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020716 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020717 return -EINVAL;
20718 }
20719
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020720 /* before starting tdls connection, set tdls
20721 * off channel established status to default value */
20722 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020723
20724 mutex_unlock(&pHddCtx->tdls_lock);
20725
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053020726 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020727 /* TDLS Off Channel, Disable tdls channel switch,
20728 when there are more than one tdls link */
20729 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053020730 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020731 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020732 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020733 /* get connected peer and send disable tdls off chan */
20734 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020735 if ((connPeer) &&
20736 (connPeer->isOffChannelSupported == TRUE) &&
20737 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020738 {
20739 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20740 "%s: More then one peer connected, Disable "
20741 "TDLS channel switch", __func__);
20742
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020743 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020744 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
20745 channel = connPeer->peerParams.channel;
20746
20747 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020748
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020749 ret = sme_SendTdlsChanSwitchReq(
20750 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020751 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020752 peerMac,
20753 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020754 TDLS_OFF_CHANNEL_BW_OFFSET,
20755 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020756 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020757 hddLog(VOS_TRACE_LEVEL_ERROR,
20758 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020759 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020760 }
20761 else
20762 {
20763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20764 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020765 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020766 "isOffChannelConfigured %d",
20767 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020768 (connPeer ? (connPeer->isOffChannelSupported)
20769 : -1),
20770 (connPeer ? (connPeer->isOffChannelConfigured)
20771 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020772 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020773 }
20774 }
20775
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020776 mutex_lock(&pHddCtx->tdls_lock);
20777 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20778 if ( NULL == pTdlsPeer ) {
20779 mutex_unlock(&pHddCtx->tdls_lock);
20780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20781 "%s: " MAC_ADDRESS_STR
20782 " (oper %d) peer got freed in other context. ignored",
20783 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20784 return -EINVAL;
20785 }
20786 peer_status = pTdlsPeer->link_status;
20787 mutex_unlock(&pHddCtx->tdls_lock);
20788
20789 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020790 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020791 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053020792
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020793 if (0 != wlan_hdd_tdls_get_link_establish_params(
20794 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020795 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020796 return -EINVAL;
20797 }
20798 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020799
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020800 ret = sme_SendTdlsLinkEstablishParams(
20801 WLAN_HDD_GET_HAL_CTX(pAdapter),
20802 pAdapter->sessionId, peer,
20803 &tdlsLinkEstablishParams);
20804 if (ret != VOS_STATUS_SUCCESS) {
20805 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
20806 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020807 /* Send TDLS peer UAPSD capabilities to the firmware and
20808 * register with the TL on after the response for this operation
20809 * is received .
20810 */
20811 ret = wait_for_completion_interruptible_timeout(
20812 &pAdapter->tdls_link_establish_req_comp,
20813 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053020814
20815 mutex_lock(&pHddCtx->tdls_lock);
20816 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20817 if ( NULL == pTdlsPeer ) {
20818 mutex_unlock(&pHddCtx->tdls_lock);
20819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20820 "%s %d: " MAC_ADDRESS_STR
20821 " (oper %d) peer got freed in other context. ignored",
20822 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
20823 (int)oper);
20824 return -EINVAL;
20825 }
20826 peer_status = pTdlsPeer->link_status;
20827 mutex_unlock(&pHddCtx->tdls_lock);
20828
20829 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020830 {
20831 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020832 FL("Link Establish Request Failed Status %ld"),
20833 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020834 return -EINVAL;
20835 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020836 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020837
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020838 mutex_lock(&pHddCtx->tdls_lock);
20839 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20840 if ( NULL == pTdlsPeer ) {
20841 mutex_unlock(&pHddCtx->tdls_lock);
20842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20843 "%s: " MAC_ADDRESS_STR
20844 " (oper %d) peer got freed in other context. ignored",
20845 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20846 return -EINVAL;
20847 }
20848
Atul Mittal115287b2014-07-08 13:26:33 +053020849 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20850 eTDLS_LINK_CONNECTED,
20851 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020852 staDesc.ucSTAId = pTdlsPeer->staId;
20853 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053020854
20855 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20856 "%s: tdlsLinkEstablishParams of peer "
20857 MAC_ADDRESS_STR "uapsdQueues: %d"
20858 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
20859 "isResponder: %d peerstaId: %d",
20860 __func__,
20861 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
20862 tdlsLinkEstablishParams.uapsdQueues,
20863 tdlsLinkEstablishParams.qos,
20864 tdlsLinkEstablishParams.maxSp,
20865 tdlsLinkEstablishParams.isBufSta,
20866 tdlsLinkEstablishParams.isOffChannelSupported,
20867 tdlsLinkEstablishParams.isResponder,
20868 pTdlsPeer->staId);
20869
20870 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20871 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
20872 __func__,
20873 staDesc.ucSTAId,
20874 staDesc.ucQosEnabled);
20875
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020876 ret = WLANTL_UpdateTdlsSTAClient(
20877 pHddCtx->pvosContext,
20878 &staDesc);
20879 if (ret != VOS_STATUS_SUCCESS) {
20880 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
20881 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053020882
Gopichand Nakkala471708b2013-06-04 20:03:01 +053020883 /* Mark TDLS client Authenticated .*/
20884 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
20885 pTdlsPeer->staId,
20886 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020887 if (VOS_STATUS_SUCCESS == status)
20888 {
Hoonki Lee14621352013-04-16 17:51:19 -070020889 if (pTdlsPeer->is_responder == 0)
20890 {
20891 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020892 tdlsConnInfo_t *tdlsInfo;
20893
20894 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
20895
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020896 if (!vos_timer_is_initialized(
20897 &pTdlsPeer->initiatorWaitTimeoutTimer))
20898 {
20899 /* Initialize initiator wait callback */
20900 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020901 &pTdlsPeer->initiatorWaitTimeoutTimer,
20902 VOS_TIMER_TYPE_SW,
20903 wlan_hdd_tdls_initiator_wait_cb,
20904 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020905 }
Hoonki Lee14621352013-04-16 17:51:19 -070020906 wlan_hdd_tdls_timer_restart(pAdapter,
20907 &pTdlsPeer->initiatorWaitTimeoutTimer,
20908 WAIT_TIME_TDLS_INITIATOR);
20909 /* suspend initiator TX until it receives direct packet from the
20910 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020911 ret = WLANTL_SuspendDataTx(
20912 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20913 &staId, NULL);
20914 if (ret != VOS_STATUS_SUCCESS) {
20915 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20916 }
Hoonki Lee14621352013-04-16 17:51:19 -070020917 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020918
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020919 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020920 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020921 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020922 suppChannelLen =
20923 tdlsLinkEstablishParams.supportedChannelsLen;
20924
20925 if ((suppChannelLen > 0) &&
20926 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20927 {
20928 tANI_U8 suppPeerChannel = 0;
20929 int i = 0;
20930 for (i = 0U; i < suppChannelLen; i++)
20931 {
20932 suppPeerChannel =
20933 tdlsLinkEstablishParams.supportedChannels[i];
20934
20935 pTdlsPeer->isOffChannelSupported = FALSE;
20936 if (suppPeerChannel ==
20937 pTdlsPeer->peerParams.channel)
20938 {
20939 pTdlsPeer->isOffChannelSupported = TRUE;
20940 break;
20941 }
20942 }
20943 }
20944 else
20945 {
20946 pTdlsPeer->isOffChannelSupported = FALSE;
20947 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020948 }
20949 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20950 "%s: TDLS channel switch request for channel "
20951 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020952 "%d isOffChannelSupported %d", __func__,
20953 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020954 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020955 suppChannelLen,
20956 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020957
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020958 /* TDLS Off Channel, Enable tdls channel switch,
20959 when their is only one tdls link and it supports */
20960 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20961 if ((numCurrTdlsPeers == 1) &&
20962 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20963 (TRUE == pTdlsPeer->isOffChannelConfigured))
20964 {
20965 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20966 "%s: Send TDLS channel switch request for channel %d",
20967 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020968
20969 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020970 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20971 channel = pTdlsPeer->peerParams.channel;
20972
20973 mutex_unlock(&pHddCtx->tdls_lock);
20974
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020975 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20976 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020977 peerMac,
20978 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020979 TDLS_OFF_CHANNEL_BW_OFFSET,
20980 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020981 if (ret != VOS_STATUS_SUCCESS) {
20982 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20983 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020984 }
20985 else
20986 {
20987 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20988 "%s: TDLS channel switch request not sent"
20989 " numCurrTdlsPeers %d "
20990 "isOffChannelSupported %d "
20991 "isOffChannelConfigured %d",
20992 __func__, numCurrTdlsPeers,
20993 pTdlsPeer->isOffChannelSupported,
20994 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020995 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020996 }
20997
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020998 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020999 else
21000 mutex_unlock(&pHddCtx->tdls_lock);
21001
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021002 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021003
21004 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021005 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
21006 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021007 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021008 int ac;
21009 uint8 ucAc[4] = { WLANTL_AC_VO,
21010 WLANTL_AC_VI,
21011 WLANTL_AC_BK,
21012 WLANTL_AC_BE };
21013 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
21014 for(ac=0; ac < 4; ac++)
21015 {
21016 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
21017 pTdlsPeer->staId, ucAc[ac],
21018 tlTid[ac], tlTid[ac], 0, 0,
21019 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021020 if (status != VOS_STATUS_SUCCESS) {
21021 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
21022 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021023 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021024 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021025 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021026
Bhargav Shah66896792015-10-01 18:17:37 +053021027 /* stop TCP delack timer if TDLS is enable */
21028 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21029 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053021030 hdd_wlan_tdls_enable_link_event(peer,
21031 pTdlsPeer->isOffChannelSupported,
21032 pTdlsPeer->isOffChannelConfigured,
21033 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021034 }
21035 break;
21036 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080021037 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021038 tANI_U16 numCurrTdlsPeers = 0;
21039 hddTdlsPeer_t *connPeer = NULL;
21040
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021041 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21042 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
21043 __func__, MAC_ADDR_ARRAY(peer));
21044
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021045 mutex_lock(&pHddCtx->tdls_lock);
21046 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021047
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021048
Sunil Dutt41de4e22013-11-14 18:09:02 +053021049 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021050 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021051 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21052 " (oper %d) not exsting. ignored",
21053 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
21054 return -EINVAL;
21055 }
21056
21057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21058 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
21059 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
21060 "NL80211_TDLS_DISABLE_LINK");
21061
Hoonki Lee5305c3a2013-04-29 23:28:59 -070021062 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080021063 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021064 long status;
21065
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053021066 /* set tdls off channel status to false for this peer */
21067 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053021068 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
21069 eTDLS_LINK_TEARING,
21070 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
21071 eTDLS_LINK_UNSPECIFIED:
21072 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021073 mutex_unlock(&pHddCtx->tdls_lock);
21074
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021075 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
21076
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021077 status = sme_DeleteTdlsPeerSta(
21078 WLAN_HDD_GET_HAL_CTX(pAdapter),
21079 pAdapter->sessionId, peer );
21080 if (status != VOS_STATUS_SUCCESS) {
21081 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
21082 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021083
21084 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
21085 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021086
21087 mutex_lock(&pHddCtx->tdls_lock);
21088 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21089 if ( NULL == pTdlsPeer ) {
21090 mutex_unlock(&pHddCtx->tdls_lock);
21091 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21092 " peer was freed in other context",
21093 __func__, MAC_ADDR_ARRAY(peer));
21094 return -EINVAL;
21095 }
21096
Atul Mittal271a7652014-09-12 13:18:22 +053021097 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053021098 eTDLS_LINK_IDLE,
21099 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021100 mutex_unlock(&pHddCtx->tdls_lock);
21101
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021102 if (status <= 0)
21103 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21105 "%s: Del station failed status %ld",
21106 __func__, status);
21107 return -EPERM;
21108 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021109
21110 /* TDLS Off Channel, Enable tdls channel switch,
21111 when their is only one tdls link and it supports */
21112 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
21113 if (numCurrTdlsPeers == 1)
21114 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021115 tSirMacAddr peerMac;
21116 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021117
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021118 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021119 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021120
21121 if (connPeer == NULL) {
21122 mutex_unlock(&pHddCtx->tdls_lock);
21123 hddLog(VOS_TRACE_LEVEL_ERROR,
21124 "%s connPeer is NULL", __func__);
21125 return -EINVAL;
21126 }
21127
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021128 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
21129 channel = connPeer->peerParams.channel;
21130
21131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21132 "%s: TDLS channel switch "
21133 "isOffChannelSupported %d "
21134 "isOffChannelConfigured %d "
21135 "isOffChannelEstablished %d",
21136 __func__,
21137 (connPeer ? connPeer->isOffChannelSupported : -1),
21138 (connPeer ? connPeer->isOffChannelConfigured : -1),
21139 (connPeer ? connPeer->isOffChannelEstablished : -1));
21140
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021141 if ((connPeer) &&
21142 (connPeer->isOffChannelSupported == TRUE) &&
21143 (connPeer->isOffChannelConfigured == TRUE))
21144 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053021145 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021146 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021147 status = sme_SendTdlsChanSwitchReq(
21148 WLAN_HDD_GET_HAL_CTX(pAdapter),
21149 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021150 peerMac,
21151 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021152 TDLS_OFF_CHANNEL_BW_OFFSET,
21153 TDLS_CHANNEL_SWITCH_ENABLE);
21154 if (status != VOS_STATUS_SUCCESS) {
21155 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
21156 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021157 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021158 else
21159 mutex_unlock(&pHddCtx->tdls_lock);
21160 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021161 else
21162 {
21163 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21164 "%s: TDLS channel switch request not sent "
21165 "numCurrTdlsPeers %d ",
21166 __func__, numCurrTdlsPeers);
21167 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021168 }
21169 else
21170 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021171 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21173 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080021174 }
Bhargav Shah66896792015-10-01 18:17:37 +053021175 if (numCurrTdlsPeers == 0) {
21176 /* start TCP delack timer if TDLS is disable */
21177 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21178 hdd_manage_delack_timer(pHddCtx);
21179 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021180 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021181 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021182 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021183 {
Atul Mittal115287b2014-07-08 13:26:33 +053021184 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021185
Atul Mittal115287b2014-07-08 13:26:33 +053021186 if (0 != status)
21187 {
21188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021189 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053021190 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021191 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053021192 break;
21193 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021194 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021195 {
Atul Mittal115287b2014-07-08 13:26:33 +053021196 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
21197 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021198 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053021199 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021200
Atul Mittal115287b2014-07-08 13:26:33 +053021201 if (0 != status)
21202 {
21203 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021204 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053021205 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053021206 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053021207 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021208 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021209 case NL80211_TDLS_DISCOVERY_REQ:
21210 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021212 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021213 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021214 return -ENOTSUPP;
21215 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21217 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021218 return -ENOTSUPP;
21219 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021220
21221 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021222 return 0;
21223}
Chilam NG571c65a2013-01-19 12:27:36 +053021224
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021225static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021226#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
21227 const u8 *peer,
21228#else
21229 u8 *peer,
21230#endif
21231 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021232{
21233 int ret;
21234
21235 vos_ssr_protect(__func__);
21236 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
21237 vos_ssr_unprotect(__func__);
21238
21239 return ret;
21240}
21241
Chilam NG571c65a2013-01-19 12:27:36 +053021242int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
21243 struct net_device *dev, u8 *peer)
21244{
Arif Hussaina7c8e412013-11-20 11:06:42 -080021245 hddLog(VOS_TRACE_LEVEL_INFO,
21246 "tdls send discover req: "MAC_ADDRESS_STR,
21247 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021248#if TDLS_MGMT_VERSION2
21249 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21250 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21251#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021252#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
21253 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21254 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
21255#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
21256 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21257 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21258#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
21259 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21260 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21261#else
Chilam NG571c65a2013-01-19 12:27:36 +053021262 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21263 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021264#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021265#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053021266}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021267#endif
21268
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021269#ifdef WLAN_FEATURE_GTK_OFFLOAD
21270/*
21271 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
21272 * Callback rountine called upon receiving response for
21273 * get offload info
21274 */
21275void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
21276 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
21277{
21278
21279 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021280 tANI_U8 tempReplayCounter[8];
21281 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021282
21283 ENTER();
21284
21285 if (NULL == pAdapter)
21286 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053021287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021288 "%s: HDD adapter is Null", __func__);
21289 return ;
21290 }
21291
21292 if (NULL == pGtkOffloadGetInfoRsp)
21293 {
21294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21295 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
21296 return ;
21297 }
21298
21299 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
21300 {
21301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21302 "%s: wlan Failed to get replay counter value",
21303 __func__);
21304 return ;
21305 }
21306
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021307 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21308 /* Update replay counter */
21309 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
21310 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21311
21312 {
21313 /* changing from little to big endian since supplicant
21314 * works on big endian format
21315 */
21316 int i;
21317 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21318
21319 for (i = 0; i < 8; i++)
21320 {
21321 tempReplayCounter[7-i] = (tANI_U8)p[i];
21322 }
21323 }
21324
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021325 /* Update replay counter to NL */
21326 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021327 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021328}
21329
21330/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021331 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021332 * This function is used to offload GTK rekeying job to the firmware.
21333 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021334int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021335 struct cfg80211_gtk_rekey_data *data)
21336{
21337 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21338 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21339 hdd_station_ctx_t *pHddStaCtx;
21340 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021341 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021342 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021343 eHalStatus status = eHAL_STATUS_FAILURE;
21344
21345 ENTER();
21346
21347 if (NULL == pAdapter)
21348 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053021349 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021350 "%s: HDD adapter is Null", __func__);
21351 return -ENODEV;
21352 }
21353
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053021354 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21355 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
21356 pAdapter->sessionId, pAdapter->device_mode));
21357
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021358 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021359 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021360 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021361 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021362 }
21363
21364 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21365 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
21366 if (NULL == hHal)
21367 {
21368 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21369 "%s: HAL context is Null!!!", __func__);
21370 return -EAGAIN;
21371 }
21372
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021373 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
21374 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
21375 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
21376 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021377 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021378 {
21379 /* changing from big to little endian since driver
21380 * works on little endian format
21381 */
21382 tANI_U8 *p =
21383 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
21384 int i;
21385
21386 for (i = 0; i < 8; i++)
21387 {
21388 p[7-i] = data->replay_ctr[i];
21389 }
21390 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021391
21392 if (TRUE == pHddCtx->hdd_wlan_suspended)
21393 {
21394 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021395 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
21396 sizeof (tSirGtkOffloadParams));
21397 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021398 pAdapter->sessionId);
21399
21400 if (eHAL_STATUS_SUCCESS != status)
21401 {
21402 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21403 "%s: sme_SetGTKOffload failed, returned %d",
21404 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021405
21406 /* Need to clear any trace of key value in the memory.
21407 * Thus zero out the memory even though it is local
21408 * variable.
21409 */
21410 vos_mem_zero(&hddGtkOffloadReqParams,
21411 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021412 return status;
21413 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21415 "%s: sme_SetGTKOffload successfull", __func__);
21416 }
21417 else
21418 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021419 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21420 "%s: wlan not suspended GTKOffload request is stored",
21421 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021422 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021423
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021424 /* Need to clear any trace of key value in the memory.
21425 * Thus zero out the memory even though it is local
21426 * variable.
21427 */
21428 vos_mem_zero(&hddGtkOffloadReqParams,
21429 sizeof(hddGtkOffloadReqParams));
21430
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021431 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021432 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021433}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021434
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021435int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
21436 struct cfg80211_gtk_rekey_data *data)
21437{
21438 int ret;
21439
21440 vos_ssr_protect(__func__);
21441 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
21442 vos_ssr_unprotect(__func__);
21443
21444 return ret;
21445}
21446#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021447/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021448 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021449 * This function is used to set access control policy
21450 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021451static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21452 struct net_device *dev,
21453 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021454{
21455 int i;
21456 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21457 hdd_hostapd_state_t *pHostapdState;
21458 tsap_Config_t *pConfig;
21459 v_CONTEXT_t pVosContext = NULL;
21460 hdd_context_t *pHddCtx;
21461 int status;
21462
21463 ENTER();
21464
21465 if (NULL == pAdapter)
21466 {
21467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21468 "%s: HDD adapter is Null", __func__);
21469 return -ENODEV;
21470 }
21471
21472 if (NULL == params)
21473 {
21474 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21475 "%s: params is Null", __func__);
21476 return -EINVAL;
21477 }
21478
21479 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21480 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021481 if (0 != status)
21482 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021483 return status;
21484 }
21485
21486 pVosContext = pHddCtx->pvosContext;
21487 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
21488
21489 if (NULL == pHostapdState)
21490 {
21491 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21492 "%s: pHostapdState is Null", __func__);
21493 return -EINVAL;
21494 }
21495
21496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
21497 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021498 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21499 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
21500 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021501
21502 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
21503 {
21504 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
21505
21506 /* default value */
21507 pConfig->num_accept_mac = 0;
21508 pConfig->num_deny_mac = 0;
21509
21510 /**
21511 * access control policy
21512 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
21513 * listed in hostapd.deny file.
21514 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
21515 * listed in hostapd.accept file.
21516 */
21517 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
21518 {
21519 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
21520 }
21521 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
21522 {
21523 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
21524 }
21525 else
21526 {
21527 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21528 "%s:Acl Policy : %d is not supported",
21529 __func__, params->acl_policy);
21530 return -ENOTSUPP;
21531 }
21532
21533 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
21534 {
21535 pConfig->num_accept_mac = params->n_acl_entries;
21536 for (i = 0; i < params->n_acl_entries; i++)
21537 {
21538 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21539 "** Add ACL MAC entry %i in WhiletList :"
21540 MAC_ADDRESS_STR, i,
21541 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21542
21543 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
21544 sizeof(qcmacaddr));
21545 }
21546 }
21547 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
21548 {
21549 pConfig->num_deny_mac = params->n_acl_entries;
21550 for (i = 0; i < params->n_acl_entries; i++)
21551 {
21552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21553 "** Add ACL MAC entry %i in BlackList :"
21554 MAC_ADDRESS_STR, i,
21555 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21556
21557 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
21558 sizeof(qcmacaddr));
21559 }
21560 }
21561
21562 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
21563 {
21564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21565 "%s: SAP Set Mac Acl fail", __func__);
21566 return -EINVAL;
21567 }
21568 }
21569 else
21570 {
21571 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053021572 "%s: Invalid device_mode = %s (%d)",
21573 __func__, hdd_device_modetoString(pAdapter->device_mode),
21574 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021575 return -EINVAL;
21576 }
21577
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021578 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021579 return 0;
21580}
21581
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021582static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21583 struct net_device *dev,
21584 const struct cfg80211_acl_data *params)
21585{
21586 int ret;
21587 vos_ssr_protect(__func__);
21588 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
21589 vos_ssr_unprotect(__func__);
21590
21591 return ret;
21592}
21593
Leo Chang9056f462013-08-01 19:21:11 -070021594#ifdef WLAN_NL80211_TESTMODE
21595#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070021596void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070021597(
21598 void *pAdapter,
21599 void *indCont
21600)
21601{
Leo Changd9df8aa2013-09-26 13:32:26 -070021602 tSirLPHBInd *lphbInd;
21603 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053021604 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070021605
21606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021607 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070021608
c_hpothu73f35e62014-04-18 13:40:08 +053021609 if (pAdapter == NULL)
21610 {
21611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21612 "%s: pAdapter is NULL\n",__func__);
21613 return;
21614 }
21615
Leo Chang9056f462013-08-01 19:21:11 -070021616 if (NULL == indCont)
21617 {
21618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021619 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070021620 return;
21621 }
21622
c_hpothu73f35e62014-04-18 13:40:08 +053021623 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070021624 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070021625 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053021626 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070021627 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070021628 GFP_ATOMIC);
21629 if (!skb)
21630 {
21631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21632 "LPHB timeout, NL buffer alloc fail");
21633 return;
21634 }
21635
Leo Changac3ba772013-10-07 09:47:04 -070021636 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070021637 {
21638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21639 "WLAN_HDD_TM_ATTR_CMD put fail");
21640 goto nla_put_failure;
21641 }
Leo Changac3ba772013-10-07 09:47:04 -070021642 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070021643 {
21644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21645 "WLAN_HDD_TM_ATTR_TYPE put fail");
21646 goto nla_put_failure;
21647 }
Leo Changac3ba772013-10-07 09:47:04 -070021648 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070021649 sizeof(tSirLPHBInd), lphbInd))
21650 {
21651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21652 "WLAN_HDD_TM_ATTR_DATA put fail");
21653 goto nla_put_failure;
21654 }
Leo Chang9056f462013-08-01 19:21:11 -070021655 cfg80211_testmode_event(skb, GFP_ATOMIC);
21656 return;
21657
21658nla_put_failure:
21659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21660 "NLA Put fail");
21661 kfree_skb(skb);
21662
21663 return;
21664}
21665#endif /* FEATURE_WLAN_LPHB */
21666
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021667static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070021668{
21669 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
21670 int err = 0;
21671#ifdef FEATURE_WLAN_LPHB
21672 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070021673 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021674
21675 ENTER();
21676
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021677 err = wlan_hdd_validate_context(pHddCtx);
21678 if (0 != err)
21679 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021680 return err;
21681 }
Leo Chang9056f462013-08-01 19:21:11 -070021682#endif /* FEATURE_WLAN_LPHB */
21683
21684 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
21685 if (err)
21686 {
21687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21688 "%s Testmode INV ATTR", __func__);
21689 return err;
21690 }
21691
21692 if (!tb[WLAN_HDD_TM_ATTR_CMD])
21693 {
21694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21695 "%s Testmode INV CMD", __func__);
21696 return -EINVAL;
21697 }
21698
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021699 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21700 TRACE_CODE_HDD_CFG80211_TESTMODE,
21701 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070021702 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
21703 {
21704#ifdef FEATURE_WLAN_LPHB
21705 /* Low Power Heartbeat configuration request */
21706 case WLAN_HDD_TM_CMD_WLAN_HB:
21707 {
21708 int buf_len;
21709 void *buf;
21710 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080021711 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070021712
21713 if (!tb[WLAN_HDD_TM_ATTR_DATA])
21714 {
21715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21716 "%s Testmode INV DATA", __func__);
21717 return -EINVAL;
21718 }
21719
21720 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
21721 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080021722
Manjeet Singh3c577442017-02-10 19:03:38 +053021723 if (buf_len > sizeof(*hb_params)) {
21724 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
21725 buf_len);
21726 return -ERANGE;
21727 }
21728
Amar Singhal05852702014-02-04 14:40:00 -080021729 hb_params_temp =(tSirLPHBReq *)buf;
21730 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
21731 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
21732 return -EINVAL;
21733
Leo Chang9056f462013-08-01 19:21:11 -070021734 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
21735 if (NULL == hb_params)
21736 {
21737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21738 "%s Request Buffer Alloc Fail", __func__);
21739 return -EINVAL;
21740 }
21741
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053021742 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070021743 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070021744 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
21745 hb_params,
21746 wlan_hdd_cfg80211_lphb_ind_handler);
21747 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070021748 {
Leo Changd9df8aa2013-09-26 13:32:26 -070021749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21750 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070021751 vos_mem_free(hb_params);
21752 }
Leo Chang9056f462013-08-01 19:21:11 -070021753 return 0;
21754 }
21755#endif /* FEATURE_WLAN_LPHB */
21756 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21758 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070021759 return -EOPNOTSUPP;
21760 }
21761
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021762 EXIT();
21763 return err;
Leo Chang9056f462013-08-01 19:21:11 -070021764}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021765
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053021766static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
21767#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
21768 struct wireless_dev *wdev,
21769#endif
21770 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021771{
21772 int ret;
21773
21774 vos_ssr_protect(__func__);
21775 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
21776 vos_ssr_unprotect(__func__);
21777
21778 return ret;
21779}
Leo Chang9056f462013-08-01 19:21:11 -070021780#endif /* CONFIG_NL80211_TESTMODE */
21781
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021782extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021783static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021784 struct net_device *dev,
21785 int idx, struct survey_info *survey)
21786{
21787 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21788 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053021789 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021790 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053021791 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021792 v_S7_t snr,rssi;
21793 int status, i, j, filled = 0;
21794
21795 ENTER();
21796
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021797 if (NULL == pAdapter)
21798 {
21799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21800 "%s: HDD adapter is Null", __func__);
21801 return -ENODEV;
21802 }
21803
21804 if (NULL == wiphy)
21805 {
21806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21807 "%s: wiphy is Null", __func__);
21808 return -ENODEV;
21809 }
21810
21811 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21812 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021813 if (0 != status)
21814 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021815 return status;
21816 }
21817
Mihir Sheted9072e02013-08-21 17:02:29 +053021818 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21819
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021820 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053021821 0 != pAdapter->survey_idx ||
21822 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021823 {
21824 /* The survey dump ops when implemented completely is expected to
21825 * return a survey of all channels and the ops is called by the
21826 * kernel with incremental values of the argument 'idx' till it
21827 * returns -ENONET. But we can only support the survey for the
21828 * operating channel for now. survey_idx is used to track
21829 * that the ops is called only once and then return -ENONET for
21830 * the next iteration
21831 */
21832 pAdapter->survey_idx = 0;
21833 return -ENONET;
21834 }
21835
Mukul Sharma9d5233b2015-06-11 20:28:20 +053021836 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
21837 {
21838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21839 "%s: Roaming in progress, hence return ", __func__);
21840 return -ENONET;
21841 }
21842
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021843 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
21844
21845 wlan_hdd_get_snr(pAdapter, &snr);
21846 wlan_hdd_get_rssi(pAdapter, &rssi);
21847
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021848 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21849 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
21850 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021851 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
21852 hdd_wlan_get_freq(channel, &freq);
21853
21854
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053021855 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021856 {
21857 if (NULL == wiphy->bands[i])
21858 {
21859 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
21860 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
21861 continue;
21862 }
21863
21864 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
21865 {
21866 struct ieee80211_supported_band *band = wiphy->bands[i];
21867
21868 if (band->channels[j].center_freq == (v_U16_t)freq)
21869 {
21870 survey->channel = &band->channels[j];
21871 /* The Rx BDs contain SNR values in dB for the received frames
21872 * while the supplicant expects noise. So we calculate and
21873 * return the value of noise (dBm)
21874 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
21875 */
21876 survey->noise = rssi - snr;
21877 survey->filled = SURVEY_INFO_NOISE_DBM;
21878 filled = 1;
21879 }
21880 }
21881 }
21882
21883 if (filled)
21884 pAdapter->survey_idx = 1;
21885 else
21886 {
21887 pAdapter->survey_idx = 0;
21888 return -ENONET;
21889 }
21890
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021891 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021892 return 0;
21893}
21894
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021895static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
21896 struct net_device *dev,
21897 int idx, struct survey_info *survey)
21898{
21899 int ret;
21900
21901 vos_ssr_protect(__func__);
21902 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
21903 vos_ssr_unprotect(__func__);
21904
21905 return ret;
21906}
21907
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021908/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021909 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021910 * this is called when cfg80211 driver resume
21911 * driver updates latest sched_scan scan result(if any) to cfg80211 database
21912 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021913int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021914{
21915 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21916 hdd_adapter_t *pAdapter;
21917 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21918 VOS_STATUS status = VOS_STATUS_SUCCESS;
21919
21920 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021921
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021922 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021923 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021924 return 0;
21925 }
21926
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021927 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21928 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021929
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021930 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021931 {
21932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21933 "%s: Resume SoftAP", __func__);
21934 hdd_set_wlan_suspend_mode(false);
21935 }
21936
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021937 spin_lock(&pHddCtx->schedScan_lock);
21938 pHddCtx->isWiphySuspended = FALSE;
21939 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21940 {
21941 spin_unlock(&pHddCtx->schedScan_lock);
21942 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21943 "%s: Return resume is not due to PNO indication", __func__);
21944 return 0;
21945 }
21946 // Reset flag to avoid updatating cfg80211 data old results again
21947 pHddCtx->isSchedScanUpdatePending = FALSE;
21948 spin_unlock(&pHddCtx->schedScan_lock);
21949
21950 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21951
21952 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21953 {
21954 pAdapter = pAdapterNode->pAdapter;
21955 if ( (NULL != pAdapter) &&
21956 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21957 {
21958 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021959 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21961 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021962 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021963 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021964 {
21965 /* Acquire wakelock to handle the case where APP's tries to
21966 * suspend immediately after updating the scan results. Whis
21967 * results in app's is in suspended state and not able to
21968 * process the connect request to AP
21969 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021970 hdd_prevent_suspend_timeout(2000,
21971 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021972 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021973 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021974
21975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21976 "%s : cfg80211 scan result database updated", __func__);
21977
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021978 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021979 return 0;
21980
21981 }
21982 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21983 pAdapterNode = pNext;
21984 }
21985
21986 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21987 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021988 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021989 return 0;
21990}
21991
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021992int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21993{
21994 int ret;
21995
21996 vos_ssr_protect(__func__);
21997 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
21998 vos_ssr_unprotect(__func__);
21999
22000 return ret;
22001}
22002
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022003/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022004 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022005 * this is called when cfg80211 driver suspends
22006 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022007int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022008 struct cfg80211_wowlan *wow)
22009{
22010 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022011 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022012
22013 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022014
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022015 ret = wlan_hdd_validate_context(pHddCtx);
22016 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022017 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022018 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022019 }
22020
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053022021 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053022022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22023 "%s: Suspend SoftAP", __func__);
22024 hdd_set_wlan_suspend_mode(true);
22025 }
22026
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022027
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022028 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
22029 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
22030 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022031 pHddCtx->isWiphySuspended = TRUE;
22032
22033 EXIT();
22034
22035 return 0;
22036}
22037
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022038int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
22039 struct cfg80211_wowlan *wow)
22040{
22041 int ret;
22042
22043 vos_ssr_protect(__func__);
22044 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
22045 vos_ssr_unprotect(__func__);
22046
22047 return ret;
22048}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022049
22050#ifdef FEATURE_OEM_DATA_SUPPORT
22051static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022052 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022053{
22054 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22055
22056 ENTER();
22057
22058 if (wlan_hdd_validate_context(pHddCtx)) {
22059 return;
22060 }
22061 if (!pMsg)
22062 {
22063 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
22064 return;
22065 }
22066
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022067 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022068
22069 EXIT();
22070 return;
22071
22072}
22073
22074void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022075 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022076{
22077 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22078
22079 ENTER();
22080
22081 if (wlan_hdd_validate_context(pHddCtx)) {
22082 return;
22083 }
22084
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022085 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022086
22087 switch(evType) {
22088 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022089 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022090 break;
22091 default:
22092 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
22093 break;
22094 }
22095 EXIT();
22096}
22097#endif
22098
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022099#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22100 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022101/**
22102 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
22103 * @wiphy: Pointer to wiphy
22104 * @wdev: Pointer to wireless device structure
22105 *
22106 * This function is used to abort an ongoing scan
22107 *
22108 * Return: None
22109 */
22110static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22111 struct wireless_dev *wdev)
22112{
22113 struct net_device *dev = wdev->netdev;
22114 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22115 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
22116 int ret;
22117
22118 ENTER();
22119
22120 if (NULL == adapter) {
22121 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
22122 return;
22123 }
22124
22125 ret = wlan_hdd_validate_context(hdd_ctx);
22126 if (0 != ret)
22127 return;
22128
22129 wlan_hdd_scan_abort(adapter);
22130
22131 return;
22132}
22133
22134/**
22135 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
22136 * @wiphy: Pointer to wiphy
22137 * @wdev: Pointer to wireless device structure
22138 *
22139 * Return: None
22140 */
22141void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22142 struct wireless_dev *wdev)
22143{
22144 vos_ssr_protect(__func__);
22145 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
22146 vos_ssr_unprotect(__func__);
22147
22148 return;
22149}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022150#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022151
Abhishek Singh936c6932017-11-07 17:28:23 +053022152#ifdef CHANNEL_SWITCH_SUPPORTED
22153/**
22154 * __wlan_hdd_cfg80211_channel_switch()- function to switch
22155 * channel in SAP/GO
22156 * @wiphy: wiphy pointer
22157 * @dev: dev pointer.
22158 * @csa_params: Change channel params
22159 *
22160 * This function is called to switch channel in SAP/GO
22161 *
22162 * Return: 0 if success else return non zero
22163 */
22164static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22165 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22166{
22167 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22168 hdd_context_t *hdd_ctx;
22169 uint8_t channel;
22170 int ret;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022171 ptSapContext sap_ctx;
Abhishek Singh936c6932017-11-07 17:28:23 +053022172 v_CONTEXT_t vos_ctx;
22173
22174 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
22175
22176 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
22177 ret = wlan_hdd_validate_context(hdd_ctx);
22178 if (ret)
22179 return ret;
22180
22181 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
22182 if (!vos_ctx) {
22183 hddLog(LOGE, FL("Vos ctx is null"));
22184 return -EINVAL;
22185 }
22186
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022187 if (WLAN_HDD_SOFTAP != adapter->device_mode)
Abhishek Singh936c6932017-11-07 17:28:23 +053022188 return -ENOTSUPP;
22189
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022190 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
22191 if (!sap_ctx) {
22192 hddLog(LOGE, FL("sap_ctx is NULL"));
22193 return -EINVAL;
22194 }
22195
22196 ret = wlansap_chk_n_set_chan_change_in_progress(sap_ctx);
22197 if (ret)
22198 return ret;
22199
22200 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
22201
Abhishek Singh936c6932017-11-07 17:28:23 +053022202 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053022203 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053022204
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022205 if (ret) {
22206 wlansap_reset_chan_change_in_progress(sap_ctx);
22207 complete(&sap_ctx->ecsa_info.chan_switch_comp);
22208 }
22209
Abhishek Singh936c6932017-11-07 17:28:23 +053022210 return ret;
22211}
22212
22213/**
22214 * wlan_hdd_cfg80211_channel_switch()- function to switch
22215 * channel in SAP/GO
22216 * @wiphy: wiphy pointer
22217 * @dev: dev pointer.
22218 * @csa_params: Change channel params
22219 *
22220 * This function is called to switch channel in SAP/GO
22221 *
22222 * Return: 0 if success else return non zero
22223 */
22224static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22225 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22226{
22227 int ret;
22228
22229 vos_ssr_protect(__func__);
22230 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
22231 vos_ssr_unprotect(__func__);
22232
22233 return ret;
22234}
22235#endif
22236
Jeff Johnson295189b2012-06-20 16:38:30 -070022237/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053022238static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070022239{
22240 .add_virtual_intf = wlan_hdd_add_virtual_intf,
22241 .del_virtual_intf = wlan_hdd_del_virtual_intf,
22242 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
22243 .change_station = wlan_hdd_change_station,
22244#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
22245 .add_beacon = wlan_hdd_cfg80211_add_beacon,
22246 .del_beacon = wlan_hdd_cfg80211_del_beacon,
22247 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022248#else
22249 .start_ap = wlan_hdd_cfg80211_start_ap,
22250 .change_beacon = wlan_hdd_cfg80211_change_beacon,
22251 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070022252#endif
22253 .change_bss = wlan_hdd_cfg80211_change_bss,
22254 .add_key = wlan_hdd_cfg80211_add_key,
22255 .get_key = wlan_hdd_cfg80211_get_key,
22256 .del_key = wlan_hdd_cfg80211_del_key,
22257 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022258#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070022259 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022260#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022261 .scan = wlan_hdd_cfg80211_scan,
22262 .connect = wlan_hdd_cfg80211_connect,
22263 .disconnect = wlan_hdd_cfg80211_disconnect,
22264 .join_ibss = wlan_hdd_cfg80211_join_ibss,
22265 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
22266 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
22267 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
22268 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070022269 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
22270 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053022271 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070022272#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
22273 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
22274 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
22275 .set_txq_params = wlan_hdd_set_txq_params,
22276#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022277 .get_station = wlan_hdd_cfg80211_get_station,
22278 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
22279 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022280 .add_station = wlan_hdd_cfg80211_add_station,
22281#ifdef FEATURE_WLAN_LFR
22282 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
22283 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
22284 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
22285#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070022286#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
22287 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
22288#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080022289#ifdef FEATURE_WLAN_TDLS
22290 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
22291 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
22292#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053022293#ifdef WLAN_FEATURE_GTK_OFFLOAD
22294 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
22295#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053022296#ifdef FEATURE_WLAN_SCAN_PNO
22297 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
22298 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
22299#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022300 .resume = wlan_hdd_cfg80211_resume_wlan,
22301 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053022302 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070022303#ifdef WLAN_NL80211_TESTMODE
22304 .testmode_cmd = wlan_hdd_cfg80211_testmode,
22305#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022306 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022307#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22308 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022309 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022310#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053022311#ifdef CHANNEL_SWITCH_SUPPORTED
22312 .channel_switch = wlan_hdd_cfg80211_channel_switch,
22313#endif
22314
Jeff Johnson295189b2012-06-20 16:38:30 -070022315};
22316