blob: 8f8de3799f0c96f02f82bb232b0ae134de926cf8 [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 = {
464 .flags = WIPHY_WOWLAN_MAGIC_PKT,
465 .n_patterns = WOWL_MAX_PTRNS_ALLOWED,
466 .pattern_min_len = 1,
467 .pattern_max_len = WOWL_PTRN_MAX_SIZE,
468};
469#endif
470
Jeff Johnson295189b2012-06-20 16:38:30 -0700471static struct cfg80211_ops wlan_hdd_cfg80211_ops;
472
473/* Data rate 100KBPS based on IE Index */
474struct index_data_rate_type
475{
476 v_U8_t beacon_rate_index;
477 v_U16_t supported_rate[4];
478};
479
480/* 11B, 11G Rate table include Basic rate and Extended rate
481 The IDX field is the rate index
482 The HI field is the rate when RSSI is strong or being ignored
483 (in this case we report actual rate)
484 The MID field is the rate when RSSI is moderate
485 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
486 The LO field is the rate when RSSI is low
487 (in this case we don't report rates, actual current rate used)
488 */
489static const struct
490{
491 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700492 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700493} supported_data_rate[] =
494{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700495/* IDX HI HM LM LO (RSSI-based index */
496 {2, { 10, 10, 10, 0}},
497 {4, { 20, 20, 10, 0}},
498 {11, { 55, 20, 10, 0}},
499 {12, { 60, 55, 20, 0}},
500 {18, { 90, 55, 20, 0}},
501 {22, {110, 55, 20, 0}},
502 {24, {120, 90, 60, 0}},
503 {36, {180, 120, 60, 0}},
504 {44, {220, 180, 60, 0}},
505 {48, {240, 180, 90, 0}},
506 {66, {330, 180, 90, 0}},
507 {72, {360, 240, 90, 0}},
508 {96, {480, 240, 120, 0}},
509 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700510};
511
512/* MCS Based rate table */
513static struct index_data_rate_type supported_mcs_rate[] =
514{
515/* MCS L20 L40 S20 S40 */
516 {0, {65, 135, 72, 150}},
517 {1, {130, 270, 144, 300}},
518 {2, {195, 405, 217, 450}},
519 {3, {260, 540, 289, 600}},
520 {4, {390, 810, 433, 900}},
521 {5, {520, 1080, 578, 1200}},
522 {6, {585, 1215, 650, 1350}},
523 {7, {650, 1350, 722, 1500}}
524};
525
Leo Chang6f8870f2013-03-26 18:11:36 -0700526#ifdef WLAN_FEATURE_11AC
527
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530528#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700529
530struct index_vht_data_rate_type
531{
532 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530533 v_U16_t supported_VHT80_rate[2];
534 v_U16_t supported_VHT40_rate[2];
535 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700536};
537
538typedef enum
539{
540 DATA_RATE_11AC_MAX_MCS_7,
541 DATA_RATE_11AC_MAX_MCS_8,
542 DATA_RATE_11AC_MAX_MCS_9,
543 DATA_RATE_11AC_MAX_MCS_NA
544} eDataRate11ACMaxMcs;
545
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530546/* SSID broadcast type */
547typedef enum eSSIDBcastType
548{
549 eBCAST_UNKNOWN = 0,
550 eBCAST_NORMAL = 1,
551 eBCAST_HIDDEN = 2,
552} tSSIDBcastType;
553
Leo Chang6f8870f2013-03-26 18:11:36 -0700554/* MCS Based VHT rate table */
555static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
556{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530557/* MCS L80 S80 L40 S40 L20 S40*/
558 {0, {293, 325}, {135, 150}, {65, 72}},
559 {1, {585, 650}, {270, 300}, {130, 144}},
560 {2, {878, 975}, {405, 450}, {195, 217}},
561 {3, {1170, 1300}, {540, 600}, {260, 289}},
562 {4, {1755, 1950}, {810, 900}, {390, 433}},
563 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
564 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
565 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
566 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
567 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700568};
569#endif /* WLAN_FEATURE_11AC */
570
c_hpothu79aab322014-07-14 21:11:01 +0530571/*array index points to MCS and array value points respective rssi*/
572static int rssiMcsTbl[][10] =
573{
574/*MCS 0 1 2 3 4 5 6 7 8 9*/
575 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
576 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
577 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
578};
579
Jeff Johnson295189b2012-06-20 16:38:30 -0700580extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530581#ifdef FEATURE_WLAN_SCAN_PNO
582static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
583#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700584
Leo Chang9056f462013-08-01 19:21:11 -0700585#ifdef WLAN_NL80211_TESTMODE
586enum wlan_hdd_tm_attr
587{
588 WLAN_HDD_TM_ATTR_INVALID = 0,
589 WLAN_HDD_TM_ATTR_CMD = 1,
590 WLAN_HDD_TM_ATTR_DATA = 2,
591 WLAN_HDD_TM_ATTR_TYPE = 3,
592 /* keep last */
593 WLAN_HDD_TM_ATTR_AFTER_LAST,
594 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
595};
596
597enum wlan_hdd_tm_cmd
598{
599 WLAN_HDD_TM_CMD_WLAN_HB = 1,
600};
601
602#define WLAN_HDD_TM_DATA_MAX_LEN 5000
603
604static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
605{
606 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
607 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
608 .len = WLAN_HDD_TM_DATA_MAX_LEN },
609};
610#endif /* WLAN_NL80211_TESTMODE */
611
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800612#ifdef FEATURE_WLAN_CH_AVOID
613/*
614 * FUNCTION: wlan_hdd_send_avoid_freq_event
615 * This is called when wlan driver needs to send vendor specific
616 * avoid frequency range event to userspace
617 */
618int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
619 tHddAvoidFreqList *pAvoidFreqList)
620{
621 struct sk_buff *vendor_event;
622
623 ENTER();
624
625 if (!pHddCtx)
626 {
627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
628 "%s: HDD context is null", __func__);
629 return -1;
630 }
631
632 if (!pAvoidFreqList)
633 {
634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
635 "%s: pAvoidFreqList is null", __func__);
636 return -1;
637 }
638
639 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530640#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
641 NULL,
642#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800643 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530644 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800645 GFP_KERNEL);
646 if (!vendor_event)
647 {
648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
649 "%s: cfg80211_vendor_event_alloc failed", __func__);
650 return -1;
651 }
652
653 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
654 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
655
656 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
657
658 EXIT();
659 return 0;
660}
661#endif /* FEATURE_WLAN_CH_AVOID */
662
Srinivas Dasari030bad32015-02-18 23:23:54 +0530663/*
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +0530664 * define short names for the global vendor params
665 * used by QCA_NL80211_VENDOR_SUBCMD_HANG
666 */
667#define HANG_REASON_INDEX QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX
668
669/**
670 * hdd_convert_hang_reason() - Convert cds recovery reason to vendor specific
671 * hang reason
672 * @reason: cds recovery reason
673 *
674 * Return: Vendor specific reason code
675 */
676static enum qca_wlan_vendor_hang_reason
677hdd_convert_hang_reason(enum vos_hang_reason reason)
678{
679 unsigned int ret_val;
680
681 switch (reason) {
682 case VOS_GET_MSG_BUFF_FAILURE:
683 ret_val = QCA_WLAN_HANG_GET_MSG_BUFF_FAILURE;
684 break;
685 case VOS_ACTIVE_LIST_TIMEOUT:
686 ret_val = QCA_WLAN_HANG_ACTIVE_LIST_TIMEOUT;
687 break;
688 case VOS_SCAN_REQ_EXPIRED:
689 ret_val = QCA_WLAN_HANG_SCAN_REQ_EXPIRED;
690 break;
691 case VOS_TRANSMISSIONS_TIMEOUT:
692 ret_val = QCA_WLAN_HANG_TRANSMISSIONS_TIMEOUT;
693 break;
694 case VOS_DXE_FAILURE:
695 ret_val = QCA_WLAN_HANG_DXE_FAILURE;
696 break;
697 case VOS_WDI_FAILURE:
698 ret_val = QCA_WLAN_HANG_WDI_FAILURE;
699 break;
700 case VOS_REASON_UNSPECIFIED:
701 default:
702 ret_val = QCA_WLAN_HANG_REASON_UNSPECIFIED;
703 }
704 return ret_val;
705}
706
707/**
708 * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace
709 * @hdd_ctx: Pointer to hdd context
710 * @reason: cds recovery reason
711 *
712 * Return: 0 on success or failure reason
713 */
714int wlan_hdd_send_hang_reason_event(hdd_context_t *hdd_ctx,
715 enum vos_hang_reason reason)
716{
717 struct sk_buff *vendor_event;
718 enum qca_wlan_vendor_hang_reason hang_reason;
719
720 ENTER();
721
722 if (!hdd_ctx) {
723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
724 "HDD context is null");
725 return -EINVAL;
726 }
727
728 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
729#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
730 NULL,
731#endif
732 sizeof(unsigned int),
733 HANG_REASON_INDEX,
734 GFP_KERNEL);
735 if (!vendor_event) {
736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
737 "cfg80211_vendor_event_alloc failed");
738 return -ENOMEM;
739 }
740
741 hang_reason = hdd_convert_hang_reason(reason);
742
743 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_HANG_REASON,
744 (unsigned int) hang_reason)) {
745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
746 "QCA_WLAN_VENDOR_ATTR_HANG_REASON put fail");
747 kfree_skb(vendor_event);
748 return -EINVAL;
749 }
750
751 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
752
753 EXIT();
754 return 0;
755}
756#undef HANG_REASON_INDEX
757
758/*
Srinivas Dasari030bad32015-02-18 23:23:54 +0530759 * FUNCTION: __wlan_hdd_cfg80211_nan_request
760 * This is called when wlan driver needs to send vendor specific
761 * nan request event.
762 */
763static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
764 struct wireless_dev *wdev,
765 const void *data, int data_len)
766{
767 tNanRequestReq nan_req;
768 VOS_STATUS status;
769 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530770 struct net_device *dev = wdev->netdev;
771 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
772 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530773 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
774
775 if (0 == data_len)
776 {
777 hddLog(VOS_TRACE_LEVEL_ERROR,
778 FL("NAN - Invalid Request, length = 0"));
779 return ret_val;
780 }
781
782 if (NULL == data)
783 {
784 hddLog(VOS_TRACE_LEVEL_ERROR,
785 FL("NAN - Invalid Request, data is NULL"));
786 return ret_val;
787 }
788
789 status = wlan_hdd_validate_context(pHddCtx);
790 if (0 != status)
791 {
792 hddLog(VOS_TRACE_LEVEL_ERROR,
793 FL("HDD context is not valid"));
794 return -EINVAL;
795 }
796
797 hddLog(LOG1, FL("Received NAN command"));
798 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
799 (tANI_U8 *)data, data_len);
800
801 /* check the NAN Capability */
802 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
803 {
804 hddLog(VOS_TRACE_LEVEL_ERROR,
805 FL("NAN is not supported by Firmware"));
806 return -EINVAL;
807 }
808
809 nan_req.request_data_len = data_len;
810 nan_req.request_data = data;
811
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530812 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530813 if (VOS_STATUS_SUCCESS == status)
814 {
815 ret_val = 0;
816 }
817 return ret_val;
818}
819
820/*
821 * FUNCTION: wlan_hdd_cfg80211_nan_request
822 * Wrapper to protect the nan vendor command from ssr
823 */
824static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
825 struct wireless_dev *wdev,
826 const void *data, int data_len)
827{
828 int ret;
829
830 vos_ssr_protect(__func__);
831 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
832 vos_ssr_unprotect(__func__);
833
834 return ret;
835}
836
837/*
838 * FUNCTION: wlan_hdd_cfg80211_nan_callback
839 * This is a callback function and it gets called
840 * when we need to report nan response event to
841 * upper layers.
842 */
843static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
844{
845 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
846 struct sk_buff *vendor_event;
847 int status;
848 tSirNanEvent *data;
849
850 ENTER();
851 if (NULL == msg)
852 {
853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
854 FL(" msg received here is null"));
855 return;
856 }
857 data = msg;
858
859 status = wlan_hdd_validate_context(pHddCtx);
860
861 if (0 != status)
862 {
863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
864 FL("HDD context is not valid"));
865 return;
866 }
867
868 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530869#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
870 NULL,
871#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530872 data->event_data_len +
873 NLMSG_HDRLEN,
874 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
875 GFP_KERNEL);
876
877 if (!vendor_event)
878 {
879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
880 FL("cfg80211_vendor_event_alloc failed"));
881 return;
882 }
883 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
884 data->event_data_len, data->event_data))
885 {
886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
887 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
888 kfree_skb(vendor_event);
889 return;
890 }
891 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
892 EXIT();
893}
894
895/*
896 * FUNCTION: wlan_hdd_cfg80211_nan_init
897 * This function is called to register the callback to sme layer
898 */
899inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
900{
901 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
902}
903
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530904/*
905 * define short names for the global vendor params
906 * used by __wlan_hdd_cfg80211_get_station_cmd()
907 */
908#define STATION_INVALID \
909 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
910#define STATION_INFO \
911 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
912#define STATION_ASSOC_FAIL_REASON \
913 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +0530914#define STATION_REMOTE \
915 QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530916#define STATION_MAX \
917 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
918
919static const struct nla_policy
920hdd_get_station_policy[STATION_MAX + 1] = {
921 [STATION_INFO] = {.type = NLA_FLAG},
922 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
923};
924
925/**
926 * hdd_get_station_assoc_fail() - Handle get station assoc fail
927 * @hdd_ctx: HDD context within host driver
928 * @wdev: wireless device
929 *
930 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
931 * Validate cmd attributes and send the station info to upper layers.
932 *
933 * Return: Success(0) or reason code for failure
934 */
935static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
936 hdd_adapter_t *adapter)
937{
938 struct sk_buff *skb = NULL;
939 uint32_t nl_buf_len;
940 hdd_station_ctx_t *hdd_sta_ctx;
941
942 nl_buf_len = NLMSG_HDRLEN;
943 nl_buf_len += sizeof(uint32_t);
944 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
945
946 if (!skb) {
947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
948 return -ENOMEM;
949 }
950
951 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
952
953 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
954 hdd_sta_ctx->conn_info.assoc_status_code)) {
955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
956 goto fail;
957 }
958 return cfg80211_vendor_cmd_reply(skb);
959fail:
960 if (skb)
961 kfree_skb(skb);
962 return -EINVAL;
963}
964
965/**
966 * hdd_map_auth_type() - transform auth type specific to
967 * vendor command
968 * @auth_type: csr auth type
969 *
970 * Return: Success(0) or reason code for failure
971 */
972static int hdd_convert_auth_type(uint32_t auth_type)
973{
974 uint32_t ret_val;
975
976 switch (auth_type) {
977 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
978 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
979 break;
980 case eCSR_AUTH_TYPE_SHARED_KEY:
981 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
982 break;
983 case eCSR_AUTH_TYPE_WPA:
984 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
985 break;
986 case eCSR_AUTH_TYPE_WPA_PSK:
987 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
988 break;
989 case eCSR_AUTH_TYPE_AUTOSWITCH:
990 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
991 break;
992 case eCSR_AUTH_TYPE_WPA_NONE:
993 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
994 break;
995 case eCSR_AUTH_TYPE_RSN:
996 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
997 break;
998 case eCSR_AUTH_TYPE_RSN_PSK:
999 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
1000 break;
1001 case eCSR_AUTH_TYPE_FT_RSN:
1002 ret_val = QCA_WLAN_AUTH_TYPE_FT;
1003 break;
1004 case eCSR_AUTH_TYPE_FT_RSN_PSK:
1005 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
1006 break;
1007 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
1008 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
1009 break;
1010 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
1011 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
1012 break;
1013#ifdef FEATURE_WLAN_ESE
1014 case eCSR_AUTH_TYPE_CCKM_WPA:
1015 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
1016 break;
1017 case eCSR_AUTH_TYPE_CCKM_RSN:
1018 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
1019 break;
1020#endif
1021 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
1022 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
1023 break;
1024 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
1025 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
1026 break;
1027 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
1028 case eCSR_AUTH_TYPE_FAILED:
1029 case eCSR_AUTH_TYPE_NONE:
1030 default:
1031 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
1032 break;
1033 }
1034 return ret_val;
1035}
1036
1037/**
1038 * hdd_map_dot_11_mode() - transform dot11mode type specific to
1039 * vendor command
1040 * @dot11mode: dot11mode
1041 *
1042 * Return: Success(0) or reason code for failure
1043 */
1044static int hdd_convert_dot11mode(uint32_t dot11mode)
1045{
1046 uint32_t ret_val;
1047
1048 switch (dot11mode) {
1049 case eCSR_CFG_DOT11_MODE_11A:
1050 ret_val = QCA_WLAN_802_11_MODE_11A;
1051 break;
1052 case eCSR_CFG_DOT11_MODE_11B:
1053 ret_val = QCA_WLAN_802_11_MODE_11B;
1054 break;
1055 case eCSR_CFG_DOT11_MODE_11G:
1056 ret_val = QCA_WLAN_802_11_MODE_11G;
1057 break;
1058 case eCSR_CFG_DOT11_MODE_11N:
1059 ret_val = QCA_WLAN_802_11_MODE_11N;
1060 break;
1061 case eCSR_CFG_DOT11_MODE_11AC:
1062 ret_val = QCA_WLAN_802_11_MODE_11AC;
1063 break;
1064 case eCSR_CFG_DOT11_MODE_AUTO:
1065 case eCSR_CFG_DOT11_MODE_ABG:
1066 default:
1067 ret_val = QCA_WLAN_802_11_MODE_INVALID;
1068 }
1069 return ret_val;
1070}
1071
1072/**
1073 * hdd_add_tx_bitrate() - add tx bitrate attribute
1074 * @skb: pointer to sk buff
1075 * @hdd_sta_ctx: pointer to hdd station context
1076 * @idx: attribute index
1077 *
1078 * Return: Success(0) or reason code for failure
1079 */
1080static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
1081 hdd_station_ctx_t *hdd_sta_ctx,
1082 int idx)
1083{
1084 struct nlattr *nla_attr;
1085 uint32_t bitrate, bitrate_compat;
1086
1087 nla_attr = nla_nest_start(skb, idx);
1088 if (!nla_attr)
1089 goto fail;
1090 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301091 bitrate = cfg80211_calculate_bitrate(
1092 &hdd_sta_ctx->cache_conn_info.txrate);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301093
1094 /* report 16-bit bitrate only if we can */
1095 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
1096 if (bitrate > 0 &&
1097 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
1098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1099 goto fail;
1100 }
1101 if (bitrate_compat > 0 &&
1102 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
1103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1104 goto fail;
1105 }
1106 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301107 hdd_sta_ctx->cache_conn_info.txrate.nss)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1109 goto fail;
1110 }
1111 nla_nest_end(skb, nla_attr);
1112 return 0;
1113fail:
1114 return -EINVAL;
1115}
1116
1117/**
1118 * hdd_add_sta_info() - add station info attribute
1119 * @skb: pointer to sk buff
1120 * @hdd_sta_ctx: pointer to hdd station context
1121 * @idx: attribute index
1122 *
1123 * Return: Success(0) or reason code for failure
1124 */
1125static int32_t hdd_add_sta_info(struct sk_buff *skb,
1126 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1127{
1128 struct nlattr *nla_attr;
1129
1130 nla_attr = nla_nest_start(skb, idx);
1131 if (!nla_attr)
1132 goto fail;
1133 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301134 (hdd_sta_ctx->cache_conn_info.signal + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1136 goto fail;
1137 }
1138 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1139 goto fail;
1140 nla_nest_end(skb, nla_attr);
1141 return 0;
1142fail:
1143 return -EINVAL;
1144}
1145
1146/**
1147 * hdd_add_survey_info() - add survey info attribute
1148 * @skb: pointer to sk buff
1149 * @hdd_sta_ctx: pointer to hdd station context
1150 * @idx: attribute index
1151 *
1152 * Return: Success(0) or reason code for failure
1153 */
1154static int32_t hdd_add_survey_info(struct sk_buff *skb,
1155 hdd_station_ctx_t *hdd_sta_ctx,
1156 int idx)
1157{
1158 struct nlattr *nla_attr;
1159
1160 nla_attr = nla_nest_start(skb, idx);
1161 if (!nla_attr)
1162 goto fail;
1163 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301164 hdd_sta_ctx->cache_conn_info.freq) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301165 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301166 (hdd_sta_ctx->cache_conn_info.noise + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301167 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1168 goto fail;
1169 }
1170 nla_nest_end(skb, nla_attr);
1171 return 0;
1172fail:
1173 return -EINVAL;
1174}
1175
1176/**
1177 * hdd_add_link_standard_info() - add link info attribute
1178 * @skb: pointer to sk buff
1179 * @hdd_sta_ctx: pointer to hdd station context
1180 * @idx: attribute index
1181 *
1182 * Return: Success(0) or reason code for failure
1183 */
1184static int32_t
1185hdd_add_link_standard_info(struct sk_buff *skb,
1186 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1187{
1188 struct nlattr *nla_attr;
1189
1190 nla_attr = nla_nest_start(skb, idx);
1191 if (!nla_attr)
1192 goto fail;
1193 if (nla_put(skb,
1194 NL80211_ATTR_SSID,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301195 hdd_sta_ctx->cache_conn_info.SSID.SSID.length,
1196 hdd_sta_ctx->cache_conn_info.SSID.SSID.ssId)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1198 goto fail;
1199 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301200 if (nla_put(skb, NL80211_ATTR_MAC, VOS_MAC_ADDR_SIZE,
1201 hdd_sta_ctx->cache_conn_info.bssId))
1202 goto fail;
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301203 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1204 goto fail;
1205 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1206 goto fail;
1207 nla_nest_end(skb, nla_attr);
1208 return 0;
1209fail:
1210 return -EINVAL;
1211}
1212
1213/**
1214 * hdd_add_ap_standard_info() - add ap info attribute
1215 * @skb: pointer to sk buff
1216 * @hdd_sta_ctx: pointer to hdd station context
1217 * @idx: attribute index
1218 *
1219 * Return: Success(0) or reason code for failure
1220 */
1221static int32_t
1222hdd_add_ap_standard_info(struct sk_buff *skb,
1223 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1224{
1225 struct nlattr *nla_attr;
1226
1227 nla_attr = nla_nest_start(skb, idx);
1228 if (!nla_attr)
1229 goto fail;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301230 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301231 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301232 sizeof(hdd_sta_ctx->cache_conn_info.vht_caps),
1233 &hdd_sta_ctx->cache_conn_info.vht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301234 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1235 goto fail;
1236 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301237 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301238 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301239 sizeof(hdd_sta_ctx->cache_conn_info.ht_caps),
1240 &hdd_sta_ctx->cache_conn_info.ht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301241 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1242 goto fail;
1243 }
1244 nla_nest_end(skb, nla_attr);
1245 return 0;
1246fail:
1247 return -EINVAL;
1248}
1249
1250/**
1251 * hdd_get_station_info() - send BSS information to supplicant
1252 * @hdd_ctx: pointer to hdd context
1253 * @adapter: pointer to adapter
1254 *
1255 * Return: 0 if success else error status
1256 */
1257static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1258 hdd_adapter_t *adapter)
1259{
1260 struct sk_buff *skb = NULL;
1261 uint8_t *tmp_hs20 = NULL;
1262 uint32_t nl_buf_len;
1263 hdd_station_ctx_t *hdd_sta_ctx;
1264
1265 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1266
1267 nl_buf_len = NLMSG_HDRLEN;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301268
1269 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.SSID.SSID.length) +
1270 VOS_MAC_ADDR_SIZE +
1271 sizeof(hdd_sta_ctx->cache_conn_info.freq) +
1272 sizeof(hdd_sta_ctx->cache_conn_info.noise) +
1273 sizeof(hdd_sta_ctx->cache_conn_info.signal) +
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301274 (sizeof(uint32_t) * 2) +
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301275 sizeof(hdd_sta_ctx->cache_conn_info.txrate.nss) +
1276 sizeof(hdd_sta_ctx->cache_conn_info.roam_count) +
1277 sizeof(hdd_sta_ctx->cache_conn_info.authType) +
1278 sizeof(hdd_sta_ctx->cache_conn_info.dot11Mode);
1279 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
1280 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.vht_caps);
1281 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
1282 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_caps);
1283 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) {
1284 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->
1285 cache_conn_info.hs20vendor_ie);
1286 nl_buf_len +=
1287 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie) -
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301288 1);
1289 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301290 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
1291 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_operation);
1292 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
1293 nl_buf_len +=
1294 sizeof(hdd_sta_ctx->cache_conn_info.vht_operation);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301295
1296
1297 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1298 if (!skb) {
1299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1300 __func__, __LINE__);
1301 return -ENOMEM;
1302 }
1303
1304 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1305 LINK_INFO_STANDARD_NL80211_ATTR)) {
1306 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1307 goto fail;
1308 }
1309 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1310 AP_INFO_STANDARD_NL80211_ATTR)) {
1311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1312 goto fail;
1313 }
1314 if (nla_put_u32(skb, INFO_ROAM_COUNT,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301315 hdd_sta_ctx->cache_conn_info.roam_count) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301316 nla_put_u32(skb, INFO_AKM,
1317 hdd_convert_auth_type(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301318 hdd_sta_ctx->cache_conn_info.authType)) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301319 nla_put_u32(skb, WLAN802_11_MODE,
1320 hdd_convert_dot11mode(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301321 hdd_sta_ctx->cache_conn_info.dot11Mode))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1323 goto fail;
1324 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301325 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301326 if (nla_put(skb, HT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301327 (sizeof(hdd_sta_ctx->cache_conn_info.ht_operation)),
1328 &hdd_sta_ctx->cache_conn_info.ht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1330 goto fail;
1331 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301332 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301333 if (nla_put(skb, VHT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301334 (sizeof(hdd_sta_ctx->
1335 cache_conn_info.vht_operation)),
1336 &hdd_sta_ctx->cache_conn_info.vht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1338 goto fail;
1339 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301340 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301341 if (nla_put(skb, AP_INFO_HS20_INDICATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301342 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie)
1343 - 1), tmp_hs20 + 1)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1345 goto fail;
1346 }
1347
1348 return cfg80211_vendor_cmd_reply(skb);
1349fail:
1350 if (skb)
1351 kfree_skb(skb);
1352 return -EINVAL;
1353}
1354
1355/**
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301356 * hdd_add_survey_info_sap_get_len - get data length used in
1357 * hdd_add_survey_info_sap()
1358 *
1359 * This function calculates the data length used in hdd_add_survey_info_sap()
1360 *
1361 * Return: total data length used in hdd_add_survey_info_sap()
1362 */
1363static uint32_t hdd_add_survey_info_sap_get_len(void)
1364{
1365 return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
1366}
1367
1368/**
1369 * hdd_add_survey_info - add survey info attribute
1370 * @skb: pointer to response skb buffer
1371 * @stainfo: station information
1372 * @idx: attribute type index for nla_next_start()
1373 *
1374 * This function adds survey info attribute to response skb buffer
1375 *
1376 * Return : 0 on success and errno on failure
1377 */
1378static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
1379 struct hdd_cache_sta_info *stainfo,
1380 int idx)
1381{
1382 struct nlattr *nla_attr;
1383
1384 nla_attr = nla_nest_start(skb, idx);
1385 if (!nla_attr)
1386 goto fail;
1387 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1388 stainfo->freq)) {
1389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1390 FL("put fail"));
1391 goto fail;
1392 }
1393 nla_nest_end(skb, nla_attr);
1394 return 0;
1395fail:
1396 return -EINVAL;
1397}
1398
1399/**
1400 * hdd_add_tx_bitrate_sap_get_len - get data length used in
1401 * hdd_add_tx_bitrate_sap()
1402 *
1403 * This function calculates the data length used in hdd_add_tx_bitrate_sap()
1404 *
1405 * Return: total data length used in hdd_add_tx_bitrate_sap()
1406 */
1407static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
1408{
1409 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
1410}
1411
1412/**
1413 * hdd_add_tx_bitrate_sap - add vht nss info attribute
1414 * @skb: pointer to response skb buffer
1415 * @stainfo: station information
1416 * @idx: attribute type index for nla_next_start()
1417 *
1418 * This function adds vht nss attribute to response skb buffer
1419 *
1420 * Return : 0 on success and errno on failure
1421 */
1422static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
1423 struct hdd_cache_sta_info *stainfo,
1424 int idx)
1425{
1426 struct nlattr *nla_attr;
1427
1428 nla_attr = nla_nest_start(skb, idx);
1429 if (!nla_attr)
1430 goto fail;
1431
1432 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1433 stainfo->nss)) {
1434 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1435 FL("put fail"));
1436 goto fail;
1437 }
1438 nla_nest_end(skb, nla_attr);
1439 return 0;
1440fail:
1441 return -EINVAL;
1442}
1443
1444/**
1445 * hdd_add_sta_info_sap_get_len - get data length used in
1446 * hdd_add_sta_info_sap()
1447 *
1448 * This function calculates the data length used in hdd_add_sta_info_sap()
1449 *
1450 * Return: total data length used in hdd_add_sta_info_sap()
1451 */
1452static uint32_t hdd_add_sta_info_sap_get_len(void)
1453{
1454 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
1455 hdd_add_tx_bitrate_sap_get_len());
1456}
1457
1458/**
1459 * hdd_add_sta_info_sap - add sta signal info attribute
1460 * @skb: pointer to response skb buffer
1461 * @rssi: peer rssi value
1462 * @stainfo: station information
1463 * @idx: attribute type index for nla_next_start()
1464 *
1465 * This function adds sta signal attribute to response skb buffer
1466 *
1467 * Return : 0 on success and errno on failure
1468 */
1469static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
1470 struct hdd_cache_sta_info *stainfo, int idx)
1471{
1472 struct nlattr *nla_attr;
1473
1474 nla_attr = nla_nest_start(skb, idx);
1475 if (!nla_attr)
1476 goto fail;
1477
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05301478 /* upperlayer expects positive rssi value */
1479 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, (rssi + 96))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1481 FL("put fail"));
1482 goto fail;
1483 }
1484 if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE)) {
1485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1486 FL("put fail"));
1487 goto fail;
1488 }
1489
1490 nla_nest_end(skb, nla_attr);
1491 return 0;
1492fail:
1493 return -EINVAL;
1494}
1495
1496/**
1497 * hdd_add_link_standard_info_sap_get_len - get data length used in
1498 * hdd_add_link_standard_info_sap()
1499 *
1500 * This function calculates the data length used in
1501 * hdd_add_link_standard_info_sap()
1502 *
1503 * Return: total data length used in hdd_add_link_standard_info_sap()
1504 */
1505static uint32_t hdd_add_link_standard_info_sap_get_len(void)
1506{
1507 return ((NLA_HDRLEN) +
1508 hdd_add_survey_info_sap_get_len() +
1509 hdd_add_sta_info_sap_get_len() +
1510 (sizeof(uint32_t) + NLA_HDRLEN));
1511}
1512
1513/**
1514 * hdd_add_link_standard_info_sap - add add link info attribut
1515 * @skb: pointer to response skb buffer
1516 * @stainfo: station information
1517 * @idx: attribute type index for nla_next_start()
1518 *
1519 * This function adds link info attribut to response skb buffer
1520 *
1521 * Return : 0 on success and errno on failure
1522 */
1523static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
1524 struct hdd_cache_sta_info *stainfo,
1525 int idx)
1526{
1527 struct nlattr *nla_attr;
1528
1529 nla_attr = nla_nest_start(skb, idx);
1530 if (!nla_attr)
1531 goto fail;
1532 if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
1533 goto fail;
1534 if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
1535 goto fail;
1536
1537 if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
1538 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1539 FL("put fail"));
1540 goto fail;
1541 }
1542
1543 nla_nest_end(skb, nla_attr);
1544 return 0;
1545fail:
1546 return -EINVAL;
1547}
1548
1549/**
1550 * hdd_add_ap_standard_info_sap_get_len - get data length used in
1551 * hdd_add_ap_standard_info_sap()
1552 * @stainfo: station information
1553 *
1554 * This function calculates the data length used in
1555 * hdd_add_ap_standard_info_sap()
1556 *
1557 * Return: total data length used in hdd_add_ap_standard_info_sap()
1558 */
1559static uint32_t hdd_add_ap_standard_info_sap_get_len(
1560 struct hdd_cache_sta_info *stainfo)
1561{
1562 uint32_t len;
1563
1564 len = NLA_HDRLEN;
1565 if (stainfo->vht_present)
1566 len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
1567 if (stainfo->ht_present)
1568 len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
1569
1570 return len;
1571}
1572
1573/**
1574 * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
1575 * @skb: pointer to response skb buffer
1576 * @stainfo: station information
1577 * @idx: attribute type index for nla_next_start()
1578 *
1579 * This function adds HT and VHT info attributes to response skb buffer
1580 *
1581 * Return : 0 on success and errno on failure
1582 */
1583static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
1584 struct hdd_cache_sta_info *stainfo,
1585 int idx)
1586{
1587 struct nlattr *nla_attr;
1588
1589 nla_attr = nla_nest_start(skb, idx);
1590 if (!nla_attr)
1591 goto fail;
1592
1593 if (stainfo->vht_present) {
1594 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1595 sizeof(stainfo->vht_caps),
1596 &stainfo->vht_caps)) {
1597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1598 FL("put fail"));
1599 goto fail;
1600 }
1601 }
1602 if (stainfo->ht_present) {
1603 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1604 sizeof(stainfo->ht_caps),
1605 &stainfo->ht_caps)) {
1606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1607 FL("put fail"));
1608 goto fail;
1609 }
1610 }
1611 nla_nest_end(skb, nla_attr);
1612 return 0;
1613fail:
1614 return -EINVAL;
1615}
1616
1617/**
1618 * hdd_decode_ch_width - decode channel band width based
1619 * @ch_width: encoded enum value holding channel band width
1620 *
1621 * This function decodes channel band width from the given encoded enum value.
1622 *
1623 * Returns: decoded channel band width.
1624 */
1625static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
1626{
1627 switch (ch_width) {
1628 case 0:
1629 return 20;
1630 case 1:
1631 return 40;
1632 case 2:
1633 return 80;
1634 default:
1635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1636 "invalid enum: %d", ch_width);
1637 return 20;
1638 }
1639}
1640
1641/**
1642 * hdd_get_cached_station_remote() - get cached(deleted) peer's info
1643 * @hdd_ctx: hdd context
1644 * @adapter: hostapd interface
1645 * @mac_addr: mac address of requested peer
1646 *
1647 * This function collect and indicate the cached(deleted) peer's info
1648 *
1649 * Return: 0 on success, otherwise error value
1650 */
1651static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx,
1652 hdd_adapter_t *adapter,
1653 v_MACADDR_t mac_addr)
1654{
1655 struct hdd_cache_sta_info *stainfo;
1656 struct sk_buff *skb = NULL;
1657 uint32_t nl_buf_len;
1658 uint8_t cw;
1659 ptSapContext sap_ctx;
1660 v_CONTEXT_t vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
1661
1662 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
1663 if(sap_ctx == NULL){
1664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1665 FL("psapCtx is NULL"));
1666 return -ENOENT;
1667 }
1668
1669 stainfo = hdd_get_cache_stainfo(sap_ctx->cache_sta_info,
1670 mac_addr.bytes);
1671 if (!stainfo) {
1672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1673 "peer " MAC_ADDRESS_STR " not found",
1674 MAC_ADDR_ARRAY(mac_addr.bytes));
1675 return -EINVAL;
1676 }
1677 if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE) {
1678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1679 "peer " MAC_ADDRESS_STR " is in connected state",
1680 MAC_ADDR_ARRAY(mac_addr.bytes));
1681 return -EINVAL;
1682 }
1683
1684
1685 nl_buf_len = NLMSG_HDRLEN + hdd_add_link_standard_info_sap_get_len() +
1686 hdd_add_ap_standard_info_sap_get_len(stainfo) +
1687 (sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
1688 (sizeof(cw) + NLA_HDRLEN) +
1689 (sizeof(stainfo->rx_rate) + NLA_HDRLEN);
1690
1691 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1692 if (!skb) {
1693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "cfg80211_vendor_cmd_alloc_reply_skb failed");
1694 return -ENOMEM;
1695 }
1696
1697 if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
1698 LINK_INFO_STANDARD_NL80211_ATTR)) {
1699 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "link standard put fail");
1700 goto fail;
1701 }
1702
1703 if (hdd_add_ap_standard_info_sap(skb, stainfo,
1704 AP_INFO_STANDARD_NL80211_ATTR)) {
1705 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ap standard put fail");
1706 goto fail;
1707 }
1708
1709 /* upper layer expects decoded channel BW */
1710 cw = hdd_decode_ch_width(stainfo->ch_width);
1711 if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE, stainfo->dot11_mode) ||
1712 nla_put_u8(skb, REMOTE_CH_WIDTH, cw)) {
1713 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "remote ch put fail");
1714 goto fail;
1715 }
Hanumanth Reddy Pothula504fe152018-01-02 20:41:03 +05301716 if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, (stainfo->rx_rate * 100))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "rx rate put fail");
1718 goto fail;
1719 }
1720
1721 vos_mem_zero(stainfo, sizeof(*stainfo));
1722
1723 return cfg80211_vendor_cmd_reply(skb);
1724fail:
1725 if (skb)
1726 kfree_skb(skb);
1727
1728 return -EINVAL;
1729}
1730
1731/**
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301732 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1733 * @wiphy: corestack handler
1734 * @wdev: wireless device
1735 * @data: data
1736 * @data_len: data length
1737 *
1738 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1739 * Validate cmd attributes and send the station info to upper layers.
1740 *
1741 * Return: Success(0) or reason code for failure
1742 */
1743static int32_t
1744__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1745 struct wireless_dev *wdev,
1746 const void *data,
1747 int data_len)
1748{
1749 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1750 struct net_device *dev = wdev->netdev;
1751 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1752 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1753 int32_t status;
1754
1755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1756 if (VOS_FTM_MODE == hdd_get_conparam()) {
1757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1758 status = -EPERM;
1759 goto out;
1760 }
1761
1762 status = wlan_hdd_validate_context(hdd_ctx);
1763 if (0 != status)
1764 goto out;
1765
1766
1767 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1768 data, data_len, NULL);
1769 if (status) {
1770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1771 goto out;
1772 }
1773
1774 /* Parse and fetch Command Type*/
1775 if (tb[STATION_INFO]) {
1776 status = hdd_get_station_info(hdd_ctx, adapter);
1777 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1778 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301779 } else if (tb[STATION_REMOTE]) {
1780 v_MACADDR_t mac_addr;
1781
1782 if (adapter->device_mode != WLAN_HDD_SOFTAP &&
1783 adapter->device_mode != WLAN_HDD_P2P_GO) {
1784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"invalid device_mode:%d",
1785 adapter->device_mode);
1786 status = -EINVAL;
1787 goto out;
1788 }
1789
1790 nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
1791 VOS_MAC_ADDRESS_LEN);
1792
1793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "STATION_REMOTE "MAC_ADDRESS_STR"",
1794 MAC_ADDR_ARRAY(mac_addr.bytes));
1795
1796 status = hdd_get_cached_station_remote(hdd_ctx, adapter,
1797 mac_addr);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301798 } else {
1799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1800 status = -EINVAL;
1801 goto out;
1802 }
1803 EXIT();
1804out:
1805 return status;
1806}
1807
1808/**
1809 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1810 * @wiphy: corestack handler
1811 * @wdev: wireless device
1812 * @data: data
1813 * @data_len: data length
1814 *
1815 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1816 * Validate cmd attributes and send the station info to upper layers.
1817 *
1818 * Return: Success(0) or reason code for failure
1819 */
1820static int32_t
1821hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1822 struct wireless_dev *wdev,
1823 const void *data,
1824 int data_len)
1825{
1826 int ret;
1827
1828 vos_ssr_protect(__func__);
1829 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1830 vos_ssr_unprotect(__func__);
1831
1832 return ret;
1833}
1834
1835/*
1836 * undef short names defined for get station command
1837 * used by __wlan_hdd_cfg80211_get_station_cmd()
1838 */
1839#undef STATION_INVALID
1840#undef STATION_INFO
1841#undef STATION_ASSOC_FAIL_REASON
1842#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301843
Sunil Duttc69bccb2014-05-26 21:30:20 +05301844#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1845
1846static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1847 struct sk_buff *vendor_event)
1848{
1849 if (nla_put_u8(vendor_event,
1850 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1851 stats->rate.preamble) ||
1852 nla_put_u8(vendor_event,
1853 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1854 stats->rate.nss) ||
1855 nla_put_u8(vendor_event,
1856 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1857 stats->rate.bw) ||
1858 nla_put_u8(vendor_event,
1859 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1860 stats->rate.rateMcsIdx) ||
1861 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1862 stats->rate.bitrate ) ||
1863 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1864 stats->txMpdu ) ||
1865 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1866 stats->rxMpdu ) ||
1867 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1868 stats->mpduLost ) ||
1869 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1870 stats->retries) ||
1871 nla_put_u32(vendor_event,
1872 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1873 stats->retriesShort ) ||
1874 nla_put_u32(vendor_event,
1875 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1876 stats->retriesLong))
1877 {
1878 hddLog(VOS_TRACE_LEVEL_ERROR,
1879 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1880 return FALSE;
1881 }
1882 return TRUE;
1883}
1884
1885static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1886 struct sk_buff *vendor_event)
1887{
1888 u32 i = 0;
1889 struct nlattr *rateInfo;
1890 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1891 stats->type) ||
1892 nla_put(vendor_event,
1893 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1894 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1895 nla_put_u32(vendor_event,
1896 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1897 stats->capabilities) ||
1898 nla_put_u32(vendor_event,
1899 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1900 stats->numRate))
1901 {
1902 hddLog(VOS_TRACE_LEVEL_ERROR,
1903 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1904 goto error;
1905 }
1906
1907 rateInfo = nla_nest_start(vendor_event,
1908 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301909 if(!rateInfo)
1910 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301911 for (i = 0; i < stats->numRate; i++)
1912 {
1913 struct nlattr *rates;
1914 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1915 stats->rateStats +
1916 (i * sizeof(tSirWifiRateStat)));
1917 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301918 if(!rates)
1919 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301920
1921 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1922 {
1923 hddLog(VOS_TRACE_LEVEL_ERROR,
1924 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1925 return FALSE;
1926 }
1927 nla_nest_end(vendor_event, rates);
1928 }
1929 nla_nest_end(vendor_event, rateInfo);
1930
1931 return TRUE;
1932error:
1933 return FALSE;
1934}
1935
1936static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1937 struct sk_buff *vendor_event)
1938{
1939 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1940 stats->ac ) ||
1941 nla_put_u32(vendor_event,
1942 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1943 stats->txMpdu ) ||
1944 nla_put_u32(vendor_event,
1945 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1946 stats->rxMpdu ) ||
1947 nla_put_u32(vendor_event,
1948 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1949 stats->txMcast ) ||
1950 nla_put_u32(vendor_event,
1951 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1952 stats->rxMcast ) ||
1953 nla_put_u32(vendor_event,
1954 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1955 stats->rxAmpdu ) ||
1956 nla_put_u32(vendor_event,
1957 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1958 stats->txAmpdu ) ||
1959 nla_put_u32(vendor_event,
1960 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1961 stats->mpduLost )||
1962 nla_put_u32(vendor_event,
1963 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1964 stats->retries ) ||
1965 nla_put_u32(vendor_event,
1966 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1967 stats->retriesShort ) ||
1968 nla_put_u32(vendor_event,
1969 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1970 stats->retriesLong ) ||
1971 nla_put_u32(vendor_event,
1972 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1973 stats->contentionTimeMin ) ||
1974 nla_put_u32(vendor_event,
1975 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1976 stats->contentionTimeMax ) ||
1977 nla_put_u32(vendor_event,
1978 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1979 stats->contentionTimeAvg ) ||
1980 nla_put_u32(vendor_event,
1981 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1982 stats->contentionNumSamples ))
1983 {
1984 hddLog(VOS_TRACE_LEVEL_ERROR,
1985 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1986 return FALSE;
1987 }
1988 return TRUE;
1989}
1990
1991static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1992 struct sk_buff *vendor_event)
1993{
Dino Myclec8f3f332014-07-21 16:48:27 +05301994 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301995 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1996 nla_put(vendor_event,
1997 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
1998 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
1999 nla_put_u32(vendor_event,
2000 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
2001 stats->state ) ||
2002 nla_put_u32(vendor_event,
2003 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
2004 stats->roaming ) ||
2005 nla_put_u32(vendor_event,
2006 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
2007 stats->capabilities ) ||
2008 nla_put(vendor_event,
2009 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
2010 strlen(stats->ssid), stats->ssid) ||
2011 nla_put(vendor_event,
2012 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
2013 WNI_CFG_BSSID_LEN, stats->bssid) ||
2014 nla_put(vendor_event,
2015 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
2016 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
2017 nla_put(vendor_event,
2018 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
2019 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
2020 )
2021 {
2022 hddLog(VOS_TRACE_LEVEL_ERROR,
2023 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2024 return FALSE;
2025 }
2026 return TRUE;
2027}
2028
Dino Mycle3b9536d2014-07-09 22:05:24 +05302029static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
2030 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302031 struct sk_buff *vendor_event)
2032{
2033 int i = 0;
2034 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302035 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2036 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302037 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302038
Sunil Duttc69bccb2014-05-26 21:30:20 +05302039 if (FALSE == put_wifi_interface_info(
2040 &pWifiIfaceStat->info,
2041 vendor_event))
2042 {
2043 hddLog(VOS_TRACE_LEVEL_ERROR,
2044 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2045 return FALSE;
2046
2047 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05302048 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
2049 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
2050 if (NULL == pWifiIfaceStatTL)
2051 {
2052 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2053 return FALSE;
2054 }
2055
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302056 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
2057 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
2058 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
2059 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
2060
2061 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
2062 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
2063 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
2064 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302065
2066 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
2067 {
2068 if (VOS_STATUS_SUCCESS ==
2069 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2070 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
2071 {
2072 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
2073 * obtained from TL structure
2074 */
2075
2076 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
2077 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302078 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
2079
Srinivas Dasari98947432014-11-07 19:41:24 +05302080 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
2081 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
2082 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
2083 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
2084 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
2085 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
2086 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
2087 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302088
Srinivas Dasari98947432014-11-07 19:41:24 +05302089 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
2090 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
2091 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
2092 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
2093 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
2094 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
2095 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
2096 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302097
Srinivas Dasari98947432014-11-07 19:41:24 +05302098 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
2099 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
2100 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
2101 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
2102 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
2103 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
2104 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
2105 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302106 }
2107 else
2108 {
2109 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
2110 }
2111
Dino Mycle3b9536d2014-07-09 22:05:24 +05302112 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
2113 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
2114 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
2115 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
2116 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
2117 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
2118 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
2119 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
2120 }
2121 else
2122 {
2123 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
2124 }
2125
2126
Sunil Duttc69bccb2014-05-26 21:30:20 +05302127
2128 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302129 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2130 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
2131 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302132 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
2133 pWifiIfaceStat->beaconRx) ||
2134 nla_put_u32(vendor_event,
2135 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
2136 pWifiIfaceStat->mgmtRx) ||
2137 nla_put_u32(vendor_event,
2138 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
2139 pWifiIfaceStat->mgmtActionRx) ||
2140 nla_put_u32(vendor_event,
2141 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
2142 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302143 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302144 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
2145 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302146 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302147 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
2148 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302149 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302150 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
2151 pWifiIfaceStat->rssiAck))
2152 {
2153 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302154 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2155 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302156 return FALSE;
2157 }
2158
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302159#ifdef FEATURE_EXT_LL_STAT
2160 /*
2161 * Ensure when EXT_LL_STAT is supported by both host and fwr,
2162 * then host should send Leaky AP stats to upper layer,
2163 * otherwise no need to send these stats.
2164 */
2165 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
2166 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
2167 )
2168 {
2169 hddLog(VOS_TRACE_LEVEL_INFO,
2170 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
2171 pWifiIfaceStat->leakyApStat.is_leaky_ap,
2172 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
2173 pWifiIfaceStat->leakyApStat.rx_leak_window,
2174 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
2175 if (nla_put_u32(vendor_event,
2176 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
2177 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
2178 nla_put_u32(vendor_event,
2179 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
2180 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
2181 nla_put_u32(vendor_event,
2182 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
2183 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05302184 hdd_wlan_nla_put_u64(vendor_event,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302185 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
2186 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
2187 {
2188 hddLog(VOS_TRACE_LEVEL_ERROR,
2189 FL("EXT_LL_STAT put fail"));
2190 vos_mem_free(pWifiIfaceStatTL);
2191 return FALSE;
2192 }
2193 }
2194#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05302195 wmmInfo = nla_nest_start(vendor_event,
2196 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302197 if(!wmmInfo)
2198 {
2199 vos_mem_free(pWifiIfaceStatTL);
2200 return FALSE;
2201 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302202 for (i = 0; i < WIFI_AC_MAX; i++)
2203 {
2204 struct nlattr *wmmStats;
2205 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302206 if(!wmmStats)
2207 {
2208 vos_mem_free(pWifiIfaceStatTL);
2209 return FALSE;
2210 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302211 if (FALSE == put_wifi_wmm_ac_stat(
2212 &pWifiIfaceStat->AccessclassStats[i],
2213 vendor_event))
2214 {
2215 hddLog(VOS_TRACE_LEVEL_ERROR,
2216 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05302217 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302218 return FALSE;
2219 }
2220
2221 nla_nest_end(vendor_event, wmmStats);
2222 }
2223 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05302224 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302225 return TRUE;
2226}
2227
2228static tSirWifiInterfaceMode
2229 hdd_map_device_to_ll_iface_mode ( int deviceMode )
2230{
2231 switch (deviceMode)
2232 {
2233 case WLAN_HDD_INFRA_STATION:
2234 return WIFI_INTERFACE_STA;
2235 case WLAN_HDD_SOFTAP:
2236 return WIFI_INTERFACE_SOFTAP;
2237 case WLAN_HDD_P2P_CLIENT:
2238 return WIFI_INTERFACE_P2P_CLIENT;
2239 case WLAN_HDD_P2P_GO:
2240 return WIFI_INTERFACE_P2P_GO;
2241 case WLAN_HDD_IBSS:
2242 return WIFI_INTERFACE_IBSS;
2243 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05302244 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302245 }
2246}
2247
2248static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
2249 tpSirWifiInterfaceInfo pInfo)
2250{
2251 v_U8_t *staMac = NULL;
2252 hdd_station_ctx_t *pHddStaCtx;
2253 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2254 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
2255
2256 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
2257
2258 vos_mem_copy(pInfo->macAddr,
2259 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
2260
2261 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2262 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
2263 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
2264 {
2265 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2266 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
2267 {
2268 pInfo->state = WIFI_DISCONNECTED;
2269 }
2270 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
2271 {
2272 hddLog(VOS_TRACE_LEVEL_ERROR,
2273 "%s: Session ID %d, Connection is in progress", __func__,
2274 pAdapter->sessionId);
2275 pInfo->state = WIFI_ASSOCIATING;
2276 }
2277 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
2278 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
2279 {
2280 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
2281 hddLog(VOS_TRACE_LEVEL_ERROR,
2282 "%s: client " MAC_ADDRESS_STR
2283 " is in the middle of WPS/EAPOL exchange.", __func__,
2284 MAC_ADDR_ARRAY(staMac));
2285 pInfo->state = WIFI_AUTHENTICATING;
2286 }
2287 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
2288 {
2289 pInfo->state = WIFI_ASSOCIATED;
2290 vos_mem_copy(pInfo->bssid,
2291 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
2292 vos_mem_copy(pInfo->ssid,
2293 pHddStaCtx->conn_info.SSID.SSID.ssId,
2294 pHddStaCtx->conn_info.SSID.SSID.length);
2295 //NULL Terminate the string.
2296 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
2297 }
2298 }
2299 vos_mem_copy(pInfo->countryStr,
2300 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2301
2302 vos_mem_copy(pInfo->apCountryStr,
2303 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2304
2305 return TRUE;
2306}
2307
2308/*
2309 * hdd_link_layer_process_peer_stats () - This function is called after
2310 * receiving Link Layer Peer statistics from FW.This function converts
2311 * the firmware data to the NL data and sends the same to the kernel/upper
2312 * layers.
2313 */
2314static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
2315 v_VOID_t *pData)
2316{
2317 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302318 tpSirWifiPeerStat pWifiPeerStat;
2319 tpSirWifiPeerInfo pWifiPeerInfo;
2320 struct nlattr *peerInfo;
2321 struct sk_buff *vendor_event;
2322 int status, i;
2323
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302324 ENTER();
2325
Sunil Duttc69bccb2014-05-26 21:30:20 +05302326 status = wlan_hdd_validate_context(pHddCtx);
2327 if (0 != status)
2328 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302329 return;
2330 }
2331
2332 pWifiPeerStat = (tpSirWifiPeerStat) pData;
2333
2334 hddLog(VOS_TRACE_LEVEL_INFO,
2335 "LL_STATS_PEER_ALL : numPeers %u",
2336 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302337 /*
2338 * Allocate a size of 4096 for the peer stats comprising
2339 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
2340 * sizeof (tSirWifiRateStat).Each field is put with an
2341 * NL attribute.The size of 4096 is considered assuming
2342 * that number of rates shall not exceed beyond 50 with
2343 * the sizeof (tSirWifiRateStat) being 32.
2344 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302345 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2346 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302347 if (!vendor_event)
2348 {
2349 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302350 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05302351 __func__);
2352 return;
2353 }
2354 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302355 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2356 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
2357 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302358 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
2359 pWifiPeerStat->numPeers))
2360 {
2361 hddLog(VOS_TRACE_LEVEL_ERROR,
2362 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
2363 kfree_skb(vendor_event);
2364 return;
2365 }
2366
2367 peerInfo = nla_nest_start(vendor_event,
2368 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302369 if(!peerInfo)
2370 {
2371 hddLog(VOS_TRACE_LEVEL_ERROR,
2372 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
2373 __func__);
2374 kfree_skb(vendor_event);
2375 return;
2376 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302377
2378 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2379 pWifiPeerStat->peerInfo);
2380
2381 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
2382 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302383 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302384 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302385
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302386 if(!peers)
2387 {
2388 hddLog(VOS_TRACE_LEVEL_ERROR,
2389 "%s: peer stats put fail",
2390 __func__);
2391 kfree_skb(vendor_event);
2392 return;
2393 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302394 if (FALSE == put_wifi_peer_info(
2395 pWifiPeerInfo, vendor_event))
2396 {
2397 hddLog(VOS_TRACE_LEVEL_ERROR,
2398 "%s: put_wifi_peer_info put fail", __func__);
2399 kfree_skb(vendor_event);
2400 return;
2401 }
2402
2403 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2404 pWifiPeerStat->peerInfo +
2405 (i * sizeof(tSirWifiPeerInfo)) +
2406 (numRate * sizeof (tSirWifiRateStat)));
2407 nla_nest_end(vendor_event, peers);
2408 }
2409 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302410 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302411 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302412}
2413
2414/*
2415 * hdd_link_layer_process_iface_stats () - This function is called after
2416 * receiving Link Layer Interface statistics from FW.This function converts
2417 * the firmware data to the NL data and sends the same to the kernel/upper
2418 * layers.
2419 */
2420static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
2421 v_VOID_t *pData)
2422{
2423 tpSirWifiIfaceStat pWifiIfaceStat;
2424 struct sk_buff *vendor_event;
2425 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2426 int status;
2427
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302428 ENTER();
2429
Sunil Duttc69bccb2014-05-26 21:30:20 +05302430 status = wlan_hdd_validate_context(pHddCtx);
2431 if (0 != status)
2432 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302433 return;
2434 }
2435 /*
2436 * Allocate a size of 4096 for the interface stats comprising
2437 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
2438 * assuming that all these fit with in the limit.Please take
2439 * a call on the limit based on the data requirements on
2440 * interface statistics.
2441 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302442 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2443 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302444 if (!vendor_event)
2445 {
2446 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302447 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302448 return;
2449 }
2450
2451 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
2452
Dino Mycle3b9536d2014-07-09 22:05:24 +05302453
2454 if (FALSE == hdd_get_interface_info( pAdapter,
2455 &pWifiIfaceStat->info))
2456 {
2457 hddLog(VOS_TRACE_LEVEL_ERROR,
2458 FL("hdd_get_interface_info get fail") );
2459 kfree_skb(vendor_event);
2460 return;
2461 }
2462
2463 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
2464 vendor_event))
2465 {
2466 hddLog(VOS_TRACE_LEVEL_ERROR,
2467 FL("put_wifi_iface_stats fail") );
2468 kfree_skb(vendor_event);
2469 return;
2470 }
2471
Sunil Duttc69bccb2014-05-26 21:30:20 +05302472 hddLog(VOS_TRACE_LEVEL_INFO,
2473 "WMI_LINK_STATS_IFACE Data");
2474
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302475 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302476
2477 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302478}
2479
2480/*
2481 * hdd_link_layer_process_radio_stats () - This function is called after
2482 * receiving Link Layer Radio statistics from FW.This function converts
2483 * the firmware data to the NL data and sends the same to the kernel/upper
2484 * layers.
2485 */
2486static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
2487 v_VOID_t *pData)
2488{
2489 int status, i;
2490 tpSirWifiRadioStat pWifiRadioStat;
2491 tpSirWifiChannelStats pWifiChannelStats;
2492 struct sk_buff *vendor_event;
2493 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2494 struct nlattr *chList;
2495
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302496 ENTER();
2497
Sunil Duttc69bccb2014-05-26 21:30:20 +05302498 status = wlan_hdd_validate_context(pHddCtx);
2499 if (0 != status)
2500 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302501 return;
2502 }
2503 pWifiRadioStat = (tpSirWifiRadioStat) pData;
2504
2505 hddLog(VOS_TRACE_LEVEL_INFO,
2506 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302507 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05302508 " radio is %d onTime is %u "
2509 " txTime is %u rxTime is %u "
2510 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05302511 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05302512 " onTimePnoScan is %u onTimeHs20 is %u "
2513 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302514 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302515 pWifiRadioStat->radio, pWifiRadioStat->onTime,
2516 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
2517 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302518 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302519 pWifiRadioStat->onTimeRoamScan,
2520 pWifiRadioStat->onTimePnoScan,
2521 pWifiRadioStat->onTimeHs20,
2522 pWifiRadioStat->numChannels);
2523 /*
2524 * Allocate a size of 4096 for the Radio stats comprising
2525 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
2526 * (tSirWifiChannelStats).Each channel data is put with an
2527 * NL attribute.The size of 4096 is considered assuming that
2528 * number of channels shall not exceed beyond 60 with the
2529 * sizeof (tSirWifiChannelStats) being 24 bytes.
2530 */
2531
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302532 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2533 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302534 if (!vendor_event)
2535 {
2536 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302537 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302538 return;
2539 }
2540
2541 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302542 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2543 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2544 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302545 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2546 pWifiRadioStat->radio) ||
2547 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302548 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2549 NUM_RADIOS) ||
2550 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302551 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2552 pWifiRadioStat->onTime) ||
2553 nla_put_u32(vendor_event,
2554 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2555 pWifiRadioStat->txTime) ||
2556 nla_put_u32(vendor_event,
2557 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2558 pWifiRadioStat->rxTime) ||
2559 nla_put_u32(vendor_event,
2560 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2561 pWifiRadioStat->onTimeScan) ||
2562 nla_put_u32(vendor_event,
2563 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2564 pWifiRadioStat->onTimeNbd) ||
2565 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302566 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2567 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302568 nla_put_u32(vendor_event,
2569 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2570 pWifiRadioStat->onTimeRoamScan) ||
2571 nla_put_u32(vendor_event,
2572 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2573 pWifiRadioStat->onTimePnoScan) ||
2574 nla_put_u32(vendor_event,
2575 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2576 pWifiRadioStat->onTimeHs20) ||
2577 nla_put_u32(vendor_event,
2578 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2579 pWifiRadioStat->numChannels))
2580 {
2581 hddLog(VOS_TRACE_LEVEL_ERROR,
2582 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2583 kfree_skb(vendor_event);
2584 return ;
2585 }
2586
2587 chList = nla_nest_start(vendor_event,
2588 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302589 if(!chList)
2590 {
2591 hddLog(VOS_TRACE_LEVEL_ERROR,
2592 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2593 __func__);
2594 kfree_skb(vendor_event);
2595 return;
2596 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302597 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2598 {
2599 struct nlattr *chInfo;
2600
2601 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2602 pWifiRadioStat->channels +
2603 (i * sizeof(tSirWifiChannelStats)));
2604
Sunil Duttc69bccb2014-05-26 21:30:20 +05302605 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302606 if(!chInfo)
2607 {
2608 hddLog(VOS_TRACE_LEVEL_ERROR,
2609 "%s: failed to put chInfo",
2610 __func__);
2611 kfree_skb(vendor_event);
2612 return;
2613 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302614
2615 if (nla_put_u32(vendor_event,
2616 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2617 pWifiChannelStats->channel.width) ||
2618 nla_put_u32(vendor_event,
2619 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2620 pWifiChannelStats->channel.centerFreq) ||
2621 nla_put_u32(vendor_event,
2622 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2623 pWifiChannelStats->channel.centerFreq0) ||
2624 nla_put_u32(vendor_event,
2625 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2626 pWifiChannelStats->channel.centerFreq1) ||
2627 nla_put_u32(vendor_event,
2628 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2629 pWifiChannelStats->onTime) ||
2630 nla_put_u32(vendor_event,
2631 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2632 pWifiChannelStats->ccaBusyTime))
2633 {
2634 hddLog(VOS_TRACE_LEVEL_ERROR,
2635 FL("cfg80211_vendor_event_alloc failed") );
2636 kfree_skb(vendor_event);
2637 return ;
2638 }
2639 nla_nest_end(vendor_event, chInfo);
2640 }
2641 nla_nest_end(vendor_event, chList);
2642
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302643 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302644
2645 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302646 return;
2647}
2648
2649/*
2650 * hdd_link_layer_stats_ind_callback () - This function is called after
2651 * receiving Link Layer indications from FW.This callback converts the firmware
2652 * data to the NL data and send the same to the kernel/upper layers.
2653 */
2654static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2655 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302656 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302657{
Dino Mycled3d50022014-07-07 12:58:25 +05302658 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2659 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302660 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302661 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302662 int status;
2663
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302664 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302665
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302666 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302667 if (0 != status)
2668 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302669 return;
2670 }
2671
Dino Mycled3d50022014-07-07 12:58:25 +05302672 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2673 if (NULL == pAdapter)
2674 {
2675 hddLog(VOS_TRACE_LEVEL_ERROR,
2676 FL(" MAC address %pM does not exist with host"),
2677 macAddr);
2678 return;
2679 }
2680
Sunil Duttc69bccb2014-05-26 21:30:20 +05302681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302682 "%s: Interface: %s LLStats indType: %d", __func__,
2683 pAdapter->dev->name, indType);
2684
Sunil Duttc69bccb2014-05-26 21:30:20 +05302685 switch (indType)
2686 {
2687 case SIR_HAL_LL_STATS_RESULTS_RSP:
2688 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302689 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302690 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2691 "respId = %u, moreResultToFollow = %u",
2692 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2693 macAddr, linkLayerStatsResults->respId,
2694 linkLayerStatsResults->moreResultToFollow);
2695
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302696 spin_lock(&hdd_context_lock);
2697 context = &pHddCtx->ll_stats_context;
2698 /* validate response received from target */
2699 if ((context->request_id != linkLayerStatsResults->respId) ||
2700 !(context->request_bitmap & linkLayerStatsResults->paramId))
2701 {
2702 spin_unlock(&hdd_context_lock);
2703 hddLog(LOGE,
2704 FL("Error : Request id %d response id %d request bitmap 0x%x"
2705 "response bitmap 0x%x"),
2706 context->request_id, linkLayerStatsResults->respId,
2707 context->request_bitmap, linkLayerStatsResults->paramId);
2708 return;
2709 }
2710 spin_unlock(&hdd_context_lock);
2711
Sunil Duttc69bccb2014-05-26 21:30:20 +05302712 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2713 {
2714 hdd_link_layer_process_radio_stats(pAdapter,
2715 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302716 spin_lock(&hdd_context_lock);
2717 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2718 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302719 }
2720 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2721 {
2722 hdd_link_layer_process_iface_stats(pAdapter,
2723 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302724 spin_lock(&hdd_context_lock);
2725 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2726 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302727 }
2728 else if ( linkLayerStatsResults->paramId &
2729 WMI_LINK_STATS_ALL_PEER )
2730 {
2731 hdd_link_layer_process_peer_stats(pAdapter,
2732 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302733 spin_lock(&hdd_context_lock);
2734 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2735 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302736 } /* WMI_LINK_STATS_ALL_PEER */
2737 else
2738 {
2739 hddLog(VOS_TRACE_LEVEL_ERROR,
2740 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2741 }
2742
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302743 spin_lock(&hdd_context_lock);
2744 /* complete response event if all requests are completed */
2745 if (0 == context->request_bitmap)
2746 complete(&context->response_event);
2747 spin_unlock(&hdd_context_lock);
2748
Sunil Duttc69bccb2014-05-26 21:30:20 +05302749 break;
2750 }
2751 default:
2752 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2753 break;
2754 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302755
2756 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302757 return;
2758}
2759
2760const struct
2761nla_policy
2762qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2763{
2764 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2765 { .type = NLA_U32 },
2766 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2767 { .type = NLA_U32 },
2768};
2769
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302770static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2771 struct wireless_dev *wdev,
2772 const void *data,
2773 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302774{
2775 int status;
2776 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302777 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302778 struct net_device *dev = wdev->netdev;
2779 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2780 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2781
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302782 ENTER();
2783
Sunil Duttc69bccb2014-05-26 21:30:20 +05302784 status = wlan_hdd_validate_context(pHddCtx);
2785 if (0 != status)
2786 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302787 return -EINVAL;
2788 }
2789
2790 if (NULL == pAdapter)
2791 {
2792 hddLog(VOS_TRACE_LEVEL_ERROR,
2793 FL("HDD adapter is Null"));
2794 return -ENODEV;
2795 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302796 /* check the LLStats Capability */
2797 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2798 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2799 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302800 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302801 FL("Link Layer Statistics not supported by Firmware"));
2802 return -EINVAL;
2803 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302804
2805 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2806 (struct nlattr *)data,
2807 data_len, qca_wlan_vendor_ll_set_policy))
2808 {
2809 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2810 return -EINVAL;
2811 }
2812 if (!tb_vendor
2813 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2814 {
2815 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2816 return -EINVAL;
2817 }
2818 if (!tb_vendor[
2819 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2820 {
2821 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2822 return -EINVAL;
2823 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302824 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302825 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302826
Dino Mycledf0a5d92014-07-04 09:41:55 +05302827 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302828 nla_get_u32(
2829 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2830
Dino Mycledf0a5d92014-07-04 09:41:55 +05302831 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302832 nla_get_u32(
2833 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2834
Dino Mycled3d50022014-07-07 12:58:25 +05302835 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2836 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302837
2838
2839 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302840 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2841 "Statistics Gathering = %d ",
2842 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2843 linkLayerStatsSetReq.mpduSizeThreshold,
2844 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302845
2846 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2847 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302848 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302849 {
2850 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2851 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302852 return -EINVAL;
2853
2854 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302855
Sunil Duttc69bccb2014-05-26 21:30:20 +05302856 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302857 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302858 {
2859 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2860 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302861 return -EINVAL;
2862 }
2863
2864 pAdapter->isLinkLayerStatsSet = 1;
2865
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302866 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302867 return 0;
2868}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302869static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2870 struct wireless_dev *wdev,
2871 const void *data,
2872 int data_len)
2873{
2874 int ret = 0;
2875
2876 vos_ssr_protect(__func__);
2877 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2878 vos_ssr_unprotect(__func__);
2879
2880 return ret;
2881}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302882
2883const struct
2884nla_policy
2885qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2886{
2887 /* Unsigned 32bit value provided by the caller issuing the GET stats
2888 * command. When reporting
2889 * the stats results, the driver uses the same value to indicate
2890 * which GET request the results
2891 * correspond to.
2892 */
2893 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2894
2895 /* Unsigned 32bit value . bit mask to identify what statistics are
2896 requested for retrieval */
2897 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2898};
2899
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302900static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2901 struct wireless_dev *wdev,
2902 const void *data,
2903 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302904{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302905 unsigned long rc;
2906 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302907 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2908 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302909 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302910 struct net_device *dev = wdev->netdev;
2911 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302912 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302913 int status;
2914
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302915 ENTER();
2916
Sunil Duttc69bccb2014-05-26 21:30:20 +05302917 status = wlan_hdd_validate_context(pHddCtx);
2918 if (0 != status)
2919 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302920 return -EINVAL ;
2921 }
2922
2923 if (NULL == pAdapter)
2924 {
2925 hddLog(VOS_TRACE_LEVEL_FATAL,
2926 "%s: HDD adapter is Null", __func__);
2927 return -ENODEV;
2928 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302929
2930 if (pHddStaCtx == NULL)
2931 {
2932 hddLog(VOS_TRACE_LEVEL_FATAL,
2933 "%s: HddStaCtx is Null", __func__);
2934 return -ENODEV;
2935 }
2936
Dino Mycledf0a5d92014-07-04 09:41:55 +05302937 /* check the LLStats Capability */
2938 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2939 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2940 {
2941 hddLog(VOS_TRACE_LEVEL_ERROR,
2942 FL("Link Layer Statistics not supported by Firmware"));
2943 return -EINVAL;
2944 }
2945
Sunil Duttc69bccb2014-05-26 21:30:20 +05302946
2947 if (!pAdapter->isLinkLayerStatsSet)
2948 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302949 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302950 "%s: isLinkLayerStatsSet : %d",
2951 __func__, pAdapter->isLinkLayerStatsSet);
2952 return -EINVAL;
2953 }
2954
Mukul Sharma10313ba2015-07-29 19:14:39 +05302955 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2956 {
2957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2958 "%s: Roaming in progress, so unable to proceed this request", __func__);
2959 return -EBUSY;
2960 }
2961
Sunil Duttc69bccb2014-05-26 21:30:20 +05302962 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2963 (struct nlattr *)data,
2964 data_len, qca_wlan_vendor_ll_get_policy))
2965 {
2966 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2967 return -EINVAL;
2968 }
2969
2970 if (!tb_vendor
2971 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2972 {
2973 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2974 return -EINVAL;
2975 }
2976
2977 if (!tb_vendor
2978 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2979 {
2980 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2981 return -EINVAL;
2982 }
2983
Sunil Duttc69bccb2014-05-26 21:30:20 +05302984
Dino Mycledf0a5d92014-07-04 09:41:55 +05302985 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302986 nla_get_u32( tb_vendor[
2987 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302988 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302989 nla_get_u32( tb_vendor[
2990 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2991
Dino Mycled3d50022014-07-07 12:58:25 +05302992 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2993 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302994
2995 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302996 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
2997 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302998 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302999
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303000 spin_lock(&hdd_context_lock);
3001 context = &pHddCtx->ll_stats_context;
3002 context->request_id = linkLayerStatsGetReq.reqId;
3003 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
3004 INIT_COMPLETION(context->response_event);
3005 spin_unlock(&hdd_context_lock);
3006
Sunil Duttc69bccb2014-05-26 21:30:20 +05303007 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303008 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303009 {
3010 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3011 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303012 return -EINVAL;
3013 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303014
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303015 rc = wait_for_completion_timeout(&context->response_event,
3016 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
3017 if (!rc)
3018 {
3019 hddLog(LOGE,
3020 FL("Target response timed out request id %d request bitmap 0x%x"),
3021 context->request_id, context->request_bitmap);
3022 return -ETIMEDOUT;
3023 }
3024
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303025 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303026 return 0;
3027}
3028
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303029static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
3030 struct wireless_dev *wdev,
3031 const void *data,
3032 int data_len)
3033{
3034 int ret = 0;
3035
3036 vos_ssr_protect(__func__);
3037 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
3038 vos_ssr_unprotect(__func__);
3039
3040 return ret;
3041}
3042
Sunil Duttc69bccb2014-05-26 21:30:20 +05303043const struct
3044nla_policy
3045qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
3046{
3047 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
3048 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
3049 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
3050 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
3051};
3052
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303053static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3054 struct wireless_dev *wdev,
3055 const void *data,
3056 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303057{
3058 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3059 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05303060 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303061 struct net_device *dev = wdev->netdev;
3062 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3063 u32 statsClearReqMask;
3064 u8 stopReq;
3065 int status;
3066
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303067 ENTER();
3068
Sunil Duttc69bccb2014-05-26 21:30:20 +05303069 status = wlan_hdd_validate_context(pHddCtx);
3070 if (0 != status)
3071 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303072 return -EINVAL;
3073 }
3074
3075 if (NULL == pAdapter)
3076 {
3077 hddLog(VOS_TRACE_LEVEL_FATAL,
3078 "%s: HDD adapter is Null", __func__);
3079 return -ENODEV;
3080 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05303081 /* check the LLStats Capability */
3082 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
3083 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
3084 {
3085 hddLog(VOS_TRACE_LEVEL_ERROR,
3086 FL("Enable LLStats Capability"));
3087 return -EINVAL;
3088 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05303089
3090 if (!pAdapter->isLinkLayerStatsSet)
3091 {
3092 hddLog(VOS_TRACE_LEVEL_FATAL,
3093 "%s: isLinkLayerStatsSet : %d",
3094 __func__, pAdapter->isLinkLayerStatsSet);
3095 return -EINVAL;
3096 }
3097
3098 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
3099 (struct nlattr *)data,
3100 data_len, qca_wlan_vendor_ll_clr_policy))
3101 {
3102 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
3103 return -EINVAL;
3104 }
3105
3106 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
3107
3108 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
3109 {
3110 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
3111 return -EINVAL;
3112
3113 }
3114
Sunil Duttc69bccb2014-05-26 21:30:20 +05303115
Dino Mycledf0a5d92014-07-04 09:41:55 +05303116 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303117 nla_get_u32(
3118 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
3119
Dino Mycledf0a5d92014-07-04 09:41:55 +05303120 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303121 nla_get_u8(
3122 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
3123
3124 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05303125 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303126
Dino Mycled3d50022014-07-07 12:58:25 +05303127 vos_mem_copy(linkLayerStatsClearReq.macAddr,
3128 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05303129
3130 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05303131 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
3132 "statsClearReqMask = 0x%X, stopReq = %d",
3133 linkLayerStatsClearReq.reqId,
3134 linkLayerStatsClearReq.macAddr,
3135 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303136 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303137
3138 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303139 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303140 {
3141 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05303142 hdd_station_ctx_t *pHddStaCtx;
3143
3144 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3145 if (VOS_STATUS_SUCCESS !=
3146 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
3147 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
3148 {
3149 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3150 "WLANTL_ClearInterfaceStats Failed", __func__);
3151 return -EINVAL;
3152 }
3153 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
3154 (statsClearReqMask & WIFI_STATS_IFACE)) {
3155 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
3156 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
3157 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
3158 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
3159 }
3160
Sunil Duttc69bccb2014-05-26 21:30:20 +05303161 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
3162 2 * sizeof(u32) +
3163 NLMSG_HDRLEN);
3164
3165 if (temp_skbuff != NULL)
3166 {
3167
3168 if (nla_put_u32(temp_skbuff,
3169 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
3170 statsClearReqMask) ||
3171 nla_put_u32(temp_skbuff,
3172 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
3173 stopReq))
3174 {
3175 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
3176 kfree_skb(temp_skbuff);
3177 return -EINVAL;
3178 }
3179 /* If the ask is to stop the stats collection as part of clear
3180 * (stopReq = 1) , ensure that no further requests of get
3181 * go to the firmware by having isLinkLayerStatsSet set to 0.
3182 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303183 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05303184 * case the firmware is just asked to clear the statistics.
3185 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05303186 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303187 pAdapter->isLinkLayerStatsSet = 0;
3188 return cfg80211_vendor_cmd_reply(temp_skbuff);
3189 }
3190 return -ENOMEM;
3191 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303192
3193 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303194 return -EINVAL;
3195}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303196static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3197 struct wireless_dev *wdev,
3198 const void *data,
3199 int data_len)
3200{
3201 int ret = 0;
3202
3203 vos_ssr_protect(__func__);
3204 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
3205 vos_ssr_unprotect(__func__);
3206
3207 return ret;
3208
3209
3210}
Sunil Duttc69bccb2014-05-26 21:30:20 +05303211#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
3212
Dino Mycle6fb96c12014-06-10 11:52:40 +05303213#ifdef WLAN_FEATURE_EXTSCAN
3214static const struct nla_policy
3215wlan_hdd_extscan_config_policy
3216 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
3217{
3218 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
3219 { .type = NLA_U32 },
3220 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
3221 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05303222 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
3223 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303224 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
3225 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
3226 { .type = NLA_U32 },
3227 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
3228 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
3229
3230 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
3231 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
3232 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
3233 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
3234 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303235 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
3236 { .type = NLA_U32 },
3237 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
3238 { .type = NLA_U32 },
3239 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
3240 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303241 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
3242 { .type = NLA_U32 },
3243 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
3244 { .type = NLA_U32 },
3245 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
3246 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303247 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
3248 { .type = NLA_U8 },
3249 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303250 { .type = NLA_U8 },
3251 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
3252 { .type = NLA_U8 },
3253 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
3254 { .type = NLA_U8 },
3255
3256 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
3257 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05303258 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
3259 .type = NLA_UNSPEC,
3260 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05303261 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
3262 { .type = NLA_S32 },
3263 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
3264 { .type = NLA_S32 },
3265 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
3266 { .type = NLA_U32 },
3267 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
3268 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303269 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
3270 { .type = NLA_U32 },
3271 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
3272 { .type = NLA_BINARY,
3273 .len = IEEE80211_MAX_SSID_LEN + 1 },
3274 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303275 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303276 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
3277 { .type = NLA_U32 },
3278 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
3279 { .type = NLA_U8 },
3280 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
3281 { .type = NLA_S32 },
3282 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
3283 { .type = NLA_S32 },
3284 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
3285 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303286};
3287
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303288/**
3289 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
3290 * @ctx: hdd global context
3291 * @data: capabilities data
3292 *
3293 * Return: none
3294 */
3295static void
3296wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303297{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303298 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303299 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303300 tSirEXTScanCapabilitiesEvent *data =
3301 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303302
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303303 ENTER();
3304
3305 if (wlan_hdd_validate_context(pHddCtx))
3306 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303307 return;
3308 }
3309
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303310 if (!pMsg)
3311 {
3312 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3313 return;
3314 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303315
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303316 vos_spin_lock_acquire(&hdd_context_lock);
3317
3318 context = &pHddCtx->ext_scan_context;
3319 /* validate response received from target*/
3320 if (context->request_id != data->requestId)
3321 {
3322 vos_spin_lock_release(&hdd_context_lock);
3323 hddLog(LOGE,
3324 FL("Target response id did not match: request_id %d resposne_id %d"),
3325 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303326 return;
3327 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303328 else
3329 {
3330 context->capability_response = *data;
3331 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303332 }
3333
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303334 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303335
Dino Mycle6fb96c12014-06-10 11:52:40 +05303336 return;
3337}
3338
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303339/*
3340 * define short names for the global vendor params
3341 * used by wlan_hdd_send_ext_scan_capability()
3342 */
3343#define PARAM_REQUEST_ID \
3344 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3345#define PARAM_STATUS \
3346 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
3347#define MAX_SCAN_CACHE_SIZE \
3348 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
3349#define MAX_SCAN_BUCKETS \
3350 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
3351#define MAX_AP_CACHE_PER_SCAN \
3352 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
3353#define MAX_RSSI_SAMPLE_SIZE \
3354 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
3355#define MAX_SCAN_RPT_THRHOLD \
3356 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
3357#define MAX_HOTLIST_BSSIDS \
3358 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
3359#define MAX_BSSID_HISTORY_ENTRIES \
3360 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
3361#define MAX_HOTLIST_SSIDS \
3362 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303363#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
3364 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303365
3366static int wlan_hdd_send_ext_scan_capability(void *ctx)
3367{
3368 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3369 struct sk_buff *skb = NULL;
3370 int ret;
3371 tSirEXTScanCapabilitiesEvent *data;
3372 tANI_U32 nl_buf_len;
3373
3374 ret = wlan_hdd_validate_context(pHddCtx);
3375 if (0 != ret)
3376 {
3377 return ret;
3378 }
3379
3380 data = &(pHddCtx->ext_scan_context.capability_response);
3381
3382 nl_buf_len = NLMSG_HDRLEN;
3383 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
3384 (sizeof(data->status) + NLA_HDRLEN) +
3385 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
3386 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
3387 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
3388 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
3389 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
3390 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
3391 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
3392 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
3393
3394 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
3395
3396 if (!skb)
3397 {
3398 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
3399 return -ENOMEM;
3400 }
3401
3402 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
3403 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
3404 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
3405 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
3406 data->maxRssiSampleSize, data->maxScanReportingThreshold);
3407 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
3408 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
3409 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
3410
3411 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
3412 nla_put_u32(skb, PARAM_STATUS, data->status) ||
3413 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
3414 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
3415 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
3416 data->maxApPerScan) ||
3417 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
3418 data->maxRssiSampleSize) ||
3419 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
3420 data->maxScanReportingThreshold) ||
3421 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
3422 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
3423 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303424 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
3425 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303426 {
3427 hddLog(LOGE, FL("nla put fail"));
3428 goto nla_put_failure;
3429 }
3430
3431 cfg80211_vendor_cmd_reply(skb);
3432 return 0;
3433
3434nla_put_failure:
3435 kfree_skb(skb);
3436 return -EINVAL;;
3437}
3438
3439/*
3440 * done with short names for the global vendor params
3441 * used by wlan_hdd_send_ext_scan_capability()
3442 */
3443#undef PARAM_REQUEST_ID
3444#undef PARAM_STATUS
3445#undef MAX_SCAN_CACHE_SIZE
3446#undef MAX_SCAN_BUCKETS
3447#undef MAX_AP_CACHE_PER_SCAN
3448#undef MAX_RSSI_SAMPLE_SIZE
3449#undef MAX_SCAN_RPT_THRHOLD
3450#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303451#undef MAX_BSSID_HISTORY_ENTRIES
3452#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05303453
3454static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
3455{
3456 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
3457 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303458 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303459 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303461 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303462
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303463 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303464 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303465
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303466 if (!pMsg)
3467 {
3468 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303469 return;
3470 }
3471
Dino Mycle6fb96c12014-06-10 11:52:40 +05303472 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3473 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
3474
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303475 context = &pHddCtx->ext_scan_context;
3476 spin_lock(&hdd_context_lock);
3477 if (context->request_id == pData->requestId) {
3478 context->response_status = pData->status ? -EINVAL : 0;
3479 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303480 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303481 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303482
3483 /*
3484 * Store the Request ID for comparing with the requestID obtained
3485 * in other requests.HDD shall return a failure is the extscan_stop
3486 * request is issued with a different requestId as that of the
3487 * extscan_start request. Also, This requestId shall be used while
3488 * indicating the full scan results to the upper layers.
3489 * The requestId is stored with the assumption that the firmware
3490 * shall return the ext scan start request's requestId in ext scan
3491 * start response.
3492 */
3493 if (pData->status == 0)
3494 pMac->sme.extScanStartReqId = pData->requestId;
3495
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303496 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303497 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303498}
3499
3500
3501static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
3502{
3503 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
3504 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303505 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303506
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303507 ENTER();
3508
3509 if (wlan_hdd_validate_context(pHddCtx)){
3510 return;
3511 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303512
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303513 if (!pMsg)
3514 {
3515 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303516 return;
3517 }
3518
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303519 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3520 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303521
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303522 context = &pHddCtx->ext_scan_context;
3523 spin_lock(&hdd_context_lock);
3524 if (context->request_id == pData->requestId) {
3525 context->response_status = pData->status ? -EINVAL : 0;
3526 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303527 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303528 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303529
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303530 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303531 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303532}
3533
Dino Mycle6fb96c12014-06-10 11:52:40 +05303534static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3535 void *pMsg)
3536{
3537 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303538 tpSirEXTScanSetBssidHotListRspParams pData =
3539 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303540 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303541
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303542 ENTER();
3543
3544 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303545 return;
3546 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303547
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303548 if (!pMsg)
3549 {
3550 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3551 return;
3552 }
3553
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303554 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3555 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303556
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303557 context = &pHddCtx->ext_scan_context;
3558 spin_lock(&hdd_context_lock);
3559 if (context->request_id == pData->requestId) {
3560 context->response_status = pData->status ? -EINVAL : 0;
3561 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303562 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303563 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303564
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303565 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303566 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303567}
3568
3569static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3570 void *pMsg)
3571{
3572 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303573 tpSirEXTScanResetBssidHotlistRspParams pData =
3574 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303575 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303576
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303577 ENTER();
3578
3579 if (wlan_hdd_validate_context(pHddCtx)) {
3580 return;
3581 }
3582 if (!pMsg)
3583 {
3584 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303585 return;
3586 }
3587
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303588 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3589 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303590
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303591 context = &pHddCtx->ext_scan_context;
3592 spin_lock(&hdd_context_lock);
3593 if (context->request_id == pData->requestId) {
3594 context->response_status = pData->status ? -EINVAL : 0;
3595 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303596 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303597 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303598
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303599 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303600 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303601}
3602
Dino Mycle6fb96c12014-06-10 11:52:40 +05303603static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3604 void *pMsg)
3605{
3606 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3607 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303608 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303609 tANI_S32 totalResults;
3610 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303611 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3612 struct hdd_ext_scan_context *context;
3613 bool ignore_cached_results = false;
3614 tExtscanCachedScanResult *result;
3615 struct nlattr *nla_results;
3616 tANI_U16 ieLength= 0;
3617 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303618
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303619 ENTER();
3620
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303621 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303622 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303623
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303624 if (!pMsg)
3625 {
3626 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3627 return;
3628 }
3629
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303630 spin_lock(&hdd_context_lock);
3631 context = &pHddCtx->ext_scan_context;
3632 ignore_cached_results = context->ignore_cached_results;
3633 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303634
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303635 if (ignore_cached_results) {
3636 hddLog(LOGE,
3637 FL("Ignore the cached results received after timeout"));
3638 return;
3639 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303640
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303641 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3642 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303643
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303644 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303645
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303646 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3647 scan_id_index++) {
3648 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303649
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303650 totalResults = result->num_results;
3651 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3652 result->scan_id, result->flags, totalResults);
3653 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303654
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303655 do{
3656 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3657 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3658 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303659
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303660 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3661 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3662
3663 if (!skb) {
3664 hddLog(VOS_TRACE_LEVEL_ERROR,
3665 FL("cfg80211_vendor_event_alloc failed"));
3666 return;
3667 }
3668
3669 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3670
3671 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3672 pData->requestId) ||
3673 nla_put_u32(skb,
3674 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3675 resultsPerEvent)) {
3676 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3677 goto fail;
3678 }
3679 if (nla_put_u8(skb,
3680 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3681 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303682 {
3683 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3684 goto fail;
3685 }
3686
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303687 if (nla_put_u32(skb,
3688 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3689 result->scan_id)) {
3690 hddLog(LOGE, FL("put fail"));
3691 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303692 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303693
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303694 nla_results = nla_nest_start(skb,
3695 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3696 if (!nla_results)
3697 goto fail;
3698
3699 if (resultsPerEvent) {
3700 struct nlattr *aps;
3701 struct nlattr *nla_result;
3702
3703 nla_result = nla_nest_start(skb, scan_id_index);
3704 if(!nla_result)
3705 goto fail;
3706
3707 if (nla_put_u32(skb,
3708 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3709 result->scan_id) ||
3710 nla_put_u32(skb,
3711 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3712 result->flags) ||
3713 nla_put_u32(skb,
3714 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3715 totalResults)) {
3716 hddLog(LOGE, FL("put fail"));
3717 goto fail;
3718 }
3719
3720 aps = nla_nest_start(skb,
3721 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3722 if (!aps)
3723 {
3724 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3725 goto fail;
3726 }
3727
3728 head_ptr = (tpSirWifiScanResult) &(result->ap);
3729
3730 for (j = 0; j < resultsPerEvent; j++, i++) {
3731 struct nlattr *ap;
3732 pSirWifiScanResult = head_ptr + i;
3733
3734 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303735 * Firmware returns timestamp from extscan_start till
3736 * BSSID was cached (in micro seconds). Add this with
3737 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303738 * to derive the time since boot when the
3739 * BSSID was cached.
3740 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303741 pSirWifiScanResult->ts +=
3742 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303743 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3744 "Ssid (%s)"
3745 "Bssid: %pM "
3746 "Channel (%u)"
3747 "Rssi (%d)"
3748 "RTT (%u)"
3749 "RTT_SD (%u)"
3750 "Beacon Period %u"
3751 "Capability 0x%x "
3752 "Ie length %d",
3753 i,
3754 pSirWifiScanResult->ts,
3755 pSirWifiScanResult->ssid,
3756 pSirWifiScanResult->bssid,
3757 pSirWifiScanResult->channel,
3758 pSirWifiScanResult->rssi,
3759 pSirWifiScanResult->rtt,
3760 pSirWifiScanResult->rtt_sd,
3761 pSirWifiScanResult->beaconPeriod,
3762 pSirWifiScanResult->capability,
3763 ieLength);
3764
3765 ap = nla_nest_start(skb, j + 1);
3766 if (!ap)
3767 {
3768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3769 goto fail;
3770 }
3771
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303772 if (hdd_wlan_nla_put_u64(skb,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303773 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3774 pSirWifiScanResult->ts) )
3775 {
3776 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3777 goto fail;
3778 }
3779 if (nla_put(skb,
3780 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3781 sizeof(pSirWifiScanResult->ssid),
3782 pSirWifiScanResult->ssid) )
3783 {
3784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3785 goto fail;
3786 }
3787 if (nla_put(skb,
3788 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3789 sizeof(pSirWifiScanResult->bssid),
3790 pSirWifiScanResult->bssid) )
3791 {
3792 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3793 goto fail;
3794 }
3795 if (nla_put_u32(skb,
3796 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3797 pSirWifiScanResult->channel) )
3798 {
3799 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3800 goto fail;
3801 }
3802 if (nla_put_s32(skb,
3803 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3804 pSirWifiScanResult->rssi) )
3805 {
3806 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3807 goto fail;
3808 }
3809 if (nla_put_u32(skb,
3810 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3811 pSirWifiScanResult->rtt) )
3812 {
3813 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3814 goto fail;
3815 }
3816 if (nla_put_u32(skb,
3817 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3818 pSirWifiScanResult->rtt_sd))
3819 {
3820 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3821 goto fail;
3822 }
3823 if (nla_put_u32(skb,
3824 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3825 pSirWifiScanResult->beaconPeriod))
3826 {
3827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3828 goto fail;
3829 }
3830 if (nla_put_u32(skb,
3831 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3832 pSirWifiScanResult->capability))
3833 {
3834 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3835 goto fail;
3836 }
3837 if (nla_put_u32(skb,
3838 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3839 ieLength))
3840 {
3841 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3842 goto fail;
3843 }
3844
3845 if (ieLength)
3846 if (nla_put(skb,
3847 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3848 ieLength, ie)) {
3849 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3850 goto fail;
3851 }
3852
3853 nla_nest_end(skb, ap);
3854 }
3855 nla_nest_end(skb, aps);
3856 nla_nest_end(skb, nla_result);
3857 }
3858
3859 nla_nest_end(skb, nla_results);
3860
3861 cfg80211_vendor_cmd_reply(skb);
3862
3863 } while (totalResults > 0);
3864 }
3865
3866 if (!pData->moreData) {
3867 spin_lock(&hdd_context_lock);
3868 context->response_status = 0;
3869 complete(&context->response_event);
3870 spin_unlock(&hdd_context_lock);
3871 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303872
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303873 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303874 return;
3875fail:
3876 kfree_skb(skb);
3877 return;
3878}
3879
3880static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3881 void *pMsg)
3882{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303883 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303884 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3885 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303886 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303887
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303888 ENTER();
3889
3890 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303891 hddLog(LOGE,
3892 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303893 return;
3894 }
3895 if (!pMsg)
3896 {
3897 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303898 return;
3899 }
3900
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303901 if (pData->bss_found)
3902 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3903 else
3904 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3905
Dino Mycle6fb96c12014-06-10 11:52:40 +05303906 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303907#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3908 NULL,
3909#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303910 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303911 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303912
3913 if (!skb) {
3914 hddLog(VOS_TRACE_LEVEL_ERROR,
3915 FL("cfg80211_vendor_event_alloc failed"));
3916 return;
3917 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303918
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303919 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3920 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3921 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3922 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3923
3924 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303925 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3926 "Ssid (%s) "
3927 "Bssid (" MAC_ADDRESS_STR ") "
3928 "Channel (%u) "
3929 "Rssi (%d) "
3930 "RTT (%u) "
3931 "RTT_SD (%u) ",
3932 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303933 pData->bssHotlist[i].ts,
3934 pData->bssHotlist[i].ssid,
3935 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3936 pData->bssHotlist[i].channel,
3937 pData->bssHotlist[i].rssi,
3938 pData->bssHotlist[i].rtt,
3939 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303940 }
3941
3942 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3943 pData->requestId) ||
3944 nla_put_u32(skb,
3945 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303946 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303947 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3948 goto fail;
3949 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303950 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303951 struct nlattr *aps;
3952
3953 aps = nla_nest_start(skb,
3954 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3955 if (!aps)
3956 goto fail;
3957
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303958 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303959 struct nlattr *ap;
3960
3961 ap = nla_nest_start(skb, i + 1);
3962 if (!ap)
3963 goto fail;
3964
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303965 if (hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303966 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303967 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303968 nla_put(skb,
3969 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303970 sizeof(pData->bssHotlist[i].ssid),
3971 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303972 nla_put(skb,
3973 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303974 sizeof(pData->bssHotlist[i].bssid),
3975 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303976 nla_put_u32(skb,
3977 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303978 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303979 nla_put_s32(skb,
3980 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303981 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303982 nla_put_u32(skb,
3983 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303984 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303985 nla_put_u32(skb,
3986 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303987 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303988 goto fail;
3989
3990 nla_nest_end(skb, ap);
3991 }
3992 nla_nest_end(skb, aps);
3993
3994 if (nla_put_u8(skb,
3995 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3996 pData->moreData))
3997 goto fail;
3998 }
3999
4000 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304001 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304002 return;
4003
4004fail:
4005 kfree_skb(skb);
4006 return;
4007
4008}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304009
4010static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
4011 void *pMsg)
4012{
4013 struct sk_buff *skb;
4014 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4015 tpSirWifiFullScanResultEvent pData =
4016 (tpSirWifiFullScanResultEvent) (pMsg);
4017
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304018 ENTER();
4019
4020 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304021 hddLog(LOGE,
4022 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304023 return;
4024 }
4025 if (!pMsg)
4026 {
4027 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304028 return;
4029 }
4030
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304031 /*
4032 * If the full scan result including IE data exceeds NL 4K size
4033 * limitation, drop that beacon/probe rsp frame.
4034 */
4035 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
4036 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
4037 return;
4038 }
4039
Dino Mycle6fb96c12014-06-10 11:52:40 +05304040 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304041#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4042 NULL,
4043#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304044 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4045 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
4046 GFP_KERNEL);
4047
4048 if (!skb) {
4049 hddLog(VOS_TRACE_LEVEL_ERROR,
4050 FL("cfg80211_vendor_event_alloc failed"));
4051 return;
4052 }
4053
Dino Mycle6fb96c12014-06-10 11:52:40 +05304054 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
4055 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
4056 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
4057 "Ssid (%s)"
4058 "Bssid (" MAC_ADDRESS_STR ")"
4059 "Channel (%u)"
4060 "Rssi (%d)"
4061 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304062 "RTT_SD (%u)"
4063 "Bcn Period %d"
4064 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05304065 pData->ap.ts,
4066 pData->ap.ssid,
4067 MAC_ADDR_ARRAY(pData->ap.bssid),
4068 pData->ap.channel,
4069 pData->ap.rssi,
4070 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304071 pData->ap.rtt_sd,
4072 pData->ap.beaconPeriod,
4073 pData->ap.capability);
4074
Dino Mycle6fb96c12014-06-10 11:52:40 +05304075 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
4076 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4077 pData->requestId) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304078 hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304079 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
4080 pData->ap.ts) ||
4081 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
4082 sizeof(pData->ap.ssid),
4083 pData->ap.ssid) ||
4084 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
4085 WNI_CFG_BSSID_LEN,
4086 pData->ap.bssid) ||
4087 nla_put_u32(skb,
4088 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
4089 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05304090 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304091 pData->ap.rssi) ||
4092 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
4093 pData->ap.rtt) ||
4094 nla_put_u32(skb,
4095 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
4096 pData->ap.rtt_sd) ||
4097 nla_put_u16(skb,
4098 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
4099 pData->ap.beaconPeriod) ||
4100 nla_put_u16(skb,
4101 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
4102 pData->ap.capability) ||
4103 nla_put_u32(skb,
4104 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304105 pData->ieLength) ||
4106 nla_put_u8(skb,
4107 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
4108 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304109 {
4110 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4111 goto nla_put_failure;
4112 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304113
4114 if (pData->ieLength) {
4115 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
4116 pData->ieLength,
4117 pData->ie))
4118 {
4119 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4120 goto nla_put_failure;
4121 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304122 }
4123
4124 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304125 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304126 return;
4127
4128nla_put_failure:
4129 kfree_skb(skb);
4130 return;
4131}
4132
4133static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
4134 void *pMsg)
4135{
4136 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4137 struct sk_buff *skb = NULL;
4138 tpSirEXTScanResultsAvailableIndParams pData =
4139 (tpSirEXTScanResultsAvailableIndParams) pMsg;
4140
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304141 ENTER();
4142
4143 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304144 hddLog(LOGE,
4145 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304146 return;
4147 }
4148 if (!pMsg)
4149 {
4150 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304151 return;
4152 }
4153
4154 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304155#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4156 NULL,
4157#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304158 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4159 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
4160 GFP_KERNEL);
4161
4162 if (!skb) {
4163 hddLog(VOS_TRACE_LEVEL_ERROR,
4164 FL("cfg80211_vendor_event_alloc failed"));
4165 return;
4166 }
4167
Dino Mycle6fb96c12014-06-10 11:52:40 +05304168 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
4169 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
4170 pData->numResultsAvailable);
4171 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4172 pData->requestId) ||
4173 nla_put_u32(skb,
4174 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
4175 pData->numResultsAvailable)) {
4176 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4177 goto nla_put_failure;
4178 }
4179
4180 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304181 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304182 return;
4183
4184nla_put_failure:
4185 kfree_skb(skb);
4186 return;
4187}
4188
4189static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
4190{
4191 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4192 struct sk_buff *skb = NULL;
4193 tpSirEXTScanProgressIndParams pData =
4194 (tpSirEXTScanProgressIndParams) pMsg;
4195
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304196 ENTER();
4197
4198 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304199 hddLog(LOGE,
4200 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304201 return;
4202 }
4203 if (!pMsg)
4204 {
4205 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304206 return;
4207 }
4208
4209 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304210#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4211 NULL,
4212#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304213 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4214 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
4215 GFP_KERNEL);
4216
4217 if (!skb) {
4218 hddLog(VOS_TRACE_LEVEL_ERROR,
4219 FL("cfg80211_vendor_event_alloc failed"));
4220 return;
4221 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304222 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304223 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
4224 pData->extScanEventType);
4225 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
4226 pData->status);
4227
4228 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
4229 pData->extScanEventType) ||
4230 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05304231 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4232 pData->requestId) ||
4233 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304234 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
4235 pData->status)) {
4236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4237 goto nla_put_failure;
4238 }
4239
4240 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304241 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304242 return;
4243
4244nla_put_failure:
4245 kfree_skb(skb);
4246 return;
4247}
4248
4249void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
4250 void *pMsg)
4251{
4252 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4253
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304254 ENTER();
4255
Dino Mycle6fb96c12014-06-10 11:52:40 +05304256 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304257 return;
4258 }
4259
4260 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
4261
4262
4263 switch(evType) {
4264 case SIR_HAL_EXTSCAN_START_RSP:
4265 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
4266 break;
4267
4268 case SIR_HAL_EXTSCAN_STOP_RSP:
4269 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
4270 break;
4271 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
4272 /* There is no need to send this response to upper layer
4273 Just log the message */
4274 hddLog(VOS_TRACE_LEVEL_INFO,
4275 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
4276 break;
4277 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
4278 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
4279 break;
4280
4281 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
4282 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
4283 break;
4284
Dino Mycle6fb96c12014-06-10 11:52:40 +05304285 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304286 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304287 break;
4288 case SIR_HAL_EXTSCAN_PROGRESS_IND:
4289 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
4290 break;
4291 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
4292 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
4293 break;
4294 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
4295 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
4296 break;
4297 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
4298 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
4299 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304300 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
4301 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
4302 break;
4303 default:
4304 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
4305 break;
4306 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304307 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304308}
4309
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304310static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4311 struct wireless_dev *wdev,
4312 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304313{
Dino Myclee8843b32014-07-04 14:21:45 +05304314 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304315 struct net_device *dev = wdev->netdev;
4316 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4317 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4318 struct nlattr
4319 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4320 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304321 struct hdd_ext_scan_context *context;
4322 unsigned long rc;
4323 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304324
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304325 ENTER();
4326
Dino Mycle6fb96c12014-06-10 11:52:40 +05304327 status = wlan_hdd_validate_context(pHddCtx);
4328 if (0 != status)
4329 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304330 return -EINVAL;
4331 }
Dino Myclee8843b32014-07-04 14:21:45 +05304332 /* check the EXTScan Capability */
4333 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304334 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4335 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304336 {
4337 hddLog(VOS_TRACE_LEVEL_ERROR,
4338 FL("EXTScan not enabled/supported by Firmware"));
4339 return -EINVAL;
4340 }
4341
Dino Mycle6fb96c12014-06-10 11:52:40 +05304342 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4343 data, dataLen,
4344 wlan_hdd_extscan_config_policy)) {
4345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4346 return -EINVAL;
4347 }
4348
4349 /* Parse and fetch request Id */
4350 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4352 return -EINVAL;
4353 }
4354
Dino Myclee8843b32014-07-04 14:21:45 +05304355 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304356 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304357 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304358
Dino Myclee8843b32014-07-04 14:21:45 +05304359 reqMsg.sessionId = pAdapter->sessionId;
4360 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304361
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304362 vos_spin_lock_acquire(&hdd_context_lock);
4363 context = &pHddCtx->ext_scan_context;
4364 context->request_id = reqMsg.requestId;
4365 INIT_COMPLETION(context->response_event);
4366 vos_spin_lock_release(&hdd_context_lock);
4367
Dino Myclee8843b32014-07-04 14:21:45 +05304368 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304369 if (!HAL_STATUS_SUCCESS(status)) {
4370 hddLog(VOS_TRACE_LEVEL_ERROR,
4371 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304372 return -EINVAL;
4373 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304374
4375 rc = wait_for_completion_timeout(&context->response_event,
4376 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4377 if (!rc) {
4378 hddLog(LOGE, FL("Target response timed out"));
4379 return -ETIMEDOUT;
4380 }
4381
4382 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
4383 if (ret)
4384 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
4385
4386 return ret;
4387
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304388 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304389 return 0;
4390}
4391
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304392static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4393 struct wireless_dev *wdev,
4394 const void *data, int dataLen)
4395{
4396 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304397
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304398 vos_ssr_protect(__func__);
4399 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
4400 vos_ssr_unprotect(__func__);
4401
4402 return ret;
4403}
4404
4405static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4406 struct wireless_dev *wdev,
4407 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304408{
Dino Myclee8843b32014-07-04 14:21:45 +05304409 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304410 struct net_device *dev = wdev->netdev;
4411 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4412 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4413 struct nlattr
4414 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4415 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304416 struct hdd_ext_scan_context *context;
4417 unsigned long rc;
4418 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304419
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304420 ENTER();
4421
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304422 if (VOS_FTM_MODE == hdd_get_conparam()) {
4423 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4424 return -EINVAL;
4425 }
4426
Dino Mycle6fb96c12014-06-10 11:52:40 +05304427 status = wlan_hdd_validate_context(pHddCtx);
4428 if (0 != status)
4429 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304430 return -EINVAL;
4431 }
Dino Myclee8843b32014-07-04 14:21:45 +05304432 /* check the EXTScan Capability */
4433 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304434 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4435 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304436 {
4437 hddLog(VOS_TRACE_LEVEL_ERROR,
4438 FL("EXTScan not enabled/supported by Firmware"));
4439 return -EINVAL;
4440 }
4441
Dino Mycle6fb96c12014-06-10 11:52:40 +05304442 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4443 data, dataLen,
4444 wlan_hdd_extscan_config_policy)) {
4445 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4446 return -EINVAL;
4447 }
4448 /* Parse and fetch request Id */
4449 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4450 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4451 return -EINVAL;
4452 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304453
Dino Myclee8843b32014-07-04 14:21:45 +05304454 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304455 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4456
Dino Myclee8843b32014-07-04 14:21:45 +05304457 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304458
Dino Myclee8843b32014-07-04 14:21:45 +05304459 reqMsg.sessionId = pAdapter->sessionId;
4460 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304461
4462 /* Parse and fetch flush parameter */
4463 if (!tb
4464 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
4465 {
4466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
4467 goto failed;
4468 }
Dino Myclee8843b32014-07-04 14:21:45 +05304469 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304470 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
4471
Dino Myclee8843b32014-07-04 14:21:45 +05304472 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304473
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304474 spin_lock(&hdd_context_lock);
4475 context = &pHddCtx->ext_scan_context;
4476 context->request_id = reqMsg.requestId;
4477 context->ignore_cached_results = false;
4478 INIT_COMPLETION(context->response_event);
4479 spin_unlock(&hdd_context_lock);
4480
Dino Myclee8843b32014-07-04 14:21:45 +05304481 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304482 if (!HAL_STATUS_SUCCESS(status)) {
4483 hddLog(VOS_TRACE_LEVEL_ERROR,
4484 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304485 return -EINVAL;
4486 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304487
4488 rc = wait_for_completion_timeout(&context->response_event,
4489 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4490 if (!rc) {
4491 hddLog(LOGE, FL("Target response timed out"));
4492 retval = -ETIMEDOUT;
4493 spin_lock(&hdd_context_lock);
4494 context->ignore_cached_results = true;
4495 spin_unlock(&hdd_context_lock);
4496 } else {
4497 spin_lock(&hdd_context_lock);
4498 retval = context->response_status;
4499 spin_unlock(&hdd_context_lock);
4500 }
4501
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304502 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304503 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304504
4505failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05304506 return -EINVAL;
4507}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304508static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4509 struct wireless_dev *wdev,
4510 const void *data, int dataLen)
4511{
4512 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304513
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304514 vos_ssr_protect(__func__);
4515 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
4516 vos_ssr_unprotect(__func__);
4517
4518 return ret;
4519}
4520
4521static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304522 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05304523 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304524{
4525 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
4526 struct net_device *dev = wdev->netdev;
4527 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4528 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4529 struct nlattr
4530 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4531 struct nlattr
4532 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4533 struct nlattr *apTh;
4534 eHalStatus status;
4535 tANI_U8 i = 0;
4536 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304537 struct hdd_ext_scan_context *context;
4538 tANI_U32 request_id;
4539 unsigned long rc;
4540 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304541
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304542 ENTER();
4543
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304544 if (VOS_FTM_MODE == hdd_get_conparam()) {
4545 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4546 return -EINVAL;
4547 }
4548
Dino Mycle6fb96c12014-06-10 11:52:40 +05304549 status = wlan_hdd_validate_context(pHddCtx);
4550 if (0 != status)
4551 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304552 return -EINVAL;
4553 }
Dino Myclee8843b32014-07-04 14:21:45 +05304554 /* check the EXTScan Capability */
4555 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304556 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4557 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304558 {
4559 hddLog(VOS_TRACE_LEVEL_ERROR,
4560 FL("EXTScan not enabled/supported by Firmware"));
4561 return -EINVAL;
4562 }
4563
Dino Mycle6fb96c12014-06-10 11:52:40 +05304564 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4565 data, dataLen,
4566 wlan_hdd_extscan_config_policy)) {
4567 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4568 return -EINVAL;
4569 }
4570
4571 /* Parse and fetch request Id */
4572 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4573 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4574 return -EINVAL;
4575 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304576 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4577 vos_mem_malloc(sizeof(*pReqMsg));
4578 if (!pReqMsg) {
4579 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4580 return -ENOMEM;
4581 }
4582
Dino Myclee8843b32014-07-04 14:21:45 +05304583
Dino Mycle6fb96c12014-06-10 11:52:40 +05304584 pReqMsg->requestId = nla_get_u32(
4585 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4586 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4587
4588 /* Parse and fetch number of APs */
4589 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4590 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4591 goto fail;
4592 }
4593
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304594 /* Parse and fetch lost ap sample size */
4595 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4596 hddLog(LOGE, FL("attr lost ap sample size failed"));
4597 goto fail;
4598 }
4599
4600 pReqMsg->lostBssidSampleSize = nla_get_u32(
4601 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4602 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4603
Dino Mycle6fb96c12014-06-10 11:52:40 +05304604 pReqMsg->sessionId = pAdapter->sessionId;
4605 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4606
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304607 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304608 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304609 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4610 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4611 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4612 goto fail;
4613 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304614 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304615
4616 nla_for_each_nested(apTh,
4617 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304618 if (i == pReqMsg->numBssid) {
4619 hddLog(LOGW, FL("Ignoring excess AP"));
4620 break;
4621 }
4622
Dino Mycle6fb96c12014-06-10 11:52:40 +05304623 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4624 nla_data(apTh), nla_len(apTh),
4625 NULL)) {
4626 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4627 goto fail;
4628 }
4629
4630 /* Parse and fetch MAC address */
4631 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4632 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4633 goto fail;
4634 }
4635 memcpy(pReqMsg->ap[i].bssid, nla_data(
4636 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4637 sizeof(tSirMacAddr));
4638 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4639
4640 /* Parse and fetch low RSSI */
4641 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4642 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4643 goto fail;
4644 }
4645 pReqMsg->ap[i].low = nla_get_s32(
4646 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4647 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4648
4649 /* Parse and fetch high RSSI */
4650 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4651 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4652 goto fail;
4653 }
4654 pReqMsg->ap[i].high = nla_get_s32(
4655 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4656 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4657 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304658 i++;
4659 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304660
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304661 if (i < pReqMsg->numBssid) {
4662 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4663 i, pReqMsg->numBssid);
4664 pReqMsg->numBssid = i;
4665 }
4666
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304667 context = &pHddCtx->ext_scan_context;
4668 spin_lock(&hdd_context_lock);
4669 INIT_COMPLETION(context->response_event);
4670 context->request_id = request_id = pReqMsg->requestId;
4671 spin_unlock(&hdd_context_lock);
4672
Dino Mycle6fb96c12014-06-10 11:52:40 +05304673 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4674 if (!HAL_STATUS_SUCCESS(status)) {
4675 hddLog(VOS_TRACE_LEVEL_ERROR,
4676 FL("sme_SetBssHotlist failed(err=%d)"), status);
4677 vos_mem_free(pReqMsg);
4678 return -EINVAL;
4679 }
4680
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304681 /* request was sent -- wait for the response */
4682 rc = wait_for_completion_timeout(&context->response_event,
4683 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4684
4685 if (!rc) {
4686 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4687 retval = -ETIMEDOUT;
4688 } else {
4689 spin_lock(&hdd_context_lock);
4690 if (context->request_id == request_id)
4691 retval = context->response_status;
4692 else
4693 retval = -EINVAL;
4694 spin_unlock(&hdd_context_lock);
4695 }
4696
Dino Myclee8843b32014-07-04 14:21:45 +05304697 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304698 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304699 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304700
4701fail:
4702 vos_mem_free(pReqMsg);
4703 return -EINVAL;
4704}
4705
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304706static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4707 struct wireless_dev *wdev,
4708 const void *data, int dataLen)
4709{
4710 int ret = 0;
4711
4712 vos_ssr_protect(__func__);
4713 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4714 dataLen);
4715 vos_ssr_unprotect(__func__);
4716
4717 return ret;
4718}
4719
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304720static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304721 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304722 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304723{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304724 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4725 struct net_device *dev = wdev->netdev;
4726 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4727 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4728 uint8_t num_channels = 0;
4729 uint8_t num_chan_new = 0;
4730 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304731 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304732 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304733 tWifiBand wifiBand;
4734 eHalStatus status;
4735 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304736 tANI_U8 i,j,k;
4737 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304738
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304739 ENTER();
4740
Dino Mycle6fb96c12014-06-10 11:52:40 +05304741 status = wlan_hdd_validate_context(pHddCtx);
4742 if (0 != status)
4743 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304744 return -EINVAL;
4745 }
Dino Myclee8843b32014-07-04 14:21:45 +05304746
Dino Mycle6fb96c12014-06-10 11:52:40 +05304747 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4748 data, dataLen,
4749 wlan_hdd_extscan_config_policy)) {
4750 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4751 return -EINVAL;
4752 }
4753
4754 /* Parse and fetch request Id */
4755 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4757 return -EINVAL;
4758 }
4759 requestId = nla_get_u32(
4760 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4761 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4762
4763 /* Parse and fetch wifi band */
4764 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4765 {
4766 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4767 return -EINVAL;
4768 }
4769 wifiBand = nla_get_u32(
4770 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4771 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4772
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304773 /* Parse and fetch max channels */
4774 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4775 {
4776 hddLog(LOGE, FL("attr max channels failed"));
4777 return -EINVAL;
4778 }
4779 maxChannels = nla_get_u32(
4780 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4781 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4782
Dino Mycle6fb96c12014-06-10 11:52:40 +05304783 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304784 wifiBand, chan_list,
4785 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304786 if (eHAL_STATUS_SUCCESS != status) {
4787 hddLog(VOS_TRACE_LEVEL_ERROR,
4788 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4789 return -EINVAL;
4790 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304791
Agrawal Ashish16abf782016-08-18 22:42:59 +05304792 num_channels = VOS_MIN(num_channels, maxChannels);
4793 num_chan_new = num_channels;
4794 /* remove the indoor only channels if iface is SAP */
4795 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4796 {
4797 num_chan_new = 0;
4798 for (i = 0; i < num_channels; i++)
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304799 for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) {
Agrawal Ashish16abf782016-08-18 22:42:59 +05304800 if (wiphy->bands[j] == NULL)
4801 continue;
4802 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4803 if ((chan_list[i] ==
4804 wiphy->bands[j]->channels[k].center_freq) &&
4805 (!(wiphy->bands[j]->channels[k].flags &
4806 IEEE80211_CHAN_INDOOR_ONLY))) {
4807 chan_list[num_chan_new] = chan_list[i];
4808 num_chan_new++;
4809 }
4810 }
4811 }
4812 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304813
Agrawal Ashish16abf782016-08-18 22:42:59 +05304814 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4815 for (i = 0; i < num_chan_new; i++)
4816 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4817 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304818
4819 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304820 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304821 NLMSG_HDRLEN);
4822
4823 if (!replySkb) {
4824 hddLog(VOS_TRACE_LEVEL_ERROR,
4825 FL("valid channels: buffer alloc fail"));
4826 return -EINVAL;
4827 }
4828 if (nla_put_u32(replySkb,
4829 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304830 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304831 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304832 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304833
4834 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4835 kfree_skb(replySkb);
4836 return -EINVAL;
4837 }
4838
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304839 ret = cfg80211_vendor_cmd_reply(replySkb);
4840
4841 EXIT();
4842 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304843}
4844
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304845static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4846 struct wireless_dev *wdev,
4847 const void *data, int dataLen)
4848{
4849 int ret = 0;
4850
4851 vos_ssr_protect(__func__);
4852 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4853 dataLen);
4854 vos_ssr_unprotect(__func__);
4855
4856 return ret;
4857}
4858
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304859static int hdd_extscan_start_fill_bucket_channel_spec(
4860 hdd_context_t *pHddCtx,
4861 tpSirEXTScanStartReqParams pReqMsg,
4862 struct nlattr **tb)
4863{
4864 struct nlattr *bucket[
4865 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4866 struct nlattr *channel[
4867 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4868 struct nlattr *buckets;
4869 struct nlattr *channels;
4870 int rem1, rem2;
4871 eHalStatus status;
4872 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304873 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304874 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4875 tANI_U32 passive_max_chn_time, active_max_chn_time;
4876
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304877 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304878 bktIndex = 0;
4879
4880 nla_for_each_nested(buckets,
4881 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304882 if (bktIndex >= expected_buckets) {
4883 hddLog(LOGW, FL("ignoring excess buckets"));
4884 break;
4885 }
4886
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304887 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304888 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4889 nla_data(buckets), nla_len(buckets),
4890 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304891 hddLog(LOGE, FL("nla_parse failed"));
4892 return -EINVAL;
4893 }
4894
4895 /* Parse and fetch bucket spec */
4896 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4897 hddLog(LOGE, FL("attr bucket index failed"));
4898 return -EINVAL;
4899 }
4900 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4901 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4902 hddLog(LOG1, FL("Bucket spec Index %d"),
4903 pReqMsg->buckets[bktIndex].bucket);
4904
4905 /* Parse and fetch wifi band */
4906 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4907 hddLog(LOGE, FL("attr wifi band failed"));
4908 return -EINVAL;
4909 }
4910 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4911 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4912 hddLog(LOG1, FL("Wifi band %d"),
4913 pReqMsg->buckets[bktIndex].band);
4914
4915 /* Parse and fetch period */
4916 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4917 hddLog(LOGE, FL("attr period failed"));
4918 return -EINVAL;
4919 }
4920 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4921 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4922 hddLog(LOG1, FL("period %d"),
4923 pReqMsg->buckets[bktIndex].period);
4924
4925 /* Parse and fetch report events */
4926 if (!bucket[
4927 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4928 hddLog(LOGE, FL("attr report events failed"));
4929 return -EINVAL;
4930 }
4931 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4932 bucket[
4933 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4934 hddLog(LOG1, FL("report events %d"),
4935 pReqMsg->buckets[bktIndex].reportEvents);
4936
4937 /* Parse and fetch max period */
4938 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4939 hddLog(LOGE, FL("attr max period failed"));
4940 return -EINVAL;
4941 }
4942 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4943 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4944 hddLog(LOG1, FL("max period %u"),
4945 pReqMsg->buckets[bktIndex].max_period);
4946
4947 /* Parse and fetch exponent */
4948 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4949 hddLog(LOGE, FL("attr exponent failed"));
4950 return -EINVAL;
4951 }
4952 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4953 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4954 hddLog(LOG1, FL("exponent %u"),
4955 pReqMsg->buckets[bktIndex].exponent);
4956
4957 /* Parse and fetch step count */
4958 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4959 hddLog(LOGE, FL("attr step count failed"));
4960 return -EINVAL;
4961 }
4962 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4963 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4964 hddLog(LOG1, FL("Step count %u"),
4965 pReqMsg->buckets[bktIndex].step_count);
4966
4967 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4968 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4969
4970 /* Framework shall pass the channel list if the input WiFi band is
4971 * WIFI_BAND_UNSPECIFIED.
4972 * If the input WiFi band is specified (any value other than
4973 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4974 */
4975 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4976 numChannels = 0;
4977 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4978 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4979 pReqMsg->buckets[bktIndex].band,
4980 chanList, &numChannels);
4981 if (!HAL_STATUS_SUCCESS(status)) {
4982 hddLog(LOGE,
4983 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4984 status);
4985 return -EINVAL;
4986 }
4987
4988 pReqMsg->buckets[bktIndex].numChannels =
4989 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4990 hddLog(LOG1, FL("Num channels %d"),
4991 pReqMsg->buckets[bktIndex].numChannels);
4992
4993 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4994 j++) {
4995 pReqMsg->buckets[bktIndex].channels[j].channel =
4996 chanList[j];
4997 pReqMsg->buckets[bktIndex].channels[j].
4998 chnlClass = 0;
4999 if (CSR_IS_CHANNEL_DFS(
5000 vos_freq_to_chan(chanList[j]))) {
5001 pReqMsg->buckets[bktIndex].channels[j].
5002 passive = 1;
5003 pReqMsg->buckets[bktIndex].channels[j].
5004 dwellTimeMs = passive_max_chn_time;
5005 } else {
5006 pReqMsg->buckets[bktIndex].channels[j].
5007 passive = 0;
5008 pReqMsg->buckets[bktIndex].channels[j].
5009 dwellTimeMs = active_max_chn_time;
5010 }
5011
5012 hddLog(LOG1,
5013 "Channel %u Passive %u Dwell time %u ms",
5014 pReqMsg->buckets[bktIndex].channels[j].channel,
5015 pReqMsg->buckets[bktIndex].channels[j].passive,
5016 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5017 }
5018
5019 bktIndex++;
5020 continue;
5021 }
5022
5023 /* Parse and fetch number of channels */
5024 if (!bucket[
5025 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
5026 hddLog(LOGE, FL("attr num channels failed"));
5027 return -EINVAL;
5028 }
5029
5030 pReqMsg->buckets[bktIndex].numChannels =
5031 nla_get_u32(bucket[
5032 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
5033 hddLog(LOG1, FL("num channels %d"),
5034 pReqMsg->buckets[bktIndex].numChannels);
5035
5036 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
5037 hddLog(LOGE, FL("attr channel spec failed"));
5038 return -EINVAL;
5039 }
5040
5041 j = 0;
5042 nla_for_each_nested(channels,
5043 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
5044 if (nla_parse(channel,
5045 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5046 nla_data(channels), nla_len(channels),
5047 wlan_hdd_extscan_config_policy)) {
5048 hddLog(LOGE, FL("nla_parse failed"));
5049 return -EINVAL;
5050 }
5051
5052 /* Parse and fetch channel */
5053 if (!channel[
5054 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
5055 hddLog(LOGE, FL("attr channel failed"));
5056 return -EINVAL;
5057 }
5058 pReqMsg->buckets[bktIndex].channels[j].channel =
5059 nla_get_u32(channel[
5060 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
5061 hddLog(LOG1, FL("channel %u"),
5062 pReqMsg->buckets[bktIndex].channels[j].channel);
5063
5064 /* Parse and fetch dwell time */
5065 if (!channel[
5066 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
5067 hddLog(LOGE, FL("attr dwelltime failed"));
5068 return -EINVAL;
5069 }
5070 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
5071 nla_get_u32(channel[
5072 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
5073
5074 hddLog(LOG1, FL("Dwell time (%u ms)"),
5075 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5076
5077
5078 /* Parse and fetch channel spec passive */
5079 if (!channel[
5080 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
5081 hddLog(LOGE,
5082 FL("attr channel spec passive failed"));
5083 return -EINVAL;
5084 }
5085 pReqMsg->buckets[bktIndex].channels[j].passive =
5086 nla_get_u8(channel[
5087 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
5088 hddLog(LOG1, FL("Chnl spec passive %u"),
5089 pReqMsg->buckets[bktIndex].channels[j].passive);
5090
5091 j++;
5092 }
5093
5094 bktIndex++;
5095 }
5096
5097 return 0;
5098}
5099
5100
5101/*
5102 * define short names for the global vendor params
5103 * used by wlan_hdd_cfg80211_extscan_start()
5104 */
5105#define PARAM_MAX \
5106QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
5107#define PARAM_REQUEST_ID \
5108QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
5109#define PARAM_BASE_PERIOD \
5110QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
5111#define PARAM_MAX_AP_PER_SCAN \
5112QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
5113#define PARAM_RPT_THRHLD_PERCENT \
5114QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
5115#define PARAM_RPT_THRHLD_NUM_SCANS \
5116QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
5117#define PARAM_NUM_BUCKETS \
5118QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
5119
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305120static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305121 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305122 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305123{
Dino Myclee8843b32014-07-04 14:21:45 +05305124 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305125 struct net_device *dev = wdev->netdev;
5126 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5127 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5128 struct nlattr *tb[PARAM_MAX + 1];
5129 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305130 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305131 tANI_U32 request_id;
5132 struct hdd_ext_scan_context *context;
5133 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305134
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305135 ENTER();
5136
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305137 if (VOS_FTM_MODE == hdd_get_conparam()) {
5138 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5139 return -EINVAL;
5140 }
5141
Dino Mycle6fb96c12014-06-10 11:52:40 +05305142 status = wlan_hdd_validate_context(pHddCtx);
5143 if (0 != status)
5144 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305145 return -EINVAL;
5146 }
Dino Myclee8843b32014-07-04 14:21:45 +05305147 /* check the EXTScan Capability */
5148 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305149 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5150 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305151 {
5152 hddLog(VOS_TRACE_LEVEL_ERROR,
5153 FL("EXTScan not enabled/supported by Firmware"));
5154 return -EINVAL;
5155 }
5156
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305157 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305158 data, dataLen,
5159 wlan_hdd_extscan_config_policy)) {
5160 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5161 return -EINVAL;
5162 }
5163
5164 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305165 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305166 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5167 return -EINVAL;
5168 }
5169
Dino Myclee8843b32014-07-04 14:21:45 +05305170 pReqMsg = (tpSirEXTScanStartReqParams)
5171 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305172 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305173 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5174 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305175 }
5176
5177 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305178 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305179 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5180
5181 pReqMsg->sessionId = pAdapter->sessionId;
5182 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5183
5184 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305185 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305186 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5187 goto fail;
5188 }
5189 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305190 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305191 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5192 pReqMsg->basePeriod);
5193
5194 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305195 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305196 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5197 goto fail;
5198 }
5199 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305200 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305201 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5202 pReqMsg->maxAPperScan);
5203
5204 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305205 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305206 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5207 goto fail;
5208 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305209 pReqMsg->reportThresholdPercent = nla_get_u8(
5210 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305211 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305212 pReqMsg->reportThresholdPercent);
5213
5214 /* Parse and fetch report threshold num scans */
5215 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5216 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5217 goto fail;
5218 }
5219 pReqMsg->reportThresholdNumScans = nla_get_u8(
5220 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5221 hddLog(LOG1, FL("Report Threshold num scans %d"),
5222 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305223
5224 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305225 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305226 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5227 goto fail;
5228 }
5229 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305230 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305231 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5232 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5233 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5234 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5235 }
5236 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5237 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305238
Dino Mycle6fb96c12014-06-10 11:52:40 +05305239 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5240 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5241 goto fail;
5242 }
5243
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305244 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305245
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305246 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5247 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305248
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305249 context = &pHddCtx->ext_scan_context;
5250 spin_lock(&hdd_context_lock);
5251 INIT_COMPLETION(context->response_event);
5252 context->request_id = request_id = pReqMsg->requestId;
5253 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305254
Dino Mycle6fb96c12014-06-10 11:52:40 +05305255 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5256 if (!HAL_STATUS_SUCCESS(status)) {
5257 hddLog(VOS_TRACE_LEVEL_ERROR,
5258 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305259 goto fail;
5260 }
5261
Srinivas Dasari91727c12016-03-23 17:59:06 +05305262 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5263
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305264 /* request was sent -- wait for the response */
5265 rc = wait_for_completion_timeout(&context->response_event,
5266 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5267
5268 if (!rc) {
5269 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5270 retval = -ETIMEDOUT;
5271 } else {
5272 spin_lock(&hdd_context_lock);
5273 if (context->request_id == request_id)
5274 retval = context->response_status;
5275 else
5276 retval = -EINVAL;
5277 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305278 }
5279
Dino Myclee8843b32014-07-04 14:21:45 +05305280 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305281 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305282 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305283
5284fail:
5285 vos_mem_free(pReqMsg);
5286 return -EINVAL;
5287}
5288
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305289/*
5290 * done with short names for the global vendor params
5291 * used by wlan_hdd_cfg80211_extscan_start()
5292 */
5293#undef PARAM_MAX
5294#undef PARAM_REQUEST_ID
5295#undef PARAM_BASE_PERIOD
5296#undef PARAMS_MAX_AP_PER_SCAN
5297#undef PARAMS_RPT_THRHLD_PERCENT
5298#undef PARAMS_RPT_THRHLD_NUM_SCANS
5299#undef PARAMS_NUM_BUCKETS
5300
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305301static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5302 struct wireless_dev *wdev,
5303 const void *data, int dataLen)
5304{
5305 int ret = 0;
5306
5307 vos_ssr_protect(__func__);
5308 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5309 vos_ssr_unprotect(__func__);
5310
5311 return ret;
5312}
5313
5314static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305315 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305316 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305317{
Dino Myclee8843b32014-07-04 14:21:45 +05305318 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305319 struct net_device *dev = wdev->netdev;
5320 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5321 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5322 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5323 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305324 int retval;
5325 unsigned long rc;
5326 struct hdd_ext_scan_context *context;
5327 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305328
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305329 ENTER();
5330
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305331 if (VOS_FTM_MODE == hdd_get_conparam()) {
5332 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5333 return -EINVAL;
5334 }
5335
Dino Mycle6fb96c12014-06-10 11:52:40 +05305336 status = wlan_hdd_validate_context(pHddCtx);
5337 if (0 != status)
5338 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305339 return -EINVAL;
5340 }
Dino Myclee8843b32014-07-04 14:21:45 +05305341 /* check the EXTScan Capability */
5342 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305343 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5344 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305345 {
5346 hddLog(VOS_TRACE_LEVEL_ERROR,
5347 FL("EXTScan not enabled/supported by Firmware"));
5348 return -EINVAL;
5349 }
5350
Dino Mycle6fb96c12014-06-10 11:52:40 +05305351 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5352 data, dataLen,
5353 wlan_hdd_extscan_config_policy)) {
5354 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5355 return -EINVAL;
5356 }
5357
5358 /* Parse and fetch request Id */
5359 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5360 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5361 return -EINVAL;
5362 }
5363
Dino Myclee8843b32014-07-04 14:21:45 +05305364 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305365 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305366 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305367
Dino Myclee8843b32014-07-04 14:21:45 +05305368 reqMsg.sessionId = pAdapter->sessionId;
5369 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305370
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305371 context = &pHddCtx->ext_scan_context;
5372 spin_lock(&hdd_context_lock);
5373 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305374 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305375 spin_unlock(&hdd_context_lock);
5376
Dino Myclee8843b32014-07-04 14:21:45 +05305377 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305378 if (!HAL_STATUS_SUCCESS(status)) {
5379 hddLog(VOS_TRACE_LEVEL_ERROR,
5380 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305381 return -EINVAL;
5382 }
5383
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305384 /* request was sent -- wait for the response */
5385 rc = wait_for_completion_timeout(&context->response_event,
5386 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5387
5388 if (!rc) {
5389 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5390 retval = -ETIMEDOUT;
5391 } else {
5392 spin_lock(&hdd_context_lock);
5393 if (context->request_id == request_id)
5394 retval = context->response_status;
5395 else
5396 retval = -EINVAL;
5397 spin_unlock(&hdd_context_lock);
5398 }
5399
5400 return retval;
5401
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305402 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305403 return 0;
5404}
5405
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305406static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5407 struct wireless_dev *wdev,
5408 const void *data, int dataLen)
5409{
5410 int ret = 0;
5411
5412 vos_ssr_protect(__func__);
5413 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5414 vos_ssr_unprotect(__func__);
5415
5416 return ret;
5417}
5418
5419static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305420 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305421 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305422{
Dino Myclee8843b32014-07-04 14:21:45 +05305423 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305424 struct net_device *dev = wdev->netdev;
5425 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5426 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5427 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5428 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305429 struct hdd_ext_scan_context *context;
5430 tANI_U32 request_id;
5431 unsigned long rc;
5432 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305433
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305434 ENTER();
5435
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305436 if (VOS_FTM_MODE == hdd_get_conparam()) {
5437 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5438 return -EINVAL;
5439 }
5440
Dino Mycle6fb96c12014-06-10 11:52:40 +05305441 status = wlan_hdd_validate_context(pHddCtx);
5442 if (0 != status)
5443 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305444 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305445 return -EINVAL;
5446 }
Dino Myclee8843b32014-07-04 14:21:45 +05305447 /* check the EXTScan Capability */
5448 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305449 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5450 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305451 {
5452 hddLog(VOS_TRACE_LEVEL_ERROR,
5453 FL("EXTScan not enabled/supported by Firmware"));
5454 return -EINVAL;
5455 }
5456
Dino Mycle6fb96c12014-06-10 11:52:40 +05305457 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5458 data, dataLen,
5459 wlan_hdd_extscan_config_policy)) {
5460 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5461 return -EINVAL;
5462 }
5463
5464 /* Parse and fetch request Id */
5465 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5467 return -EINVAL;
5468 }
5469
Dino Myclee8843b32014-07-04 14:21:45 +05305470 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305471 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305472 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305473
Dino Myclee8843b32014-07-04 14:21:45 +05305474 reqMsg.sessionId = pAdapter->sessionId;
5475 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305476
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305477 context = &pHddCtx->ext_scan_context;
5478 spin_lock(&hdd_context_lock);
5479 INIT_COMPLETION(context->response_event);
5480 context->request_id = request_id = reqMsg.requestId;
5481 spin_unlock(&hdd_context_lock);
5482
Dino Myclee8843b32014-07-04 14:21:45 +05305483 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305484 if (!HAL_STATUS_SUCCESS(status)) {
5485 hddLog(VOS_TRACE_LEVEL_ERROR,
5486 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305487 return -EINVAL;
5488 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305489
5490 /* request was sent -- wait for the response */
5491 rc = wait_for_completion_timeout(&context->response_event,
5492 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5493 if (!rc) {
5494 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5495 retval = -ETIMEDOUT;
5496 } else {
5497 spin_lock(&hdd_context_lock);
5498 if (context->request_id == request_id)
5499 retval = context->response_status;
5500 else
5501 retval = -EINVAL;
5502 spin_unlock(&hdd_context_lock);
5503 }
5504
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305505 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305506 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305507}
5508
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305509static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5510 struct wireless_dev *wdev,
5511 const void *data, int dataLen)
5512{
5513 int ret = 0;
5514
5515 vos_ssr_protect(__func__);
5516 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5517 vos_ssr_unprotect(__func__);
5518
5519 return ret;
5520}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305521#endif /* WLAN_FEATURE_EXTSCAN */
5522
Atul Mittal115287b2014-07-08 13:26:33 +05305523/*EXT TDLS*/
5524static const struct nla_policy
5525wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5526{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305527 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5528 .type = NLA_UNSPEC,
5529 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305530 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5531 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5532 {.type = NLA_S32 },
5533 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5534 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5535
5536};
5537
5538static const struct nla_policy
5539wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5540{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305541 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5542 .type = NLA_UNSPEC,
5543 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305544
5545};
5546
5547static const struct nla_policy
5548wlan_hdd_tdls_config_state_change_policy[
5549 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5550{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305551 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5552 .type = NLA_UNSPEC,
5553 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305554 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5555 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305556 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5557 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5558 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305559
5560};
5561
5562static const struct nla_policy
5563wlan_hdd_tdls_config_get_status_policy[
5564 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5565{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305566 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5567 .type = NLA_UNSPEC,
5568 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305569 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5570 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305571 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5572 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5573 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305574
5575};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305576
5577static const struct nla_policy
5578wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5579{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305580 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5581 .type = NLA_UNSPEC,
5582 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305583};
5584
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305585static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305586 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305587 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305588 int data_len)
5589{
5590
5591 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5592 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5593
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305594 ENTER();
5595
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305596 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305597 return -EINVAL;
5598 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305599 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305600 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305601 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305602 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305603 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305604 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305605 return -ENOTSUPP;
5606 }
5607
5608 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5609 data, data_len, wlan_hdd_mac_config)) {
5610 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5611 return -EINVAL;
5612 }
5613
5614 /* Parse and fetch mac address */
5615 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5616 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5617 return -EINVAL;
5618 }
5619
5620 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5621 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5622 VOS_MAC_ADDR_LAST_3_BYTES);
5623
Siddharth Bhal76972212014-10-15 16:22:51 +05305624 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5625
5626 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305627 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5628 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305629 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5630 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5631 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5632 {
5633 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5634 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5635 VOS_MAC_ADDRESS_LEN);
5636 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305637 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305638
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305639 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5640 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305641
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305642 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305643 return 0;
5644}
5645
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305646static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5647 struct wireless_dev *wdev,
5648 const void *data,
5649 int data_len)
5650{
5651 int ret = 0;
5652
5653 vos_ssr_protect(__func__);
5654 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5655 vos_ssr_unprotect(__func__);
5656
5657 return ret;
5658}
5659
5660static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305661 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305662 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305663 int data_len)
5664{
5665 u8 peer[6] = {0};
5666 struct net_device *dev = wdev->netdev;
5667 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5668 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5669 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5670 eHalStatus ret;
5671 tANI_S32 state;
5672 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305673 tANI_S32 global_operating_class = 0;
5674 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305675 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305676 int retVal;
5677
5678 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305679
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305680 if (!pAdapter) {
5681 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5682 return -EINVAL;
5683 }
5684
Atul Mittal115287b2014-07-08 13:26:33 +05305685 ret = wlan_hdd_validate_context(pHddCtx);
5686 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305687 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305688 return -EINVAL;
5689 }
5690 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305691 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305692 return -ENOTSUPP;
5693 }
5694 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5695 data, data_len,
5696 wlan_hdd_tdls_config_get_status_policy)) {
5697 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5698 return -EINVAL;
5699 }
5700
5701 /* Parse and fetch mac address */
5702 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5703 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5704 return -EINVAL;
5705 }
5706
5707 memcpy(peer, nla_data(
5708 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5709 sizeof(peer));
5710 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5711
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305712 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305713
Atul Mittal115287b2014-07-08 13:26:33 +05305714 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305715 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305716 NLMSG_HDRLEN);
5717
5718 if (!skb) {
5719 hddLog(VOS_TRACE_LEVEL_ERROR,
5720 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5721 return -EINVAL;
5722 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305723 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 +05305724 reason,
5725 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305726 global_operating_class,
5727 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305728 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305729 if (nla_put_s32(skb,
5730 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5731 state) ||
5732 nla_put_s32(skb,
5733 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5734 reason) ||
5735 nla_put_s32(skb,
5736 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5737 global_operating_class) ||
5738 nla_put_s32(skb,
5739 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5740 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305741
5742 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5743 goto nla_put_failure;
5744 }
5745
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305746 retVal = cfg80211_vendor_cmd_reply(skb);
5747 EXIT();
5748 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305749
5750nla_put_failure:
5751 kfree_skb(skb);
5752 return -EINVAL;
5753}
5754
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305755static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5756 struct wireless_dev *wdev,
5757 const void *data,
5758 int data_len)
5759{
5760 int ret = 0;
5761
5762 vos_ssr_protect(__func__);
5763 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5764 vos_ssr_unprotect(__func__);
5765
5766 return ret;
5767}
5768
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305769static int wlan_hdd_cfg80211_exttdls_callback(
5770#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5771 const tANI_U8* mac,
5772#else
5773 tANI_U8* mac,
5774#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305775 tANI_S32 state,
5776 tANI_S32 reason,
5777 void *ctx)
5778{
5779 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305780 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305781 tANI_S32 global_operating_class = 0;
5782 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305783 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305784
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305785 ENTER();
5786
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305787 if (!pAdapter) {
5788 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5789 return -EINVAL;
5790 }
5791
5792 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305793 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305795 return -EINVAL;
5796 }
5797
5798 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305799 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305800 return -ENOTSUPP;
5801 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305802 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5803#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5804 NULL,
5805#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305806 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5807 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5808 GFP_KERNEL);
5809
5810 if (!skb) {
5811 hddLog(VOS_TRACE_LEVEL_ERROR,
5812 FL("cfg80211_vendor_event_alloc failed"));
5813 return -EINVAL;
5814 }
5815 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305816 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5817 reason,
5818 state,
5819 global_operating_class,
5820 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305821 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5822 MAC_ADDR_ARRAY(mac));
5823
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305824 if (nla_put(skb,
5825 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5826 VOS_MAC_ADDR_SIZE, mac) ||
5827 nla_put_s32(skb,
5828 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5829 state) ||
5830 nla_put_s32(skb,
5831 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5832 reason) ||
5833 nla_put_s32(skb,
5834 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5835 channel) ||
5836 nla_put_s32(skb,
5837 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5838 global_operating_class)
5839 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305840 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5841 goto nla_put_failure;
5842 }
5843
5844 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305845 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305846 return (0);
5847
5848nla_put_failure:
5849 kfree_skb(skb);
5850 return -EINVAL;
5851}
5852
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305853static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305854 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305855 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305856 int data_len)
5857{
5858 u8 peer[6] = {0};
5859 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305860 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5861 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5862 eHalStatus status;
5863 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305864 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305865 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305866
5867 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305868
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305869 if (!dev) {
5870 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5871 return -EINVAL;
5872 }
5873
5874 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5875 if (!pAdapter) {
5876 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5877 return -EINVAL;
5878 }
5879
Atul Mittal115287b2014-07-08 13:26:33 +05305880 status = wlan_hdd_validate_context(pHddCtx);
5881 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305882 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305883 return -EINVAL;
5884 }
5885 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305886 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305887 return -ENOTSUPP;
5888 }
5889 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5890 data, data_len,
5891 wlan_hdd_tdls_config_enable_policy)) {
5892 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5893 return -EINVAL;
5894 }
5895
5896 /* Parse and fetch mac address */
5897 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5898 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5899 return -EINVAL;
5900 }
5901
5902 memcpy(peer, nla_data(
5903 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5904 sizeof(peer));
5905 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5906
5907 /* Parse and fetch channel */
5908 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5909 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5910 return -EINVAL;
5911 }
5912 pReqMsg.channel = nla_get_s32(
5913 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5914 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5915
5916 /* Parse and fetch global operating class */
5917 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5918 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5919 return -EINVAL;
5920 }
5921 pReqMsg.global_operating_class = nla_get_s32(
5922 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5923 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5924 pReqMsg.global_operating_class);
5925
5926 /* Parse and fetch latency ms */
5927 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5928 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5929 return -EINVAL;
5930 }
5931 pReqMsg.max_latency_ms = nla_get_s32(
5932 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5933 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5934 pReqMsg.max_latency_ms);
5935
5936 /* Parse and fetch required bandwidth kbps */
5937 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5939 return -EINVAL;
5940 }
5941
5942 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5943 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5944 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5945 pReqMsg.min_bandwidth_kbps);
5946
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305947 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305948 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305949 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305950 wlan_hdd_cfg80211_exttdls_callback);
5951
5952 EXIT();
5953 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305954}
5955
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305956static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5957 struct wireless_dev *wdev,
5958 const void *data,
5959 int data_len)
5960{
5961 int ret = 0;
5962
5963 vos_ssr_protect(__func__);
5964 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5965 vos_ssr_unprotect(__func__);
5966
5967 return ret;
5968}
5969
5970static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305971 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305972 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305973 int data_len)
5974{
5975 u8 peer[6] = {0};
5976 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305977 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5978 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5979 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305980 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305981 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305982
5983 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305984
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305985 if (!dev) {
5986 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5987 return -EINVAL;
5988 }
5989
5990 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5991 if (!pAdapter) {
5992 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5993 return -EINVAL;
5994 }
5995
Atul Mittal115287b2014-07-08 13:26:33 +05305996 status = wlan_hdd_validate_context(pHddCtx);
5997 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305998 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305999 return -EINVAL;
6000 }
6001 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05306002 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05306003 return -ENOTSUPP;
6004 }
6005 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
6006 data, data_len,
6007 wlan_hdd_tdls_config_disable_policy)) {
6008 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6009 return -EINVAL;
6010 }
6011 /* Parse and fetch mac address */
6012 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
6013 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
6014 return -EINVAL;
6015 }
6016
6017 memcpy(peer, nla_data(
6018 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
6019 sizeof(peer));
6020 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
6021
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306022 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
6023
6024 EXIT();
6025 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05306026}
6027
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306028static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
6029 struct wireless_dev *wdev,
6030 const void *data,
6031 int data_len)
6032{
6033 int ret = 0;
6034
6035 vos_ssr_protect(__func__);
6036 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
6037 vos_ssr_unprotect(__func__);
6038
6039 return ret;
6040}
6041
Dasari Srinivas7875a302014-09-26 17:50:57 +05306042static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306043__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05306044 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306045 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05306046{
6047 struct net_device *dev = wdev->netdev;
6048 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6049 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6050 struct sk_buff *skb = NULL;
6051 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306052 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306053
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306054 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306055
6056 ret = wlan_hdd_validate_context(pHddCtx);
6057 if (0 != ret)
6058 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306059 return ret;
6060 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306061 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
6062 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
6063 fset |= WIFI_FEATURE_INFRA;
6064 }
6065
6066 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
6067 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
6068 fset |= WIFI_FEATURE_INFRA_5G;
6069 }
6070
6071#ifdef WLAN_FEATURE_P2P
6072 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
6073 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
6074 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
6075 fset |= WIFI_FEATURE_P2P;
6076 }
6077#endif
6078
6079 /* Soft-AP is supported currently by default */
6080 fset |= WIFI_FEATURE_SOFT_AP;
6081
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05306082 /* HOTSPOT is a supplicant feature, enable it by default */
6083 fset |= WIFI_FEATURE_HOTSPOT;
6084
Dasari Srinivas7875a302014-09-26 17:50:57 +05306085#ifdef WLAN_FEATURE_EXTSCAN
6086 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05306087 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
6088 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
6089 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306090 fset |= WIFI_FEATURE_EXTSCAN;
6091 }
6092#endif
6093
Dasari Srinivas7875a302014-09-26 17:50:57 +05306094 if (sme_IsFeatureSupportedByFW(NAN)) {
6095 hddLog(LOG1, FL("NAN is supported by firmware"));
6096 fset |= WIFI_FEATURE_NAN;
6097 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306098
6099 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05306100 if (sme_IsFeatureSupportedByFW(RTT) &&
6101 pHddCtx->cfg_ini->enable_rtt_support) {
6102 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306103 fset |= WIFI_FEATURE_D2AP_RTT;
6104 }
6105
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05306106 if (sme_IsFeatureSupportedByFW(RTT3)) {
6107 hddLog(LOG1, FL("RTT3 is supported by firmware"));
6108 fset |= WIFI_FEATURE_RTT3;
6109 }
6110
Dasari Srinivas7875a302014-09-26 17:50:57 +05306111#ifdef FEATURE_WLAN_BATCH_SCAN
6112 if (fset & WIFI_FEATURE_EXTSCAN) {
6113 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
6114 fset &= ~WIFI_FEATURE_BATCH_SCAN;
6115 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
6116 hddLog(LOG1, FL("Batch scan is supported by firmware"));
6117 fset |= WIFI_FEATURE_BATCH_SCAN;
6118 }
6119#endif
6120
6121#ifdef FEATURE_WLAN_SCAN_PNO
6122 if (pHddCtx->cfg_ini->configPNOScanSupport &&
6123 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
6124 hddLog(LOG1, FL("PNO is supported by firmware"));
6125 fset |= WIFI_FEATURE_PNO;
6126 }
6127#endif
6128
6129 /* STA+STA is supported currently by default */
6130 fset |= WIFI_FEATURE_ADDITIONAL_STA;
6131
6132#ifdef FEATURE_WLAN_TDLS
6133 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6134 sme_IsFeatureSupportedByFW(TDLS)) {
6135 hddLog(LOG1, FL("TDLS is supported by firmware"));
6136 fset |= WIFI_FEATURE_TDLS;
6137 }
6138
6139 /* TDLS_OFFCHANNEL is not supported currently by default */
6140#endif
6141
6142#ifdef WLAN_AP_STA_CONCURRENCY
6143 /* AP+STA concurrency is supported currently by default */
6144 fset |= WIFI_FEATURE_AP_STA;
6145#endif
6146
Mukul Sharma5add0532015-08-17 15:57:47 +05306147#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306148 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6149 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306150 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6151 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306152 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306153#endif
6154
Dasari Srinivas7875a302014-09-26 17:50:57 +05306155 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6156 NLMSG_HDRLEN);
6157
6158 if (!skb) {
6159 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6160 return -EINVAL;
6161 }
6162 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6163
6164 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6165 hddLog(LOGE, FL("nla put fail"));
6166 goto nla_put_failure;
6167 }
6168
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306169 ret = cfg80211_vendor_cmd_reply(skb);
6170 EXIT();
6171 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306172
6173nla_put_failure:
6174 kfree_skb(skb);
6175 return -EINVAL;
6176}
6177
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306178static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306179wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6180 struct wireless_dev *wdev,
6181 const void *data, int data_len)
6182{
6183 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306184 vos_ssr_protect(__func__);
6185 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6186 vos_ssr_unprotect(__func__);
6187
6188 return ret;
6189}
6190
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306191
6192static const struct
6193nla_policy
6194qca_wlan_vendor_wifi_logger_get_ring_data_policy
6195[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6196 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6197 = {.type = NLA_U32 },
6198};
6199
6200static int
6201 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6202 struct wireless_dev *wdev,
6203 const void *data,
6204 int data_len)
6205{
6206 int ret;
6207 VOS_STATUS status;
6208 uint32_t ring_id;
6209 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6210 struct nlattr *tb
6211 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6212
6213 ENTER();
6214
6215 ret = wlan_hdd_validate_context(hdd_ctx);
6216 if (0 != ret) {
6217 return ret;
6218 }
6219
6220 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6221 data, data_len,
6222 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6223 hddLog(LOGE, FL("Invalid attribute"));
6224 return -EINVAL;
6225 }
6226
6227 /* Parse and fetch ring id */
6228 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6229 hddLog(LOGE, FL("attr ATTR failed"));
6230 return -EINVAL;
6231 }
6232
6233 ring_id = nla_get_u32(
6234 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6235
6236 hddLog(LOG1, FL("Bug report triggered by framework"));
6237
6238 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6239 WLAN_LOG_INDICATOR_FRAMEWORK,
6240 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306241 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306242 );
6243 if (VOS_STATUS_SUCCESS != status) {
6244 hddLog(LOGE, FL("Failed to trigger bug report"));
6245
6246 return -EINVAL;
6247 }
6248
6249 return 0;
6250
6251
6252}
6253
6254
6255static int
6256 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6257 struct wireless_dev *wdev,
6258 const void *data,
6259 int data_len)
6260{
6261 int ret = 0;
6262
6263 vos_ssr_protect(__func__);
6264 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6265 wdev, data, data_len);
6266 vos_ssr_unprotect(__func__);
6267
6268 return ret;
6269
6270}
6271
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306272#define MAX_CONCURRENT_MATRIX \
6273 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6274#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6275 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6276static const struct nla_policy
6277wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6278 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6279};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306280
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306281static int
6282__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306283 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306284 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306285{
6286 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6287 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306288 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306289 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306290 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6291 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306292
6293 ENTER();
6294
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306295 ret = wlan_hdd_validate_context(pHddCtx);
6296 if (0 != ret)
6297 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306298 return ret;
6299 }
6300
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306301 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6302 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306303 hddLog(LOGE, FL("Invalid ATTR"));
6304 return -EINVAL;
6305 }
6306
6307 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306308 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306309 hddLog(LOGE, FL("Attr max feature set size failed"));
6310 return -EINVAL;
6311 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306312 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306313 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6314
6315 /* Fill feature combination matrix */
6316 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306317 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6318 WIFI_FEATURE_P2P;
6319
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306320 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6321 WIFI_FEATURE_SOFT_AP;
6322
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306323 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6324 WIFI_FEATURE_SOFT_AP;
6325
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306326 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6327 WIFI_FEATURE_SOFT_AP |
6328 WIFI_FEATURE_P2P;
6329
6330 /* Add more feature combinations here */
6331
6332 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6333 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6334 hddLog(LOG1, "Feature set matrix");
6335 for (i = 0; i < feature_sets; i++)
6336 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6337
6338 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6339 sizeof(u32) * feature_sets +
6340 NLMSG_HDRLEN);
6341
6342 if (reply_skb) {
6343 if (nla_put_u32(reply_skb,
6344 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6345 feature_sets) ||
6346 nla_put(reply_skb,
6347 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6348 sizeof(u32) * feature_sets, feature_set_matrix)) {
6349 hddLog(LOGE, FL("nla put fail"));
6350 kfree_skb(reply_skb);
6351 return -EINVAL;
6352 }
6353
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306354 ret = cfg80211_vendor_cmd_reply(reply_skb);
6355 EXIT();
6356 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306357 }
6358 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6359 return -ENOMEM;
6360
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306361}
6362
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306363#undef MAX_CONCURRENT_MATRIX
6364#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6365
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306366static int
6367wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6368 struct wireless_dev *wdev,
6369 const void *data, int data_len)
6370{
6371 int ret = 0;
6372
6373 vos_ssr_protect(__func__);
6374 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6375 data_len);
6376 vos_ssr_unprotect(__func__);
6377
6378 return ret;
6379}
6380
c_manjeecfd1efb2015-09-25 19:32:34 +05306381
6382static int
6383__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6384 struct wireless_dev *wdev,
6385 const void *data, int data_len)
6386{
6387 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6388 int ret;
6389 ENTER();
6390
6391 ret = wlan_hdd_validate_context(pHddCtx);
6392 if (0 != ret)
6393 {
6394 return ret;
6395 }
6396
6397 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6398 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6399 {
6400 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306401 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306402 }
6403 /*call common API for FW mem dump req*/
6404 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6405
Abhishek Singhc783fa72015-12-09 18:07:34 +05306406 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306407 {
6408 /*indicate to userspace the status of fw mem dump */
6409 wlan_indicate_mem_dump_complete(true);
6410 }
6411 else
6412 {
6413 /*else send failure to userspace */
6414 wlan_indicate_mem_dump_complete(false);
6415 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306416 EXIT();
6417 return ret;
6418}
6419
6420/**
6421 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6422 * @wiphy: pointer to wireless wiphy structure.
6423 * @wdev: pointer to wireless_dev structure.
6424 * @data: Pointer to the NL data.
6425 * @data_len:Length of @data
6426 *
6427 * This is called when wlan driver needs to get the firmware memory dump
6428 * via vendor specific command.
6429 *
6430 * Return: 0 on success, error number otherwise.
6431 */
6432
6433static int
6434wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6435 struct wireless_dev *wdev,
6436 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306437{
6438 int ret = 0;
6439 vos_ssr_protect(__func__);
6440 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6441 data_len);
6442 vos_ssr_unprotect(__func__);
6443 return ret;
6444}
c_manjeecfd1efb2015-09-25 19:32:34 +05306445
Sushant Kaushik8e644982015-09-23 12:18:54 +05306446static const struct
6447nla_policy
6448qca_wlan_vendor_wifi_logger_start_policy
6449[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6450 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6451 = {.type = NLA_U32 },
6452 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6453 = {.type = NLA_U32 },
6454 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6455 = {.type = NLA_U32 },
6456};
6457
6458/**
6459 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6460 * or disable the collection of packet statistics from the firmware
6461 * @wiphy: WIPHY structure pointer
6462 * @wdev: Wireless device structure pointer
6463 * @data: Pointer to the data received
6464 * @data_len: Length of the data received
6465 *
6466 * This function is used to enable or disable the collection of packet
6467 * statistics from the firmware
6468 *
6469 * Return: 0 on success and errno on failure
6470 */
6471static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6472 struct wireless_dev *wdev,
6473 const void *data,
6474 int data_len)
6475{
6476 eHalStatus status;
6477 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6478 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6479 tAniWifiStartLog start_log;
6480
6481 status = wlan_hdd_validate_context(hdd_ctx);
6482 if (0 != status) {
6483 return -EINVAL;
6484 }
6485
6486 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6487 data, data_len,
6488 qca_wlan_vendor_wifi_logger_start_policy)) {
6489 hddLog(LOGE, FL("Invalid attribute"));
6490 return -EINVAL;
6491 }
6492
6493 /* Parse and fetch ring id */
6494 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6495 hddLog(LOGE, FL("attr ATTR failed"));
6496 return -EINVAL;
6497 }
6498 start_log.ringId = nla_get_u32(
6499 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6500 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6501
6502 /* Parse and fetch verbose level */
6503 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6504 hddLog(LOGE, FL("attr verbose_level failed"));
6505 return -EINVAL;
6506 }
6507 start_log.verboseLevel = nla_get_u32(
6508 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6509 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6510
6511 /* Parse and fetch flag */
6512 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6513 hddLog(LOGE, FL("attr flag failed"));
6514 return -EINVAL;
6515 }
6516 start_log.flag = nla_get_u32(
6517 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6518 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6519
6520 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306521 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6522 !vos_isPktStatsEnabled()))
6523
Sushant Kaushik8e644982015-09-23 12:18:54 +05306524 {
6525 hddLog(LOGE, FL("per pkt stats not enabled"));
6526 return -EINVAL;
6527 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306528
Sushant Kaushik33200572015-08-05 16:46:20 +05306529 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306530 return 0;
6531}
6532
6533/**
6534 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6535 * or disable the collection of packet statistics from the firmware
6536 * @wiphy: WIPHY structure pointer
6537 * @wdev: Wireless device structure pointer
6538 * @data: Pointer to the data received
6539 * @data_len: Length of the data received
6540 *
6541 * This function is used to enable or disable the collection of packet
6542 * statistics from the firmware
6543 *
6544 * Return: 0 on success and errno on failure
6545 */
6546static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6547 struct wireless_dev *wdev,
6548 const void *data,
6549 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306550{
6551 int ret = 0;
6552
6553 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306554
6555 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6556 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306557 vos_ssr_unprotect(__func__);
6558
6559 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306560}
6561
6562
Agarwal Ashish738843c2014-09-25 12:27:56 +05306563static const struct nla_policy
6564wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6565 +1] =
6566{
6567 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6568};
6569
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306570static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306571 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306572 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306573 int data_len)
6574{
6575 struct net_device *dev = wdev->netdev;
6576 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6577 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6578 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6579 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6580 eHalStatus status;
6581 u32 dfsFlag = 0;
6582
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306583 ENTER();
6584
Agarwal Ashish738843c2014-09-25 12:27:56 +05306585 status = wlan_hdd_validate_context(pHddCtx);
6586 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306587 return -EINVAL;
6588 }
6589 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6590 data, data_len,
6591 wlan_hdd_set_no_dfs_flag_config_policy)) {
6592 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6593 return -EINVAL;
6594 }
6595
6596 /* Parse and fetch required bandwidth kbps */
6597 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6598 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6599 return -EINVAL;
6600 }
6601
6602 dfsFlag = nla_get_u32(
6603 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6604 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6605 dfsFlag);
6606
6607 pHddCtx->disable_dfs_flag = dfsFlag;
6608
6609 sme_disable_dfs_channel(hHal, dfsFlag);
6610 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306611
6612 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306613 return 0;
6614}
Atul Mittal115287b2014-07-08 13:26:33 +05306615
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306616static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6617 struct wireless_dev *wdev,
6618 const void *data,
6619 int data_len)
6620{
6621 int ret = 0;
6622
6623 vos_ssr_protect(__func__);
6624 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6625 vos_ssr_unprotect(__func__);
6626
6627 return ret;
6628
6629}
6630
Mukul Sharma2a271632014-10-13 14:59:01 +05306631const struct
6632nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6633{
6634 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306635 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6636 .type = NLA_UNSPEC,
6637 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306638};
6639
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306640static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306641 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306642{
6643
6644 u8 bssid[6] = {0};
6645 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6646 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6647 eHalStatus status = eHAL_STATUS_SUCCESS;
6648 v_U32_t isFwrRoamEnabled = FALSE;
6649 int ret;
6650
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306651 ENTER();
6652
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306653 ret = wlan_hdd_validate_context(pHddCtx);
6654 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306655 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306656 }
6657
6658 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6659 data, data_len,
6660 qca_wlan_vendor_attr);
6661 if (ret){
6662 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6663 return -EINVAL;
6664 }
6665
6666 /* Parse and fetch Enable flag */
6667 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6668 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6669 return -EINVAL;
6670 }
6671
6672 isFwrRoamEnabled = nla_get_u32(
6673 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6674
6675 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6676
6677 /* Parse and fetch bssid */
6678 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6680 return -EINVAL;
6681 }
6682
6683 memcpy(bssid, nla_data(
6684 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6685 sizeof(bssid));
6686 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6687
6688 //Update roaming
6689 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306690 if (!HAL_STATUS_SUCCESS(status)) {
6691 hddLog(LOGE,
6692 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6693 return -EINVAL;
6694 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306695 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306696 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306697}
6698
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306699static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6700 struct wireless_dev *wdev, const void *data, int data_len)
6701{
6702 int ret = 0;
6703
6704 vos_ssr_protect(__func__);
6705 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6706 vos_ssr_unprotect(__func__);
6707
6708 return ret;
6709}
6710
Sushant Kaushik847890c2015-09-28 16:05:17 +05306711static const struct
6712nla_policy
6713qca_wlan_vendor_get_wifi_info_policy[
6714 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6715 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6716 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6717};
6718
6719
6720/**
6721 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6722 * @wiphy: pointer to wireless wiphy structure.
6723 * @wdev: pointer to wireless_dev structure.
6724 * @data: Pointer to the data to be passed via vendor interface
6725 * @data_len:Length of the data to be passed
6726 *
6727 * This is called when wlan driver needs to send wifi driver related info
6728 * (driver/fw version) to the user space application upon request.
6729 *
6730 * Return: Return the Success or Failure code.
6731 */
6732static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6733 struct wireless_dev *wdev,
6734 const void *data, int data_len)
6735{
6736 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6737 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6738 tSirVersionString version;
6739 uint32 version_len;
6740 uint8 attr;
6741 int status;
6742 struct sk_buff *reply_skb = NULL;
6743
6744 if (VOS_FTM_MODE == hdd_get_conparam()) {
6745 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6746 return -EINVAL;
6747 }
6748
6749 status = wlan_hdd_validate_context(hdd_ctx);
6750 if (0 != status) {
6751 hddLog(LOGE, FL("HDD context is not valid"));
6752 return -EINVAL;
6753 }
6754
6755 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6756 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6757 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6758 return -EINVAL;
6759 }
6760
6761 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6762 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6763 QWLAN_VERSIONSTR);
6764 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6765 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6766 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6767 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6768 hdd_ctx->fw_Version);
6769 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6770 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6771 } else {
6772 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6773 return -EINVAL;
6774 }
6775
6776 version_len = strlen(version);
6777 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6778 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6779 if (!reply_skb) {
6780 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6781 return -ENOMEM;
6782 }
6783
6784 if (nla_put(reply_skb, attr, version_len, version)) {
6785 hddLog(LOGE, FL("nla put fail"));
6786 kfree_skb(reply_skb);
6787 return -EINVAL;
6788 }
6789
6790 return cfg80211_vendor_cmd_reply(reply_skb);
6791}
6792
6793/**
6794 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6795 * @wiphy: pointer to wireless wiphy structure.
6796 * @wdev: pointer to wireless_dev structure.
6797 * @data: Pointer to the data to be passed via vendor interface
6798 * @data_len:Length of the data to be passed
6799 * @data_len: Length of the data received
6800 *
6801 * This function is used to enable or disable the collection of packet
6802 * statistics from the firmware
6803 *
6804 * Return: 0 on success and errno on failure
6805 */
6806
6807static int
6808wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6809 struct wireless_dev *wdev,
6810 const void *data, int data_len)
6811
6812
6813{
6814 int ret = 0;
6815
6816 vos_ssr_protect(__func__);
6817 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6818 wdev, data, data_len);
6819 vos_ssr_unprotect(__func__);
6820
6821 return ret;
6822}
6823
6824
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306825/*
6826 * define short names for the global vendor params
6827 * used by __wlan_hdd_cfg80211_monitor_rssi()
6828 */
6829#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6830#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6831#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6832#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6833#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6834
6835/**---------------------------------------------------------------------------
6836
6837 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6838 monitor start is completed successfully.
6839
6840 \return - None
6841
6842 --------------------------------------------------------------------------*/
6843void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6844{
6845 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6846
6847 if (NULL == pHddCtx)
6848 {
6849 hddLog(VOS_TRACE_LEVEL_ERROR,
6850 "%s: HDD context is NULL",__func__);
6851 return;
6852 }
6853
6854 if (VOS_STATUS_SUCCESS == status)
6855 {
6856 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6857 }
6858 else
6859 {
6860 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6861 }
6862
6863 return;
6864}
6865
6866/**---------------------------------------------------------------------------
6867
6868 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6869 stop is completed successfully.
6870
6871 \return - None
6872
6873 --------------------------------------------------------------------------*/
6874void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6875{
6876 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6877
6878 if (NULL == pHddCtx)
6879 {
6880 hddLog(VOS_TRACE_LEVEL_ERROR,
6881 "%s: HDD context is NULL",__func__);
6882 return;
6883 }
6884
6885 if (VOS_STATUS_SUCCESS == status)
6886 {
6887 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6888 }
6889 else
6890 {
6891 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6892 }
6893
6894 return;
6895}
6896
6897/**
6898 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6899 * @wiphy: Pointer to wireless phy
6900 * @wdev: Pointer to wireless device
6901 * @data: Pointer to data
6902 * @data_len: Data length
6903 *
6904 * Return: 0 on success, negative errno on failure
6905 */
6906
6907static int
6908__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6909 struct wireless_dev *wdev,
6910 const void *data,
6911 int data_len)
6912{
6913 struct net_device *dev = wdev->netdev;
6914 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6915 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6916 hdd_station_ctx_t *pHddStaCtx;
6917 struct nlattr *tb[PARAM_MAX + 1];
6918 tpSirRssiMonitorReq pReq;
6919 eHalStatus status;
6920 int ret;
6921 uint32_t control;
6922 static const struct nla_policy policy[PARAM_MAX + 1] = {
6923 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6924 [PARAM_CONTROL] = { .type = NLA_U32 },
6925 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6926 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6927 };
6928
6929 ENTER();
6930
6931 ret = wlan_hdd_validate_context(hdd_ctx);
6932 if (0 != ret) {
6933 return -EINVAL;
6934 }
6935
6936 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6937 hddLog(LOGE, FL("Not in Connected state!"));
6938 return -ENOTSUPP;
6939 }
6940
6941 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6942 hddLog(LOGE, FL("Invalid ATTR"));
6943 return -EINVAL;
6944 }
6945
6946 if (!tb[PARAM_REQUEST_ID]) {
6947 hddLog(LOGE, FL("attr request id failed"));
6948 return -EINVAL;
6949 }
6950
6951 if (!tb[PARAM_CONTROL]) {
6952 hddLog(LOGE, FL("attr control failed"));
6953 return -EINVAL;
6954 }
6955
6956 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6957
6958 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6959 if(NULL == pReq)
6960 {
6961 hddLog(LOGE,
6962 FL("vos_mem_alloc failed "));
6963 return eHAL_STATUS_FAILED_ALLOC;
6964 }
6965 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6966
6967 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6968 pReq->sessionId = pAdapter->sessionId;
6969 pReq->rssiMonitorCbContext = hdd_ctx;
6970 control = nla_get_u32(tb[PARAM_CONTROL]);
6971 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6972
6973 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6974 pReq->requestId, pReq->sessionId, control);
6975
6976 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6977 if (!tb[PARAM_MIN_RSSI]) {
6978 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306979 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306980 }
6981
6982 if (!tb[PARAM_MAX_RSSI]) {
6983 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306984 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306985 }
6986
6987 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6988 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6989 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6990
6991 if (!(pReq->minRssi < pReq->maxRssi)) {
6992 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6993 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306994 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306995 }
6996 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6997 pReq->minRssi, pReq->maxRssi);
6998 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6999
7000 }
7001 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
7002 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
7003 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
7004 }
7005 else {
7006 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307007 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307008 }
7009
7010 if (!HAL_STATUS_SUCCESS(status)) {
7011 hddLog(LOGE,
7012 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307013 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307014 }
7015
7016 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307017fail:
7018 vos_mem_free(pReq);
7019 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307020}
7021
7022/*
7023 * done with short names for the global vendor params
7024 * used by __wlan_hdd_cfg80211_monitor_rssi()
7025 */
7026#undef PARAM_MAX
7027#undef PARAM_CONTROL
7028#undef PARAM_REQUEST_ID
7029#undef PARAM_MAX_RSSI
7030#undef PARAM_MIN_RSSI
7031
7032/**
7033 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
7034 * @wiphy: wiphy structure pointer
7035 * @wdev: Wireless device structure pointer
7036 * @data: Pointer to the data received
7037 * @data_len: Length of @data
7038 *
7039 * Return: 0 on success; errno on failure
7040 */
7041static int
7042wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
7043 const void *data, int data_len)
7044{
7045 int ret;
7046
7047 vos_ssr_protect(__func__);
7048 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
7049 vos_ssr_unprotect(__func__);
7050
7051 return ret;
7052}
7053
7054/**
7055 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
7056 * @hddctx: HDD context
7057 * @data: rssi breached event data
7058 *
7059 * This function reads the rssi breached event %data and fill in the skb with
7060 * NL attributes and send up the NL event.
7061 * This callback execute in atomic context and must not invoke any
7062 * blocking calls.
7063 *
7064 * Return: none
7065 */
7066void hdd_rssi_threshold_breached_cb(void *hddctx,
7067 struct rssi_breach_event *data)
7068{
7069 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
7070 int status;
7071 struct sk_buff *skb;
7072
7073 ENTER();
7074 status = wlan_hdd_validate_context(pHddCtx);
7075
7076 if (0 != status) {
7077 return;
7078 }
7079
7080 if (!data) {
7081 hddLog(LOGE, FL("data is null"));
7082 return;
7083 }
7084
7085 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
7086#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7087 NULL,
7088#endif
7089 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
7090 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
7091 GFP_KERNEL);
7092
7093 if (!skb) {
7094 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
7095 return;
7096 }
7097
7098 hddLog(LOG1, "Req Id: %u Current rssi: %d",
7099 data->request_id, data->curr_rssi);
7100 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
7101 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
7102
7103 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
7104 data->request_id) ||
7105 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
7106 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
7107 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
7108 data->curr_rssi)) {
7109 hddLog(LOGE, FL("nla put fail"));
7110 goto fail;
7111 }
7112
7113 cfg80211_vendor_event(skb, GFP_KERNEL);
7114 return;
7115
7116fail:
7117 kfree_skb(skb);
7118 return;
7119}
7120
7121
7122
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307123/**
7124 * __wlan_hdd_cfg80211_setband() - set band
7125 * @wiphy: Pointer to wireless phy
7126 * @wdev: Pointer to wireless device
7127 * @data: Pointer to data
7128 * @data_len: Data length
7129 *
7130 * Return: 0 on success, negative errno on failure
7131 */
7132static int
7133__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7134 struct wireless_dev *wdev,
7135 const void *data,
7136 int data_len)
7137{
7138 struct net_device *dev = wdev->netdev;
7139 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7140 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7141 int ret;
7142 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7143 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7144
7145 ENTER();
7146
7147 ret = wlan_hdd_validate_context(hdd_ctx);
7148 if (0 != ret) {
7149 hddLog(LOGE, FL("HDD context is not valid"));
7150 return ret;
7151 }
7152
7153 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7154 policy)) {
7155 hddLog(LOGE, FL("Invalid ATTR"));
7156 return -EINVAL;
7157 }
7158
7159 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7160 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7161 return -EINVAL;
7162 }
7163
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307164 hdd_ctx->isSetBandByNL = TRUE;
7165 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307166 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307167 hdd_ctx->isSetBandByNL = FALSE;
7168
7169 EXIT();
7170 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307171}
7172
7173/**
7174 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7175 * @wiphy: wiphy structure pointer
7176 * @wdev: Wireless device structure pointer
7177 * @data: Pointer to the data received
7178 * @data_len: Length of @data
7179 *
7180 * Return: 0 on success; errno on failure
7181 */
7182static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7183 struct wireless_dev *wdev,
7184 const void *data,
7185 int data_len)
7186{
7187 int ret = 0;
7188
7189 vos_ssr_protect(__func__);
7190 ret = __wlan_hdd_cfg80211_setband(wiphy,
7191 wdev, data, data_len);
7192 vos_ssr_unprotect(__func__);
7193
7194 return ret;
7195}
7196
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307197#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7198/**
7199 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7200 * @hdd_ctx: HDD context
7201 * @request_id: [input] request id
7202 * @pattern_id: [output] pattern id
7203 *
7204 * This function loops through request id to pattern id array
7205 * if the slot is available, store the request id and return pattern id
7206 * if entry exists, return the pattern id
7207 *
7208 * Return: 0 on success and errno on failure
7209 */
7210static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7211 uint32_t request_id,
7212 uint8_t *pattern_id)
7213{
7214 uint32_t i;
7215
7216 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7217 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7218 {
7219 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7220 {
7221 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7222 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7223 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7224 return 0;
7225 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7226 request_id) {
7227 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7228 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7229 return 0;
7230 }
7231 }
7232 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7233 return -EINVAL;
7234}
7235
7236/**
7237 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7238 * @hdd_ctx: HDD context
7239 * @request_id: [input] request id
7240 * @pattern_id: [output] pattern id
7241 *
7242 * This function loops through request id to pattern id array
7243 * reset request id to 0 (slot available again) and
7244 * return pattern id
7245 *
7246 * Return: 0 on success and errno on failure
7247 */
7248static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7249 uint32_t request_id,
7250 uint8_t *pattern_id)
7251{
7252 uint32_t i;
7253
7254 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7255 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7256 {
7257 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7258 {
7259 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7260 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7261 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7262 return 0;
7263 }
7264 }
7265 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7266 return -EINVAL;
7267}
7268
7269
7270/*
7271 * define short names for the global vendor params
7272 * used by __wlan_hdd_cfg80211_offloaded_packets()
7273 */
7274#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7275#define PARAM_REQUEST_ID \
7276 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7277#define PARAM_CONTROL \
7278 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7279#define PARAM_IP_PACKET \
7280 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7281#define PARAM_SRC_MAC_ADDR \
7282 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7283#define PARAM_DST_MAC_ADDR \
7284 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7285#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7286
7287/**
7288 * wlan_hdd_add_tx_ptrn() - add tx pattern
7289 * @adapter: adapter pointer
7290 * @hdd_ctx: hdd context
7291 * @tb: nl attributes
7292 *
7293 * This function reads the NL attributes and forms a AddTxPtrn message
7294 * posts it to SME.
7295 *
7296 */
7297static int
7298wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7299 struct nlattr **tb)
7300{
7301 struct sSirAddPeriodicTxPtrn *add_req;
7302 eHalStatus status;
7303 uint32_t request_id, ret, len;
7304 uint8_t pattern_id = 0;
7305 v_MACADDR_t dst_addr;
7306 uint16_t eth_type = htons(ETH_P_IP);
7307
7308 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7309 {
7310 hddLog(LOGE, FL("Not in Connected state!"));
7311 return -ENOTSUPP;
7312 }
7313
7314 add_req = vos_mem_malloc(sizeof(*add_req));
7315 if (!add_req)
7316 {
7317 hddLog(LOGE, FL("memory allocation failed"));
7318 return -ENOMEM;
7319 }
7320
7321 /* Parse and fetch request Id */
7322 if (!tb[PARAM_REQUEST_ID])
7323 {
7324 hddLog(LOGE, FL("attr request id failed"));
7325 goto fail;
7326 }
7327
7328 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7329 hddLog(LOG1, FL("Request Id: %u"), request_id);
7330 if (request_id == 0)
7331 {
7332 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307333 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307334 }
7335
7336 if (!tb[PARAM_PERIOD])
7337 {
7338 hddLog(LOGE, FL("attr period failed"));
7339 goto fail;
7340 }
7341 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7342 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7343 if (add_req->usPtrnIntervalMs == 0)
7344 {
7345 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7346 goto fail;
7347 }
7348
7349 if (!tb[PARAM_SRC_MAC_ADDR])
7350 {
7351 hddLog(LOGE, FL("attr source mac address failed"));
7352 goto fail;
7353 }
7354 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7355 VOS_MAC_ADDR_SIZE);
7356 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7357 MAC_ADDR_ARRAY(add_req->macAddress));
7358
7359 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7360 VOS_MAC_ADDR_SIZE))
7361 {
7362 hddLog(LOGE,
7363 FL("input src mac address and connected ap bssid are different"));
7364 goto fail;
7365 }
7366
7367 if (!tb[PARAM_DST_MAC_ADDR])
7368 {
7369 hddLog(LOGE, FL("attr dst mac address failed"));
7370 goto fail;
7371 }
7372 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7373 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7374 MAC_ADDR_ARRAY(dst_addr.bytes));
7375
7376 if (!tb[PARAM_IP_PACKET])
7377 {
7378 hddLog(LOGE, FL("attr ip packet failed"));
7379 goto fail;
7380 }
7381 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7382 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7383
7384 if (add_req->ucPtrnSize < 0 ||
7385 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7386 HDD_ETH_HEADER_LEN))
7387 {
7388 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7389 add_req->ucPtrnSize);
7390 goto fail;
7391 }
7392
7393 len = 0;
7394 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7395 len += VOS_MAC_ADDR_SIZE;
7396 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7397 VOS_MAC_ADDR_SIZE);
7398 len += VOS_MAC_ADDR_SIZE;
7399 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7400 len += 2;
7401
7402 /*
7403 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7404 * ------------------------------------------------------------
7405 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7406 * ------------------------------------------------------------
7407 */
7408 vos_mem_copy(&add_req->ucPattern[len],
7409 nla_data(tb[PARAM_IP_PACKET]),
7410 add_req->ucPtrnSize);
7411 add_req->ucPtrnSize += len;
7412
7413 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7414 add_req->ucPattern, add_req->ucPtrnSize);
7415
7416 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7417 if (ret)
7418 {
7419 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7420 goto fail;
7421 }
7422 add_req->ucPtrnId = pattern_id;
7423 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7424
7425 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7426 if (!HAL_STATUS_SUCCESS(status))
7427 {
7428 hddLog(LOGE,
7429 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7430 goto fail;
7431 }
7432
7433 EXIT();
7434 vos_mem_free(add_req);
7435 return 0;
7436
7437fail:
7438 vos_mem_free(add_req);
7439 return -EINVAL;
7440}
7441
7442/**
7443 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7444 * @adapter: adapter pointer
7445 * @hdd_ctx: hdd context
7446 * @tb: nl attributes
7447 *
7448 * This function reads the NL attributes and forms a DelTxPtrn message
7449 * posts it to SME.
7450 *
7451 */
7452static int
7453wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7454 struct nlattr **tb)
7455{
7456 struct sSirDelPeriodicTxPtrn *del_req;
7457 eHalStatus status;
7458 uint32_t request_id, ret;
7459 uint8_t pattern_id = 0;
7460
7461 /* Parse and fetch request Id */
7462 if (!tb[PARAM_REQUEST_ID])
7463 {
7464 hddLog(LOGE, FL("attr request id failed"));
7465 return -EINVAL;
7466 }
7467 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7468 if (request_id == 0)
7469 {
7470 hddLog(LOGE, FL("request_id cannot be zero"));
7471 return -EINVAL;
7472 }
7473
7474 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7475 if (ret)
7476 {
7477 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7478 return -EINVAL;
7479 }
7480
7481 del_req = vos_mem_malloc(sizeof(*del_req));
7482 if (!del_req)
7483 {
7484 hddLog(LOGE, FL("memory allocation failed"));
7485 return -ENOMEM;
7486 }
7487
7488 vos_mem_set(del_req, sizeof(*del_req), 0);
7489 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7490 VOS_MAC_ADDR_SIZE);
7491 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7492 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7493 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7494 request_id, pattern_id, del_req->ucPatternIdBitmap);
7495
7496 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7497 if (!HAL_STATUS_SUCCESS(status))
7498 {
7499 hddLog(LOGE,
7500 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7501 goto fail;
7502 }
7503
7504 EXIT();
7505 vos_mem_free(del_req);
7506 return 0;
7507
7508fail:
7509 vos_mem_free(del_req);
7510 return -EINVAL;
7511}
7512
7513
7514/**
7515 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7516 * @wiphy: Pointer to wireless phy
7517 * @wdev: Pointer to wireless device
7518 * @data: Pointer to data
7519 * @data_len: Data length
7520 *
7521 * Return: 0 on success, negative errno on failure
7522 */
7523static int
7524__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7525 struct wireless_dev *wdev,
7526 const void *data,
7527 int data_len)
7528{
7529 struct net_device *dev = wdev->netdev;
7530 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7531 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7532 struct nlattr *tb[PARAM_MAX + 1];
7533 uint8_t control;
7534 int ret;
7535 static const struct nla_policy policy[PARAM_MAX + 1] =
7536 {
7537 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7538 [PARAM_CONTROL] = { .type = NLA_U32 },
7539 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7540 .len = VOS_MAC_ADDR_SIZE },
7541 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7542 .len = VOS_MAC_ADDR_SIZE },
7543 [PARAM_PERIOD] = { .type = NLA_U32 },
7544 };
7545
7546 ENTER();
7547
7548 ret = wlan_hdd_validate_context(hdd_ctx);
7549 if (0 != ret)
7550 {
7551 hddLog(LOGE, FL("HDD context is not valid"));
7552 return ret;
7553 }
7554
7555 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7556 {
7557 hddLog(LOGE,
7558 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7559 return -ENOTSUPP;
7560 }
7561
7562 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7563 {
7564 hddLog(LOGE, FL("Invalid ATTR"));
7565 return -EINVAL;
7566 }
7567
7568 if (!tb[PARAM_CONTROL])
7569 {
7570 hddLog(LOGE, FL("attr control failed"));
7571 return -EINVAL;
7572 }
7573 control = nla_get_u32(tb[PARAM_CONTROL]);
7574 hddLog(LOG1, FL("Control: %d"), control);
7575
7576 if (control == WLAN_START_OFFLOADED_PACKETS)
7577 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7578 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7579 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7580 else
7581 {
7582 hddLog(LOGE, FL("Invalid control: %d"), control);
7583 return -EINVAL;
7584 }
7585}
7586
7587/*
7588 * done with short names for the global vendor params
7589 * used by __wlan_hdd_cfg80211_offloaded_packets()
7590 */
7591#undef PARAM_MAX
7592#undef PARAM_REQUEST_ID
7593#undef PARAM_CONTROL
7594#undef PARAM_IP_PACKET
7595#undef PARAM_SRC_MAC_ADDR
7596#undef PARAM_DST_MAC_ADDR
7597#undef PARAM_PERIOD
7598
7599/**
7600 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7601 * @wiphy: wiphy structure pointer
7602 * @wdev: Wireless device structure pointer
7603 * @data: Pointer to the data received
7604 * @data_len: Length of @data
7605 *
7606 * Return: 0 on success; errno on failure
7607 */
7608static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7609 struct wireless_dev *wdev,
7610 const void *data,
7611 int data_len)
7612{
7613 int ret = 0;
7614
7615 vos_ssr_protect(__func__);
7616 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7617 wdev, data, data_len);
7618 vos_ssr_unprotect(__func__);
7619
7620 return ret;
7621}
7622#endif
7623
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307624static const struct
7625nla_policy
7626qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307627 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7628 .type = NLA_BINARY,
7629 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307630};
7631
7632/**
7633 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7634 * get link properties like nss, rate flags and operating frequency for
7635 * the connection with the given peer.
7636 * @wiphy: WIPHY structure pointer
7637 * @wdev: Wireless device structure pointer
7638 * @data: Pointer to the data received
7639 * @data_len: Length of the data received
7640 *
7641 * This function return the above link properties on success.
7642 *
7643 * Return: 0 on success and errno on failure
7644 */
7645static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7646 struct wireless_dev *wdev,
7647 const void *data,
7648 int data_len)
7649{
7650 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7651 struct net_device *dev = wdev->netdev;
7652 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7653 hdd_station_ctx_t *hdd_sta_ctx;
7654 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7655 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7656 uint32_t sta_id;
7657 struct sk_buff *reply_skb;
7658 uint32_t rate_flags = 0;
7659 uint8_t nss;
7660 uint8_t final_rate_flags = 0;
7661 uint32_t freq;
7662 v_CONTEXT_t pVosContext = NULL;
7663 ptSapContext pSapCtx = NULL;
7664
7665 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7666 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7667 return -EINVAL;
7668 }
7669
7670 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7671 qca_wlan_vendor_attr_policy)) {
7672 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7673 return -EINVAL;
7674 }
7675
7676 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7677 hddLog(VOS_TRACE_LEVEL_ERROR,
7678 FL("Attribute peerMac not provided for mode=%d"),
7679 adapter->device_mode);
7680 return -EINVAL;
7681 }
7682
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307683 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7684 hddLog(VOS_TRACE_LEVEL_ERROR,
7685 FL("Attribute peerMac is invalid=%d"),
7686 adapter->device_mode);
7687 return -EINVAL;
7688 }
7689
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307690 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7691 sizeof(peer_mac));
7692 hddLog(VOS_TRACE_LEVEL_INFO,
7693 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7694 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7695
7696 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7697 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7698 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7699 if ((hdd_sta_ctx->conn_info.connState !=
7700 eConnectionState_Associated) ||
7701 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7702 VOS_MAC_ADDRESS_LEN)) {
7703 hddLog(VOS_TRACE_LEVEL_ERROR,
7704 FL("Not Associated to mac "MAC_ADDRESS_STR),
7705 MAC_ADDR_ARRAY(peer_mac));
7706 return -EINVAL;
7707 }
7708
7709 nss = 1; //pronto supports only one spatial stream
7710 freq = vos_chan_to_freq(
7711 hdd_sta_ctx->conn_info.operationChannel);
7712 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7713
7714 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7715 adapter->device_mode == WLAN_HDD_SOFTAP) {
7716
7717 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7718 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7719 if(pSapCtx == NULL){
7720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7721 FL("psapCtx is NULL"));
7722 return -ENOENT;
7723 }
7724
7725
7726 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7727 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7728 !vos_is_macaddr_broadcast(
7729 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7730 vos_mem_compare(
7731 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7732 peer_mac, VOS_MAC_ADDRESS_LEN))
7733 break;
7734 }
7735
7736 if (WLAN_MAX_STA_COUNT == sta_id) {
7737 hddLog(VOS_TRACE_LEVEL_ERROR,
7738 FL("No active peer with mac="MAC_ADDRESS_STR),
7739 MAC_ADDR_ARRAY(peer_mac));
7740 return -EINVAL;
7741 }
7742
7743 nss = 1; //pronto supports only one spatial stream
7744 freq = vos_chan_to_freq(
7745 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7746 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7747 } else {
7748 hddLog(VOS_TRACE_LEVEL_ERROR,
7749 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7750 MAC_ADDR_ARRAY(peer_mac));
7751 return -EINVAL;
7752 }
7753
7754 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7755 if (rate_flags & eHAL_TX_RATE_VHT80) {
7756 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307757#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7758 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307759 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307760#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307761 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7762 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307763#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7764 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307765 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307766#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307767 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7768 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7769 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7770 final_rate_flags |= RATE_INFO_FLAGS_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307771#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7772 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307773 if (rate_flags & eHAL_TX_RATE_HT40)
7774 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307775#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307776 }
7777
7778 if (rate_flags & eHAL_TX_RATE_SGI) {
7779 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7780 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7781 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7782 }
7783 }
7784
7785 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7786 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7787
7788 if (NULL == reply_skb) {
7789 hddLog(VOS_TRACE_LEVEL_ERROR,
7790 FL("getLinkProperties: skb alloc failed"));
7791 return -EINVAL;
7792 }
7793
7794 if (nla_put_u8(reply_skb,
7795 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7796 nss) ||
7797 nla_put_u8(reply_skb,
7798 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7799 final_rate_flags) ||
7800 nla_put_u32(reply_skb,
7801 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7802 freq)) {
7803 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7804 kfree_skb(reply_skb);
7805 return -EINVAL;
7806 }
7807
7808 return cfg80211_vendor_cmd_reply(reply_skb);
7809}
7810
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307811#define BEACON_MISS_THRESH_2_4 \
7812 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7813#define BEACON_MISS_THRESH_5_0 \
7814 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307815#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7816#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7817#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7818#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307819#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7820 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307821
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307822/*
7823 * hdd_set_qpower() - Process the qpower command and invoke the SME api
7824 * @hdd_ctx: hdd context
7825 * @enable: Value received in the command, 1 for disable and 2 for enable
7826 *
7827 * Return: void
7828 */
7829static void hdd_set_qpower(hdd_context_t *hdd_ctx, uint8_t enable)
7830{
7831 if (!hdd_ctx) {
7832 hddLog(LOGE, "hdd_ctx NULL");
7833 return;
7834 }
7835
7836 sme_set_qpower(hdd_ctx->hHal, enable);
7837}
7838
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307839/**
7840 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7841 * vendor command
7842 *
7843 * @wiphy: wiphy device pointer
7844 * @wdev: wireless device pointer
7845 * @data: Vendor command data buffer
7846 * @data_len: Buffer length
7847 *
7848 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7849 *
7850 * Return: EOK or other error codes.
7851 */
7852
7853static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7854 struct wireless_dev *wdev,
7855 const void *data,
7856 int data_len)
7857{
7858 struct net_device *dev = wdev->netdev;
7859 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7860 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7861 hdd_station_ctx_t *pHddStaCtx;
7862 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7863 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307864 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307865 eHalStatus status;
7866 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307867 uint8_t hb_thresh_val;
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307868 uint8_t qpower;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307869
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307870 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7871 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7872 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307873 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7874 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7875 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307876 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7877 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307878 };
7879
7880 ENTER();
7881
7882 if (VOS_FTM_MODE == hdd_get_conparam()) {
7883 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7884 return -EINVAL;
7885 }
7886
7887 ret_val = wlan_hdd_validate_context(pHddCtx);
7888 if (ret_val) {
7889 return ret_val;
7890 }
7891
7892 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7893
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307894 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7895 hddLog(LOGE, FL("Invalid ATTR"));
7896 return -EINVAL;
7897 }
7898
7899 /* check the Wifi Capability */
7900 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7901 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7902 {
7903 hddLog(VOS_TRACE_LEVEL_ERROR,
7904 FL("WIFICONFIG not supported by Firmware"));
7905 return -EINVAL;
7906 }
7907
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307908 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7909 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7910 modifyRoamParamsReq.value =
7911 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7912
7913 if (eHAL_STATUS_SUCCESS !=
7914 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7915 {
7916 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7917 ret_val = -EINVAL;
7918 }
7919 return ret_val;
7920 }
7921
7922 /* Moved this down in order to provide provision to set beacon
7923 * miss penalty count irrespective of connection state.
7924 */
7925 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7926 hddLog(LOGE, FL("Not in Connected state!"));
7927 return -ENOTSUPP;
7928 }
7929
7930 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307931
7932 if (!pReq) {
7933 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7934 "%s: Not able to allocate memory for tSetWifiConfigParams",
7935 __func__);
7936 return eHAL_STATUS_E_MALLOC_FAILED;
7937 }
7938
7939 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7940
7941 pReq->sessionId = pAdapter->sessionId;
7942 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7943
7944 if (tb[PARAM_MODULATED_DTIM]) {
7945 pReq->paramValue = nla_get_u32(
7946 tb[PARAM_MODULATED_DTIM]);
7947 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7948 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307949 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307950 hdd_set_pwrparams(pHddCtx);
7951 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7952 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7953
7954 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7955 iw_full_power_cbfn, pAdapter,
7956 eSME_FULL_PWR_NEEDED_BY_HDD);
7957 }
7958 else
7959 {
7960 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7961 }
7962 }
7963
7964 if (tb[PARAM_STATS_AVG_FACTOR]) {
7965 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7966 pReq->paramValue = nla_get_u16(
7967 tb[PARAM_STATS_AVG_FACTOR]);
7968 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7969 pReq->paramType, pReq->paramValue);
7970 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7971
7972 if (eHAL_STATUS_SUCCESS != status)
7973 {
7974 vos_mem_free(pReq);
7975 pReq = NULL;
7976 ret_val = -EPERM;
7977 return ret_val;
7978 }
7979 }
7980
7981
7982 if (tb[PARAM_GUARD_TIME]) {
7983 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7984 pReq->paramValue = nla_get_u32(
7985 tb[PARAM_GUARD_TIME]);
7986 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7987 pReq->paramType, pReq->paramValue);
7988 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7989
7990 if (eHAL_STATUS_SUCCESS != status)
7991 {
7992 vos_mem_free(pReq);
7993 pReq = NULL;
7994 ret_val = -EPERM;
7995 return ret_val;
7996 }
7997
7998 }
7999
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05308000 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
8001 hb_thresh_val = nla_get_u8(
8002 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
8003
8004 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
8005 hb_thresh_val);
8006 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
8007 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
8008 NULL, eANI_BOOLEAN_FALSE);
8009
8010 status = sme_update_hb_threshold(
8011 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
8012 WNI_CFG_HEART_BEAT_THRESHOLD,
8013 hb_thresh_val, eCSR_BAND_24);
8014 if (eHAL_STATUS_SUCCESS != status) {
8015 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
8016 vos_mem_free(pReq);
8017 pReq = NULL;
8018 return -EPERM;
8019 }
8020 }
8021
8022 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
8023 hb_thresh_val = nla_get_u8(
8024 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
8025
8026 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
8027 hb_thresh_val);
8028 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
8029 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
8030 NULL, eANI_BOOLEAN_FALSE);
8031
8032 status = sme_update_hb_threshold(
8033 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
8034 WNI_CFG_HEART_BEAT_THRESHOLD,
8035 hb_thresh_val, eCSR_BAND_5G);
8036 if (eHAL_STATUS_SUCCESS != status) {
8037 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
8038 vos_mem_free(pReq);
8039 pReq = NULL;
8040 return -EPERM;
8041 }
8042 }
8043
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05308044 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]) {
8045 qpower = nla_get_u8(
8046 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]);
8047
8048 if(qpower > 1) {
8049 hddLog(LOGE, "Invalid QPOWER value %d", qpower);
8050 vos_mem_free(pReq);
8051 pReq = NULL;
8052 return -EINVAL;
8053 }
8054 /* FW is expacting qpower as 1 for Disable and 2 for enable */
8055 qpower++;
8056 hdd_set_qpower(pHddCtx, qpower);
8057 }
8058
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308059 EXIT();
8060 return ret_val;
8061}
8062
8063/**
8064 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
8065 * vendor command
8066 *
8067 * @wiphy: wiphy device pointer
8068 * @wdev: wireless device pointer
8069 * @data: Vendor command data buffer
8070 * @data_len: Buffer length
8071 *
8072 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
8073 *
8074 * Return: EOK or other error codes.
8075 */
8076static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
8077 struct wireless_dev *wdev,
8078 const void *data,
8079 int data_len)
8080{
8081 int ret;
8082
8083 vos_ssr_protect(__func__);
8084 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
8085 data, data_len);
8086 vos_ssr_unprotect(__func__);
8087
8088 return ret;
8089}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308090
8091/*
8092 * define short names for the global vendor params
8093 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8094 */
8095#define STATS_SET_INVALID \
8096 QCA_ATTR_NUD_STATS_SET_INVALID
8097#define STATS_SET_START \
8098 QCA_ATTR_NUD_STATS_SET_START
8099#define STATS_GW_IPV4 \
8100 QCA_ATTR_NUD_STATS_GW_IPV4
8101#define STATS_SET_MAX \
8102 QCA_ATTR_NUD_STATS_SET_MAX
8103
8104const struct nla_policy
8105qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
8106{
8107 [STATS_SET_START] = {.type = NLA_FLAG },
8108 [STATS_GW_IPV4] = {.type = NLA_U32 },
8109};
8110
8111/**
8112 * hdd_set_nud_stats_cb() - hdd callback api to get status
8113 * @data: pointer to adapter
8114 * @rsp: status
8115 *
8116 * Return: None
8117 */
8118static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
8119{
8120
8121 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8122
8123 if (NULL == adapter)
8124 return;
8125
8126 if (VOS_STATUS_SUCCESS == rsp) {
8127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8128 "%s success received STATS_SET_START", __func__);
8129 } else {
8130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8131 "%s STATS_SET_START Failed!!", __func__);
8132 }
8133 return;
8134}
8135
8136/**
8137 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8138 * @wiphy: pointer to wireless wiphy structure.
8139 * @wdev: pointer to wireless_dev structure.
8140 * @data: pointer to apfind configuration data.
8141 * @data_len: the length in byte of apfind data.
8142 *
8143 * This is called when wlan driver needs to send arp stats to
8144 * firmware.
8145 *
8146 * Return: An error code or 0 on success.
8147 */
8148static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8149 struct wireless_dev *wdev,
8150 const void *data, int data_len)
8151{
8152 struct nlattr *tb[STATS_SET_MAX + 1];
8153 struct net_device *dev = wdev->netdev;
8154 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8155 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308156 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308157 setArpStatsParams arp_stats_params;
8158 int err = 0;
8159
8160 ENTER();
8161
8162 err = wlan_hdd_validate_context(hdd_ctx);
8163 if (0 != err)
8164 return err;
8165
8166 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8168 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8169 return -EINVAL;
8170 }
8171
8172 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8173 qca_wlan_vendor_set_nud_stats);
8174 if (err)
8175 {
8176 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8177 "%s STATS_SET_START ATTR", __func__);
8178 return err;
8179 }
8180
8181 if (tb[STATS_SET_START])
8182 {
8183 if (!tb[STATS_GW_IPV4]) {
8184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8185 "%s STATS_SET_START CMD", __func__);
8186 return -EINVAL;
8187 }
8188 arp_stats_params.flag = true;
8189 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8190 } else {
8191 arp_stats_params.flag = false;
8192 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308193 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8195 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308196 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8197 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308198
8199 arp_stats_params.pkt_type = 1; // ARP packet type
8200
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308201 if (arp_stats_params.flag) {
8202 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8203 WLANTL_SetARPFWDatapath(pVosContext, true);
8204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8205 "%s Set FW in data path for ARP with tgt IP :%d",
8206 __func__, hdd_ctx->track_arp_ip);
8207 }
8208 else {
8209 WLANTL_SetARPFWDatapath(pVosContext, false);
8210 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8211 "%s Remove FW from data path", __func__);
8212 }
8213
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308214 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8215 arp_stats_params.data_ctx = adapter;
8216
8217 if (eHAL_STATUS_SUCCESS !=
8218 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8220 "%s STATS_SET_START CMD Failed!!", __func__);
8221 return -EINVAL;
8222 }
8223
8224 EXIT();
8225
8226 return err;
8227}
8228
8229/**
8230 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8231 * @wiphy: pointer to wireless wiphy structure.
8232 * @wdev: pointer to wireless_dev structure.
8233 * @data: pointer to apfind configuration data.
8234 * @data_len: the length in byte of apfind data.
8235 *
8236 * This is called when wlan driver needs to send arp stats to
8237 * firmware.
8238 *
8239 * Return: An error code or 0 on success.
8240 */
8241static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8242 struct wireless_dev *wdev,
8243 const void *data, int data_len)
8244{
8245 int ret;
8246
8247 vos_ssr_protect(__func__);
8248 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8249 vos_ssr_unprotect(__func__);
8250
8251 return ret;
8252}
8253#undef STATS_SET_INVALID
8254#undef STATS_SET_START
8255#undef STATS_GW_IPV4
8256#undef STATS_SET_MAX
8257
8258/*
8259 * define short names for the global vendor params
8260 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8261 */
8262#define STATS_GET_INVALID \
8263 QCA_ATTR_NUD_STATS_SET_INVALID
8264#define COUNT_FROM_NETDEV \
8265 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8266#define COUNT_TO_LOWER_MAC \
8267 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8268#define RX_COUNT_BY_LOWER_MAC \
8269 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8270#define COUNT_TX_SUCCESS \
8271 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8272#define RSP_RX_COUNT_BY_LOWER_MAC \
8273 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8274#define RSP_RX_COUNT_BY_UPPER_MAC \
8275 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8276#define RSP_COUNT_TO_NETDEV \
8277 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8278#define RSP_COUNT_OUT_OF_ORDER_DROP \
8279 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8280#define AP_LINK_ACTIVE \
8281 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8282#define AP_LINK_DAD \
8283 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8284#define STATS_GET_MAX \
8285 QCA_ATTR_NUD_STATS_GET_MAX
8286
8287const struct nla_policy
8288qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8289{
8290 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8291 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8292 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8293 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8294 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8295 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8296 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8297 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8298 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8299 [AP_LINK_DAD] = {.type = NLA_FLAG },
8300};
8301
8302static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8303{
8304
8305 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308306 hdd_context_t *hdd_ctx;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308307 struct hdd_nud_stats_context *context;
8308 int status;
8309
8310 ENTER();
8311
8312 if (NULL == adapter)
8313 return;
8314
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308315 if (!rsp) {
8316 hddLog(LOGE, FL("data is null"));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308317 return;
8318 }
8319
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308320 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8321 status = wlan_hdd_validate_context(hdd_ctx);
8322 if (0 != status) {
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308323 return;
8324 }
8325
8326 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8327 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8328 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8329 adapter->dad |= rsp->dad;
8330
8331 spin_lock(&hdd_context_lock);
8332 context = &hdd_ctx->nud_stats_context;
8333 complete(&context->response_event);
8334 spin_unlock(&hdd_context_lock);
8335
8336 return;
8337}
8338static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8339 struct wireless_dev *wdev,
8340 const void *data, int data_len)
8341{
8342 int err = 0;
8343 unsigned long rc;
8344 struct hdd_nud_stats_context *context;
8345 struct net_device *dev = wdev->netdev;
8346 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8347 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8348 getArpStatsParams arp_stats_params;
8349 struct sk_buff *skb;
8350
8351 ENTER();
8352
8353 err = wlan_hdd_validate_context(hdd_ctx);
8354 if (0 != err)
8355 return err;
8356
8357 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8358 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8359 arp_stats_params.data_ctx = adapter;
8360
8361 spin_lock(&hdd_context_lock);
8362 context = &hdd_ctx->nud_stats_context;
8363 INIT_COMPLETION(context->response_event);
8364 spin_unlock(&hdd_context_lock);
8365
8366 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8368 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8369 return -EINVAL;
8370 }
8371
8372 if (eHAL_STATUS_SUCCESS !=
8373 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8375 "%s STATS_SET_START CMD Failed!!", __func__);
8376 return -EINVAL;
8377 }
8378
8379 rc = wait_for_completion_timeout(&context->response_event,
8380 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8381 if (!rc)
8382 {
8383 hddLog(LOGE,
8384 FL("Target response timed out request "));
8385 return -ETIMEDOUT;
8386 }
8387
8388 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8389 WLAN_NUD_STATS_LEN);
8390 if (!skb)
8391 {
8392 hddLog(VOS_TRACE_LEVEL_ERROR,
8393 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8394 __func__);
8395 return -ENOMEM;
8396 }
8397
8398 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8399 adapter->hdd_stats.hddArpStats.txCount) ||
8400 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8401 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8402 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8403 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8404 nla_put_u16(skb, COUNT_TX_SUCCESS,
8405 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8406 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8407 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8408 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8409 adapter->hdd_stats.hddArpStats.rxCount) ||
8410 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8411 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8412 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8413 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8414 hddLog(LOGE, FL("nla put fail"));
8415 kfree_skb(skb);
8416 return -EINVAL;
8417 }
8418 if (adapter->con_status)
8419 nla_put_flag(skb, AP_LINK_ACTIVE);
8420 if (adapter->dad)
8421 nla_put_flag(skb, AP_LINK_DAD);
8422
8423 cfg80211_vendor_cmd_reply(skb);
8424 return err;
8425}
8426
8427static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8428 struct wireless_dev *wdev,
8429 const void *data, int data_len)
8430{
8431 int ret;
8432
8433 vos_ssr_protect(__func__);
8434 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8435 vos_ssr_unprotect(__func__);
8436
8437 return ret;
8438}
8439
8440#undef QCA_ATTR_NUD_STATS_SET_INVALID
8441#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8442#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8443#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8444#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8445#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8446#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8447#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8448#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8449#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8450#undef QCA_ATTR_NUD_STATS_GET_MAX
8451
8452
8453
Kapil Guptaee33bf12016-12-20 18:27:37 +05308454#ifdef WLAN_FEATURE_APFIND
8455/**
8456 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8457 * @wiphy: pointer to wireless wiphy structure.
8458 * @wdev: pointer to wireless_dev structure.
8459 * @data: pointer to apfind configuration data.
8460 * @data_len: the length in byte of apfind data.
8461 *
8462 * This is called when wlan driver needs to send APFIND configurations to
8463 * firmware.
8464 *
8465 * Return: An error code or 0 on success.
8466 */
8467static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8468 struct wireless_dev *wdev,
8469 const void *data, int data_len)
8470{
8471 struct sme_ap_find_request_req apfind_req;
8472 VOS_STATUS status;
8473 int ret_val;
8474 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8475
8476 ENTER();
8477
8478 ret_val = wlan_hdd_validate_context(hdd_ctx);
8479 if (ret_val)
8480 return ret_val;
8481
8482 if (VOS_FTM_MODE == hdd_get_conparam()) {
8483 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8484 return -EPERM;
8485 }
8486
8487 apfind_req.request_data_len = data_len;
8488 apfind_req.request_data = data;
8489
8490 status = sme_apfind_set_cmd(&apfind_req);
8491 if (VOS_STATUS_SUCCESS != status) {
8492 ret_val = -EIO;
8493 }
8494 return ret_val;
8495}
8496
8497/**
8498 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8499 * @wiphy: pointer to wireless wiphy structure.
8500 * @wdev: pointer to wireless_dev structure.
8501 * @data: pointer to apfind configuration data.
8502 * @data_len: the length in byte of apfind data.
8503 *
8504 * This is called when wlan driver needs to send APFIND configurations to
8505 * firmware.
8506 *
8507 * Return: An error code or 0 on success.
8508 */
8509static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8510 struct wireless_dev *wdev,
8511 const void *data, int data_len)
8512{
8513 int ret;
8514
8515 vos_ssr_protect(__func__);
8516 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8517 vos_ssr_unprotect(__func__);
8518
8519 return ret;
8520}
8521#endif /* WLAN_FEATURE_APFIND */
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308522
8523/**
8524 * __wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8525 * @wiphy: pointer to wireless wiphy structure.
8526 * @wdev: pointer to wireless_dev structure.
8527 * @data: Pointer to the data to be passed via vendor interface
8528 * @data_len:Length of the data to be passed
8529 *
8530 * This is called by userspace to know the supported logger features
8531 *
8532 * Return: Return the Success or Failure code.
8533 */
8534static int
8535__wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8536 struct wireless_dev *wdev,
8537 const void *data, int data_len)
8538{
8539 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8540 int status;
8541 uint32_t features;
8542 struct sk_buff *reply_skb = NULL;
8543
8544 if (VOS_FTM_MODE == hdd_get_conparam()) {
8545 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8546 return -EINVAL;
8547 }
8548
8549 status = wlan_hdd_validate_context(hdd_ctx);
8550 if (0 != status)
8551 return -EINVAL;
8552
8553 features = 0;
8554
8555 if (hdd_is_memdump_supported())
8556 features |= WIFI_LOGGER_MEMORY_DUMP_SUPPORTED;
8557
8558 if (hdd_ctx->cfg_ini->wlanLoggingEnable &&
8559 hdd_ctx->cfg_ini->enableFatalEvent &&
8560 hdd_ctx->is_fatal_event_log_sup) {
8561 features |= WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED;
8562 features |= WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
8563 }
8564
8565 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8566 sizeof(uint32_t) + NLA_HDRLEN + NLMSG_HDRLEN);
8567 if (!reply_skb) {
8568 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
8569 return -ENOMEM;
8570 }
8571
8572 hddLog(LOG1, FL("Supported logger features: 0x%0x"), features);
8573 if (nla_put_u32(reply_skb, QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED,
8574 features)) {
8575 hddLog(LOGE, FL("nla put fail"));
8576 kfree_skb(reply_skb);
8577 return -EINVAL;
8578 }
8579
8580 return cfg80211_vendor_cmd_reply(reply_skb);
8581}
8582
8583/**
8584 * wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8585 * @wiphy: pointer to wireless wiphy structure.
8586 * @wdev: pointer to wireless_dev structure.
8587 * @data: Pointer to the data to be passed via vendor interface
8588 * @data_len:Length of the data to be passed
8589 *
8590 * This is called by userspace to know the supported logger features
8591 *
8592 * Return: Return the Success or Failure code.
8593 */
8594static int
8595wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8596 struct wireless_dev *wdev,
8597 const void *data, int data_len)
8598{
8599 int ret;
8600
8601 vos_ssr_protect(__func__);
8602 ret = __wlan_hdd_cfg80211_get_logger_supp_feature(wiphy, wdev,
8603 data, data_len);
8604 vos_ssr_unprotect(__func__);
8605
8606 return ret;
8607}
8608
Sunil Duttc69bccb2014-05-26 21:30:20 +05308609const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8610{
Mukul Sharma2a271632014-10-13 14:59:01 +05308611 {
8612 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8613 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8614 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8615 WIPHY_VENDOR_CMD_NEED_NETDEV |
8616 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308617 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308618 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308619
8620 {
8621 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8622 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8623 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8624 WIPHY_VENDOR_CMD_NEED_NETDEV |
8625 WIPHY_VENDOR_CMD_NEED_RUNNING,
8626 .doit = wlan_hdd_cfg80211_nan_request
8627 },
8628
Sunil Duttc69bccb2014-05-26 21:30:20 +05308629#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8630 {
8631 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8632 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8633 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8634 WIPHY_VENDOR_CMD_NEED_NETDEV |
8635 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308636 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308637 },
8638
8639 {
8640 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8641 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8642 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8643 WIPHY_VENDOR_CMD_NEED_NETDEV |
8644 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308645 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308646 },
8647
8648 {
8649 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8650 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
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_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308655 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308656#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308657#ifdef WLAN_FEATURE_EXTSCAN
8658 {
8659 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8660 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8661 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8662 WIPHY_VENDOR_CMD_NEED_NETDEV |
8663 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308664 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308665 },
8666 {
8667 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8668 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
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_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308673 },
8674 {
8675 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8676 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8677 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8678 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308679 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308680 },
8681 {
8682 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8683 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8684 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8685 WIPHY_VENDOR_CMD_NEED_NETDEV |
8686 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308687 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308688 },
8689 {
8690 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8691 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8692 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8693 WIPHY_VENDOR_CMD_NEED_NETDEV |
8694 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308695 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308696 },
8697 {
8698 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8699 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8700 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8701 WIPHY_VENDOR_CMD_NEED_NETDEV |
8702 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308703 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308704 },
8705 {
8706 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8707 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8708 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8709 WIPHY_VENDOR_CMD_NEED_NETDEV |
8710 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308711 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308712 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308713#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308714/*EXT TDLS*/
8715 {
8716 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8717 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
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_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308722 },
8723 {
8724 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8725 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
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_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308730 },
8731 {
8732 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8733 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8734 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8735 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308736 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308737 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308738 {
8739 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8740 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8741 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8742 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308743 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308744 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308745 {
8746 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8747 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8748 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8749 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308750 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308751 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308752 {
8753 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8754 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8755 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8756 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308757 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308758 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308759 {
8760 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8761 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8762 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8763 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308764 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308765 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308766 {
8767 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308768 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8769 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8770 WIPHY_VENDOR_CMD_NEED_NETDEV |
8771 WIPHY_VENDOR_CMD_NEED_RUNNING,
8772 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8773 },
8774 {
8775 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308776 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8777 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8778 WIPHY_VENDOR_CMD_NEED_NETDEV |
8779 WIPHY_VENDOR_CMD_NEED_RUNNING,
8780 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308781 },
8782 {
8783 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8784 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8785 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8786 WIPHY_VENDOR_CMD_NEED_NETDEV,
8787 .doit = wlan_hdd_cfg80211_wifi_logger_start
8788 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308789 {
8790 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8791 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8792 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8793 WIPHY_VENDOR_CMD_NEED_NETDEV|
8794 WIPHY_VENDOR_CMD_NEED_RUNNING,
8795 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308796 },
8797 {
8798 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8799 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8800 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8801 WIPHY_VENDOR_CMD_NEED_NETDEV |
8802 WIPHY_VENDOR_CMD_NEED_RUNNING,
8803 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308804 },
8805 {
8806 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8807 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8808 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8809 WIPHY_VENDOR_CMD_NEED_NETDEV |
8810 WIPHY_VENDOR_CMD_NEED_RUNNING,
8811 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308812 },
8813#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8814 {
8815 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8816 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8817 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8818 WIPHY_VENDOR_CMD_NEED_NETDEV |
8819 WIPHY_VENDOR_CMD_NEED_RUNNING,
8820 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308821 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308822#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308823 {
8824 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8825 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8826 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8827 WIPHY_VENDOR_CMD_NEED_NETDEV |
8828 WIPHY_VENDOR_CMD_NEED_RUNNING,
8829 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308830 },
8831 {
8832 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8833 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8834 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8835 WIPHY_VENDOR_CMD_NEED_NETDEV |
8836 WIPHY_VENDOR_CMD_NEED_RUNNING,
8837 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308838 },
8839#ifdef WLAN_FEATURE_APFIND
8840 {
8841 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8842 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8843 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8844 WIPHY_VENDOR_CMD_NEED_NETDEV,
8845 .doit = wlan_hdd_cfg80211_apfind_cmd
8846 },
8847#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308848 {
8849 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8850 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8851 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8852 WIPHY_VENDOR_CMD_NEED_NETDEV |
8853 WIPHY_VENDOR_CMD_NEED_RUNNING,
8854 .doit = wlan_hdd_cfg80211_set_nud_stats
8855 },
8856 {
8857 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8858 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8859 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8860 WIPHY_VENDOR_CMD_NEED_NETDEV |
8861 WIPHY_VENDOR_CMD_NEED_RUNNING,
8862 .doit = wlan_hdd_cfg80211_get_nud_stats
8863 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308864 {
8865 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8866 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8867 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8868 WIPHY_VENDOR_CMD_NEED_NETDEV |
8869 WIPHY_VENDOR_CMD_NEED_RUNNING,
8870 .doit = hdd_cfg80211_get_station_cmd
8871 },
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308872 {
8873 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8874 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET,
8875 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8876 WIPHY_VENDOR_CMD_NEED_NETDEV |
8877 WIPHY_VENDOR_CMD_NEED_RUNNING,
8878 .doit = wlan_hdd_cfg80211_get_logger_supp_feature
8879 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308880};
8881
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008882/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308883static const
8884struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008885{
8886#ifdef FEATURE_WLAN_CH_AVOID
8887 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308888 .vendor_id = QCA_NL80211_VENDOR_ID,
8889 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008890 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308891#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8892#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8893 {
8894 /* Index = 1*/
8895 .vendor_id = QCA_NL80211_VENDOR_ID,
8896 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8897 },
8898 {
8899 /* Index = 2*/
8900 .vendor_id = QCA_NL80211_VENDOR_ID,
8901 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8902 },
8903 {
8904 /* Index = 3*/
8905 .vendor_id = QCA_NL80211_VENDOR_ID,
8906 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8907 },
8908 {
8909 /* Index = 4*/
8910 .vendor_id = QCA_NL80211_VENDOR_ID,
8911 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8912 },
8913 {
8914 /* Index = 5*/
8915 .vendor_id = QCA_NL80211_VENDOR_ID,
8916 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8917 },
8918 {
8919 /* Index = 6*/
8920 .vendor_id = QCA_NL80211_VENDOR_ID,
8921 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8922 },
8923#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308924#ifdef WLAN_FEATURE_EXTSCAN
8925 {
8926 .vendor_id = QCA_NL80211_VENDOR_ID,
8927 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8928 },
8929 {
8930 .vendor_id = QCA_NL80211_VENDOR_ID,
8931 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8932 },
8933 {
8934 .vendor_id = QCA_NL80211_VENDOR_ID,
8935 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8936 },
8937 {
8938 .vendor_id = QCA_NL80211_VENDOR_ID,
8939 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8940 },
8941 {
8942 .vendor_id = QCA_NL80211_VENDOR_ID,
8943 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8944 },
8945 {
8946 .vendor_id = QCA_NL80211_VENDOR_ID,
8947 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8948 },
8949 {
8950 .vendor_id = QCA_NL80211_VENDOR_ID,
8951 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8952 },
8953 {
8954 .vendor_id = QCA_NL80211_VENDOR_ID,
8955 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8956 },
8957 {
8958 .vendor_id = QCA_NL80211_VENDOR_ID,
8959 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8960 },
8961 {
8962 .vendor_id = QCA_NL80211_VENDOR_ID,
8963 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8964 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308965#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308966/*EXT TDLS*/
8967 {
8968 .vendor_id = QCA_NL80211_VENDOR_ID,
8969 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8970 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308971 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8972 .vendor_id = QCA_NL80211_VENDOR_ID,
8973 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8974 },
8975
Srinivas Dasari030bad32015-02-18 23:23:54 +05308976
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308977 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308978 .vendor_id = QCA_NL80211_VENDOR_ID,
8979 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8980 },
8981
Sushant Kaushik084f6592015-09-10 13:11:56 +05308982 {
8983 .vendor_id = QCA_NL80211_VENDOR_ID,
8984 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308985 },
8986 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8987 .vendor_id = QCA_NL80211_VENDOR_ID,
8988 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8989 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308990 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8991 .vendor_id = QCA_NL80211_VENDOR_ID,
8992 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8993 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308994 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8995 .vendor_id = QCA_NL80211_VENDOR_ID,
8996 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8997 },
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05308998 [QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
8999 .vendor_id = QCA_NL80211_VENDOR_ID,
9000 .subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
9001 },
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +05309002 [QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX] = {
9003 .vendor_id = QCA_NL80211_VENDOR_ID,
9004 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
9005 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009006};
9007
Jeff Johnson295189b2012-06-20 16:38:30 -07009008/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309009 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309010 * This function is called by hdd_wlan_startup()
9011 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309012 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07009013 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309014struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07009015{
9016 struct wiphy *wiphy;
9017 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309018 /*
9019 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07009020 */
9021 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
9022
9023 if (!wiphy)
9024 {
9025 /* Print error and jump into err label and free the memory */
9026 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
9027 return NULL;
9028 }
9029
Sunil Duttc69bccb2014-05-26 21:30:20 +05309030
Jeff Johnson295189b2012-06-20 16:38:30 -07009031 return wiphy;
9032}
9033
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309034#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
9035 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
9036/**
9037 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
9038 * @wiphy: pointer to wiphy
9039 * @config: pointer to config
9040 *
9041 * Return: None
9042 */
9043static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
9044 hdd_config_t *config)
9045{
9046 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
9047 if (config->max_sched_scan_plan_interval)
9048 wiphy->max_sched_scan_plan_interval =
9049 config->max_sched_scan_plan_interval;
9050 if (config->max_sched_scan_plan_iterations)
9051 wiphy->max_sched_scan_plan_iterations =
9052 config->max_sched_scan_plan_iterations;
9053}
9054#else
9055static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
9056 hdd_config_t *config)
9057{
9058}
9059#endif
9060
Jeff Johnson295189b2012-06-20 16:38:30 -07009061/*
9062 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309063 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07009064 * private ioctl to change the band value
9065 */
9066int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
9067{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309068 int i, j;
9069 eNVChannelEnabledType channelEnabledState;
9070
Jeff Johnsone7245742012-09-05 17:12:55 -07009071 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309072
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309073 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009074 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309075
9076 if (NULL == wiphy->bands[i])
9077 {
9078 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
9079 __func__, i);
9080 continue;
9081 }
9082
9083 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9084 {
9085 struct ieee80211_supported_band *band = wiphy->bands[i];
9086
9087 channelEnabledState = vos_nv_getChannelEnabledState(
9088 band->channels[j].hw_value);
9089
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309090 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309091 {
Abhishek Singh678227a2014-11-04 10:52:38 +05309092 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309093 continue;
9094 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309095 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309096 {
9097 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9098 continue;
9099 }
9100
9101 if (NV_CHANNEL_DISABLE == channelEnabledState ||
9102 NV_CHANNEL_INVALID == channelEnabledState)
9103 {
9104 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9105 }
9106 else if (NV_CHANNEL_DFS == channelEnabledState)
9107 {
9108 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9109 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
9110 }
9111 else
9112 {
9113 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
9114 |IEEE80211_CHAN_RADAR);
9115 }
9116 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009117 }
9118 return 0;
9119}
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309120
9121/**
9122 * hdd_add_channel_switch_support()- Adds Channel Switch flag if supported
9123 * @wiphy: Pointer to the wiphy.
9124 *
9125 * This Function adds Channel Switch support flag, if channel switch is
9126 * supported by kernel.
9127 * Return: void.
9128 */
9129#ifdef CHANNEL_SWITCH_SUPPORTED
9130static inline
9131void hdd_add_channel_switch_support(struct wiphy *wiphy)
9132{
9133 wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
9134 wiphy->max_num_csa_counters = WLAN_HDD_MAX_NUM_CSA_COUNTERS;
9135}
9136#else
9137static inline
9138void hdd_add_channel_switch_support(struct wiphy *wiphy)
9139{
9140}
9141#endif
9142
Jeff Johnson295189b2012-06-20 16:38:30 -07009143/*
9144 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309145 * This function is called by hdd_wlan_startup()
9146 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07009147 * This function is used to initialize and register wiphy structure.
9148 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309149int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009150 struct wiphy *wiphy,
9151 hdd_config_t *pCfg
9152 )
9153{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309154 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309155 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9156
Jeff Johnsone7245742012-09-05 17:12:55 -07009157 ENTER();
9158
Jeff Johnson295189b2012-06-20 16:38:30 -07009159 /* Now bind the underlying wlan device with wiphy */
9160 set_wiphy_dev(wiphy, dev);
9161
9162 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009163
Kiet Lam6c583332013-10-14 05:37:09 +05309164#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009165 /* the flag for the other case would be initialzed in
9166 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05309167#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9168 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
9169#else
Amar Singhal0a402232013-10-11 20:57:16 -07009170 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05309171#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05309172#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009173
Amar Singhalfddc28c2013-09-05 13:03:40 -07009174 /* This will disable updating of NL channels from passive to
9175 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309176#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9177 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
9178#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07009179 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309180#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07009181
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309182#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
9183 wiphy->wowlan = &wowlan_support_cfg80211_init;
9184#else
9185 wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT;
9186 wiphy->wowlan.n_patterns = WOWL_MAX_PTRNS_ALLOWED;
9187 wiphy->wowlan.pattern_min_len = 1;
9188 wiphy->wowlan.pattern_max_len = WOWL_PTRN_MAX_SIZE;
9189#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009190
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009191#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009192 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
9193 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
9194 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07009195 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309196#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05309197 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309198#else
9199 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
9200#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009201#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009202
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009203#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009204 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08009205#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009206 || pCfg->isFastRoamIniFeatureEnabled
9207#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009208#ifdef FEATURE_WLAN_ESE
9209 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009210#endif
9211 )
9212 {
9213 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
9214 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08009215#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009216#ifdef FEATURE_WLAN_TDLS
9217 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
9218 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
9219#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309220#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05309221 if (pCfg->configPNOScanSupport)
9222 {
9223 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
9224 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
9225 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
9226 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
9227 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309228#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009229
Abhishek Singh10d85972015-04-17 10:27:23 +05309230#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9231 wiphy->features |= NL80211_FEATURE_HT_IBSS;
9232#endif
9233
Amar Singhalfddc28c2013-09-05 13:03:40 -07009234#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009235 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
9236 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07009237 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009238 driver need to determine what to do with both
9239 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07009240
9241 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07009242#else
9243 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009244#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009245
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309246 wiphy->max_scan_ssids = MAX_SCAN_SSID;
9247
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05309248 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07009249
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309250 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
9251
Jeff Johnson295189b2012-06-20 16:38:30 -07009252 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05309253 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
9254 | BIT(NL80211_IFTYPE_ADHOC)
9255 | BIT(NL80211_IFTYPE_P2P_CLIENT)
9256 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309257 | BIT(NL80211_IFTYPE_AP)
9258 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07009259
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309260 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009261 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309262#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9263 if( pCfg->enableMCC )
9264 {
9265 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309266 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009267
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309268 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309269 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009270
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309271 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309272 wiphy->iface_combinations = wlan_hdd_iface_combination;
9273 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009274#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309275 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009276
Jeff Johnson295189b2012-06-20 16:38:30 -07009277 /* Before registering we need to update the ht capabilitied based
9278 * on ini values*/
9279 if( !pCfg->ShortGI20MhzEnable )
9280 {
9281 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
9282 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07009283 }
9284
9285 if( !pCfg->ShortGI40MhzEnable )
9286 {
9287 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9288 }
9289
9290 if( !pCfg->nChannelBondingMode5GHz )
9291 {
9292 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9293 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309294 /*
9295 * In case of static linked driver at the time of driver unload,
9296 * module exit doesn't happens. Module cleanup helps in cleaning
9297 * of static memory.
9298 * If driver load happens statically, at the time of driver unload,
9299 * wiphy flags don't get reset because of static memory.
9300 * It's better not to store channel in static memory.
9301 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309302 wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9303 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309304 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309305 if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309306 {
9307 hddLog(VOS_TRACE_LEVEL_ERROR,
9308 FL("Not enough memory to allocate channels"));
9309 return -ENOMEM;
9310 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309311 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309312 &hdd_channels_2_4_GHZ[0],
9313 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009314
Agrawal Ashish97dec502015-11-26 20:20:58 +05309315 if (true == hdd_is_5g_supported(pHddCtx))
9316 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309317 wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9318 wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309319 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309320 if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309321 {
9322 hddLog(VOS_TRACE_LEVEL_ERROR,
9323 FL("Not enough memory to allocate channels"));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309324 vos_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
9325 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
Agrawal Ashish97dec502015-11-26 20:20:58 +05309326 return -ENOMEM;
9327 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309328 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309329 &hdd_channels_5_GHZ[0],
9330 sizeof(hdd_channels_5_GHZ));
9331 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309332
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309333 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309334 {
9335
9336 if (NULL == wiphy->bands[i])
9337 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309338 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309339 __func__, i);
9340 continue;
9341 }
9342
9343 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9344 {
9345 struct ieee80211_supported_band *band = wiphy->bands[i];
9346
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309347 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309348 {
9349 // Enable social channels for P2P
9350 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9351 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9352 else
9353 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9354 continue;
9355 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309356 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309357 {
9358 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9359 continue;
9360 }
9361 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009362 }
9363 /*Initialise the supported cipher suite details*/
9364 wiphy->cipher_suites = hdd_cipher_suites;
9365 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9366
9367 /*signal strength in mBm (100*dBm) */
9368 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9369
9370#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309371 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009372#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009373
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309374 hdd_add_channel_switch_support(wiphy);
Sunil Duttc69bccb2014-05-26 21:30:20 +05309375 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9376 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009377 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9378 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9379
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309380 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
9381
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309382 EXIT();
9383 return 0;
9384}
9385
9386/* In this function we are registering wiphy. */
9387int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9388{
9389 ENTER();
9390 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009391 if (0 > wiphy_register(wiphy))
9392 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309393 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009394 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9395 return -EIO;
9396 }
9397
9398 EXIT();
9399 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309400}
Jeff Johnson295189b2012-06-20 16:38:30 -07009401
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309402/* In this function we are updating channel list when,
9403 regulatory domain is FCC and country code is US.
9404 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9405 As per FCC smart phone is not a indoor device.
9406 GO should not opeate on indoor channels */
9407void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9408{
9409 int j;
9410 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9411 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9412 //Default counrtycode from NV at the time of wiphy initialization.
9413 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9414 &defaultCountryCode[0]))
9415 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009416 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309417 }
9418 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9419 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309420 if (NULL == wiphy->bands[HDD_NL80211_BAND_5GHZ])
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309421 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309422 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[HDD_NL80211_BAND_5GHZ] is NULL",__func__ );
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309423 return;
9424 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309425 for (j = 0; j < wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels; j++)
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309426 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309427 struct ieee80211_supported_band *band = wiphy->bands[HDD_NL80211_BAND_5GHZ];
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309428 // Mark UNII -1 band channel as passive
9429 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9430 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9431 }
9432 }
9433}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309434/* This function registers for all frame which supplicant is interested in */
9435void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009436{
Jeff Johnson295189b2012-06-20 16:38:30 -07009437 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9438 /* Register for all P2P action, public action etc frames */
9439 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009440 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309441 /* Register frame indication call back */
9442 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009443 /* Right now we are registering these frame when driver is getting
9444 initialized. Once we will move to 2.6.37 kernel, in which we have
9445 frame register ops, we will move this code as a part of that */
9446 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309447 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009448 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9449
9450 /* GAS Initial Response */
9451 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9452 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309453
Jeff Johnson295189b2012-06-20 16:38:30 -07009454 /* GAS Comeback Request */
9455 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9456 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9457
9458 /* GAS Comeback Response */
9459 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9460 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9461
9462 /* P2P Public Action */
9463 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309464 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009465 P2P_PUBLIC_ACTION_FRAME_SIZE );
9466
9467 /* P2P Action */
9468 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9469 (v_U8_t*)P2P_ACTION_FRAME,
9470 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009471
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309472 /* WNM BSS Transition Request frame */
9473 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9474 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9475 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009476
9477 /* WNM-Notification */
9478 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9479 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9480 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009481}
9482
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309483void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009484{
Jeff Johnson295189b2012-06-20 16:38:30 -07009485 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9486 /* Register for all P2P action, public action etc frames */
9487 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9488
Jeff Johnsone7245742012-09-05 17:12:55 -07009489 ENTER();
9490
Jeff Johnson295189b2012-06-20 16:38:30 -07009491 /* Right now we are registering these frame when driver is getting
9492 initialized. Once we will move to 2.6.37 kernel, in which we have
9493 frame register ops, we will move this code as a part of that */
9494 /* GAS Initial Request */
9495
9496 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9497 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9498
9499 /* GAS Initial Response */
9500 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9501 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309502
Jeff Johnson295189b2012-06-20 16:38:30 -07009503 /* GAS Comeback Request */
9504 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9505 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9506
9507 /* GAS Comeback Response */
9508 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9509 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9510
9511 /* P2P Public Action */
9512 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309513 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009514 P2P_PUBLIC_ACTION_FRAME_SIZE );
9515
9516 /* P2P Action */
9517 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9518 (v_U8_t*)P2P_ACTION_FRAME,
9519 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009520 /* WNM-Notification */
9521 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9522 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9523 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009524}
9525
9526#ifdef FEATURE_WLAN_WAPI
9527void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309528 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009529{
9530 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9531 tCsrRoamSetKey setKey;
9532 v_BOOL_t isConnected = TRUE;
9533 int status = 0;
9534 v_U32_t roamId= 0xFF;
9535 tANI_U8 *pKeyPtr = NULL;
9536 int n = 0;
9537
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309538 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9539 __func__, hdd_device_modetoString(pAdapter->device_mode),
9540 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009541
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309542 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009543 setKey.keyId = key_index; // Store Key ID
9544 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9545 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9546 setKey.paeRole = 0 ; // the PAE role
9547 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9548 {
9549 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9550 }
9551 else
9552 {
9553 isConnected = hdd_connIsConnected(pHddStaCtx);
9554 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9555 }
9556 setKey.keyLength = key_Len;
9557 pKeyPtr = setKey.Key;
9558 memcpy( pKeyPtr, key, key_Len);
9559
Arif Hussain6d2a3322013-11-17 19:50:10 -08009560 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009561 __func__, key_Len);
9562 for (n = 0 ; n < key_Len; n++)
9563 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9564 __func__,n,setKey.Key[n]);
9565
9566 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9567 if ( isConnected )
9568 {
9569 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9570 pAdapter->sessionId, &setKey, &roamId );
9571 }
9572 if ( status != 0 )
9573 {
9574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9575 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9576 __LINE__, status );
9577 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9578 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309579 /* Need to clear any trace of key value in the memory.
9580 * Thus zero out the memory even though it is local
9581 * variable.
9582 */
9583 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009584}
9585#endif /* FEATURE_WLAN_WAPI*/
9586
9587#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309588int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009589 beacon_data_t **ppBeacon,
9590 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009591#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309592int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009593 beacon_data_t **ppBeacon,
9594 struct cfg80211_beacon_data *params,
9595 int dtim_period)
9596#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309597{
Jeff Johnson295189b2012-06-20 16:38:30 -07009598 int size;
9599 beacon_data_t *beacon = NULL;
9600 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309601 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9602 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009603
Jeff Johnsone7245742012-09-05 17:12:55 -07009604 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009605 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309606 {
9607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9608 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009609 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309610 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009611
9612 old = pAdapter->sessionCtx.ap.beacon;
9613
9614 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309615 {
9616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9617 FL("session(%d) old and new heads points to NULL"),
9618 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009619 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309620 }
9621
9622 if (params->tail && !params->tail_len)
9623 {
9624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9625 FL("tail_len is zero but tail is not NULL"));
9626 return -EINVAL;
9627 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009628
Jeff Johnson295189b2012-06-20 16:38:30 -07009629#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9630 /* Kernel 3.0 is not updating dtim_period for set beacon */
9631 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309632 {
9633 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9634 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009635 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309636 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009637#endif
9638
Kapil Gupta137ef892016-12-13 19:38:00 +05309639 if (params->head)
9640 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009641 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309642 head = params->head;
9643 } else
9644 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009645 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309646 head = old->head;
9647 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009648
Kapil Gupta137ef892016-12-13 19:38:00 +05309649 if (params->tail || !old)
9650 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009651 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309652 tail = params->tail;
9653 } else
9654 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009655 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309656 tail = old->tail;
9657 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009658
Kapil Gupta137ef892016-12-13 19:38:00 +05309659 if (params->proberesp_ies || !old)
9660 {
9661 proberesp_ies_len = params->proberesp_ies_len;
9662 proberesp_ies = params->proberesp_ies;
9663 } else
9664 {
9665 proberesp_ies_len = old->proberesp_ies_len;
9666 proberesp_ies = old->proberesp_ies;
9667 }
9668
9669 if (params->assocresp_ies || !old)
9670 {
9671 assocresp_ies_len = params->assocresp_ies_len;
9672 assocresp_ies = params->assocresp_ies;
9673 } else
9674 {
9675 assocresp_ies_len = old->assocresp_ies_len;
9676 assocresp_ies = old->assocresp_ies;
9677 }
9678
9679 size = sizeof(beacon_data_t) + head_len + tail_len +
9680 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009681
9682 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009683 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309684 {
9685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9686 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009687 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309688 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009689
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009690#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309691 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009692 beacon->dtim_period = params->dtim_period;
9693 else
9694 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009695#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309696 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009697 beacon->dtim_period = dtim_period;
9698 else
9699 beacon->dtim_period = old->dtim_period;
9700#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309701
Jeff Johnson295189b2012-06-20 16:38:30 -07009702 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9703 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309704 beacon->proberesp_ies = beacon->tail + tail_len;
9705 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9706
Jeff Johnson295189b2012-06-20 16:38:30 -07009707 beacon->head_len = head_len;
9708 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309709 beacon->proberesp_ies_len = proberesp_ies_len;
9710 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009711
c_manjee527ecac2017-01-25 12:25:27 +05309712 if (head && head_len)
9713 memcpy(beacon->head, head, head_len);
9714 if (tail && tail_len)
9715 memcpy(beacon->tail, tail, tail_len);
9716 if (proberesp_ies && proberesp_ies_len)
9717 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9718 if (assocresp_ies && assocresp_ies_len)
9719 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009720
9721 *ppBeacon = beacon;
9722
9723 kfree(old);
9724
9725 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009726}
Jeff Johnson295189b2012-06-20 16:38:30 -07009727
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309728v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9729#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9730 const v_U8_t *pIes,
9731#else
9732 v_U8_t *pIes,
9733#endif
9734 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009735{
9736 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309737 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009738 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309739
Jeff Johnson295189b2012-06-20 16:38:30 -07009740 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309741 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009742 elem_id = ptr[0];
9743 elem_len = ptr[1];
9744 left -= 2;
9745 if(elem_len > left)
9746 {
9747 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009748 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009749 eid,elem_len,left);
9750 return NULL;
9751 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309752 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009753 {
9754 return ptr;
9755 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309756
Jeff Johnson295189b2012-06-20 16:38:30 -07009757 left -= elem_len;
9758 ptr += (elem_len + 2);
9759 }
9760 return NULL;
9761}
9762
Jeff Johnson295189b2012-06-20 16:38:30 -07009763/* Check if rate is 11g rate or not */
9764static int wlan_hdd_rate_is_11g(u8 rate)
9765{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009766 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009767 u8 i;
9768 for (i = 0; i < 8; i++)
9769 {
9770 if(rate == gRateArray[i])
9771 return TRUE;
9772 }
9773 return FALSE;
9774}
9775
9776/* Check for 11g rate and set proper 11g only mode */
9777static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9778 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9779{
9780 u8 i, num_rates = pIe[0];
9781
9782 pIe += 1;
9783 for ( i = 0; i < num_rates; i++)
9784 {
9785 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9786 {
9787 /* If rate set have 11g rate than change the mode to 11G */
9788 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9789 if (pIe[i] & BASIC_RATE_MASK)
9790 {
9791 /* If we have 11g rate as basic rate, it means mode
9792 is 11g only mode.
9793 */
9794 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9795 *pCheckRatesfor11g = FALSE;
9796 }
9797 }
9798 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9799 {
9800 *require_ht = TRUE;
9801 }
9802 }
9803 return;
9804}
9805
9806static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9807{
9808 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9809 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9810 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9811 u8 checkRatesfor11g = TRUE;
9812 u8 require_ht = FALSE;
9813 u8 *pIe=NULL;
9814
9815 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9816
9817 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9818 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9819 if (pIe != NULL)
9820 {
9821 pIe += 1;
9822 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9823 &pConfig->SapHw_mode);
9824 }
9825
9826 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9827 WLAN_EID_EXT_SUPP_RATES);
9828 if (pIe != NULL)
9829 {
9830
9831 pIe += 1;
9832 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9833 &pConfig->SapHw_mode);
9834 }
9835
9836 if( pConfig->channel > 14 )
9837 {
9838 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9839 }
9840
9841 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9842 WLAN_EID_HT_CAPABILITY);
9843
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309844 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009845 {
9846 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9847 if(require_ht)
9848 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9849 }
9850}
9851
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309852static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9853 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9854{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009855 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309856 v_U8_t *pIe = NULL;
9857 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9858
9859 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9860 pBeacon->tail, pBeacon->tail_len);
9861
9862 if (pIe)
9863 {
9864 ielen = pIe[1] + 2;
9865 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9866 {
9867 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9868 }
9869 else
9870 {
9871 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9872 return -EINVAL;
9873 }
9874 *total_ielen += ielen;
9875 }
9876 return 0;
9877}
9878
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009879static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9880 v_U8_t *genie, v_U8_t *total_ielen)
9881{
9882 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9883 int left = pBeacon->tail_len;
9884 v_U8_t *ptr = pBeacon->tail;
9885 v_U8_t elem_id, elem_len;
9886 v_U16_t ielen = 0;
9887
9888 if ( NULL == ptr || 0 == left )
9889 return;
9890
9891 while (left >= 2)
9892 {
9893 elem_id = ptr[0];
9894 elem_len = ptr[1];
9895 left -= 2;
9896 if (elem_len > left)
9897 {
9898 hddLog( VOS_TRACE_LEVEL_ERROR,
9899 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9900 elem_id, elem_len, left);
9901 return;
9902 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309903 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009904 {
9905 /* skipping the VSIE's which we don't want to include or
9906 * it will be included by existing code
9907 */
9908 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9909#ifdef WLAN_FEATURE_WFD
9910 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9911#endif
9912 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9913 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9914 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9915 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9916 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9917 {
9918 ielen = ptr[1] + 2;
9919 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9920 {
9921 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9922 *total_ielen += ielen;
9923 }
9924 else
9925 {
9926 hddLog( VOS_TRACE_LEVEL_ERROR,
9927 "IE Length is too big "
9928 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9929 elem_id, elem_len, *total_ielen);
9930 }
9931 }
9932 }
9933
9934 left -= elem_len;
9935 ptr += (elem_len + 2);
9936 }
9937 return;
9938}
9939
Kapil Gupta137ef892016-12-13 19:38:00 +05309940int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009941{
9942 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309943 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009944 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009945 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309946 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009947
9948 genie = vos_mem_malloc(MAX_GENIE_LEN);
9949
9950 if(genie == NULL) {
9951
9952 return -ENOMEM;
9953 }
9954
Kapil Gupta137ef892016-12-13 19:38:00 +05309955 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309956 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9957 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009958 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309959 hddLog(LOGE,
9960 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309961 ret = -EINVAL;
9962 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009963 }
9964
9965#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309966 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9967 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9968 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309969 hddLog(LOGE,
9970 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309971 ret = -EINVAL;
9972 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009973 }
9974#endif
9975
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309976 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9977 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009978 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309979 hddLog(LOGE,
9980 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309981 ret = -EINVAL;
9982 goto done;
9983 }
9984
9985 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9986 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009987 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009988 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009989
9990 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9991 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9992 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9993 {
9994 hddLog(LOGE,
9995 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009996 ret = -EINVAL;
9997 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009998 }
9999
10000 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10001 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10002 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10003 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10004 ==eHAL_STATUS_FAILURE)
10005 {
10006 hddLog(LOGE,
10007 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010008 ret = -EINVAL;
10009 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010010 }
10011
10012 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +053010013 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010014 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010015 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -070010016 u8 probe_rsp_ie_len[3] = {0};
10017 u8 counter = 0;
10018 /* Check Probe Resp Length if it is greater then 255 then Store
10019 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
10020 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
10021 Store More then 255 bytes into One Variable.
10022 */
10023 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
10024 {
10025 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
10026 {
10027 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
10028 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
10029 }
10030 else
10031 {
10032 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
10033 rem_probe_resp_ie_len = 0;
10034 }
10035 }
10036
10037 rem_probe_resp_ie_len = 0;
10038
10039 if (probe_rsp_ie_len[0] > 0)
10040 {
10041 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10042 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +053010043 (tANI_U8*)&pBeacon->
10044 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010045 probe_rsp_ie_len[0], NULL,
10046 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10047 {
10048 hddLog(LOGE,
10049 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010050 ret = -EINVAL;
10051 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010052 }
10053 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10054 }
10055
10056 if (probe_rsp_ie_len[1] > 0)
10057 {
10058 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10059 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +053010060 (tANI_U8*)&pBeacon->
10061 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010062 probe_rsp_ie_len[1], NULL,
10063 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10064 {
10065 hddLog(LOGE,
10066 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010067 ret = -EINVAL;
10068 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010069 }
10070 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10071 }
10072
10073 if (probe_rsp_ie_len[2] > 0)
10074 {
10075 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10076 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +053010077 (tANI_U8*)&pBeacon->
10078 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010079 probe_rsp_ie_len[2], NULL,
10080 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10081 {
10082 hddLog(LOGE,
10083 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010084 ret = -EINVAL;
10085 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010086 }
10087 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10088 }
10089
10090 if (probe_rsp_ie_len[1] == 0 )
10091 {
10092 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10093 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10094 eANI_BOOLEAN_FALSE) )
10095 {
10096 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010097 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010098 }
10099 }
10100
10101 if (probe_rsp_ie_len[2] == 0 )
10102 {
10103 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10104 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10105 eANI_BOOLEAN_FALSE) )
10106 {
10107 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010108 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010109 }
10110 }
10111
10112 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10113 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10114 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10115 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10116 == eHAL_STATUS_FAILURE)
10117 {
10118 hddLog(LOGE,
10119 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010120 ret = -EINVAL;
10121 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010122 }
10123 }
10124 else
10125 {
10126 // Reset WNI_CFG_PROBE_RSP Flags
10127 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
10128
10129 hddLog(VOS_TRACE_LEVEL_INFO,
10130 "%s: No Probe Response IE received in set beacon",
10131 __func__);
10132 }
10133
10134 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +053010135 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010136 {
10137 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +053010138 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
10139 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -070010140 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10141 {
10142 hddLog(LOGE,
10143 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010144 ret = -EINVAL;
10145 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010146 }
10147
10148 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10149 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
10150 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10151 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10152 == eHAL_STATUS_FAILURE)
10153 {
10154 hddLog(LOGE,
10155 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010156 ret = -EINVAL;
10157 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010158 }
10159 }
10160 else
10161 {
10162 hddLog(VOS_TRACE_LEVEL_INFO,
10163 "%s: No Assoc Response IE received in set beacon",
10164 __func__);
10165
10166 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10167 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10168 eANI_BOOLEAN_FALSE) )
10169 {
10170 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010171 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010172 }
10173 }
10174
Jeff Johnsone7245742012-09-05 17:12:55 -070010175done:
Jeff Johnson295189b2012-06-20 16:38:30 -070010176 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010177 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010178}
Jeff Johnson295189b2012-06-20 16:38:30 -070010179
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010180/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010181 * FUNCTION: wlan_hdd_validate_operation_channel
10182 * called by wlan_hdd_cfg80211_start_bss() and
10183 * wlan_hdd_cfg80211_set_channel()
10184 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010185 * channel list.
10186 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -070010187VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010188{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010189
Jeff Johnson295189b2012-06-20 16:38:30 -070010190 v_U32_t num_ch = 0;
10191 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10192 u32 indx = 0;
10193 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010194 v_U8_t fValidChannel = FALSE, count = 0;
10195 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010196
Jeff Johnson295189b2012-06-20 16:38:30 -070010197 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10198
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010199 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010200 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010201 /* Validate the channel */
10202 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010203 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010204 if ( channel == rfChannels[count].channelNum )
10205 {
10206 fValidChannel = TRUE;
10207 break;
10208 }
10209 }
10210 if (fValidChannel != TRUE)
10211 {
10212 hddLog(VOS_TRACE_LEVEL_ERROR,
10213 "%s: Invalid Channel [%d]", __func__, channel);
10214 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010215 }
10216 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010217 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010218 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010219 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10220 valid_ch, &num_ch))
10221 {
10222 hddLog(VOS_TRACE_LEVEL_ERROR,
10223 "%s: failed to get valid channel list", __func__);
10224 return VOS_STATUS_E_FAILURE;
10225 }
10226 for (indx = 0; indx < num_ch; indx++)
10227 {
10228 if (channel == valid_ch[indx])
10229 {
10230 break;
10231 }
10232 }
10233
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010234 if (indx >= num_ch)
10235 {
10236 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10237 {
10238 eCsrBand band;
10239 unsigned int freq;
10240
10241 sme_GetFreqBand(hHal, &band);
10242
10243 if (eCSR_BAND_5G == band)
10244 {
10245#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10246 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10247 {
10248 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010249 HDD_NL80211_BAND_2GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010250 }
10251 else
10252 {
10253 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010254 HDD_NL80211_BAND_5GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010255 }
10256#else
10257 freq = ieee80211_channel_to_frequency(channel);
10258#endif
10259 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
10260 return VOS_STATUS_SUCCESS;
10261 }
10262 }
10263
10264 hddLog(VOS_TRACE_LEVEL_ERROR,
10265 "%s: Invalid Channel [%d]", __func__, channel);
10266 return VOS_STATUS_E_FAILURE;
10267 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010268 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010269
Jeff Johnson295189b2012-06-20 16:38:30 -070010270 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010271
Jeff Johnson295189b2012-06-20 16:38:30 -070010272}
10273
Viral Modi3a32cc52013-02-08 11:14:52 -080010274/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010275 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -080010276 * This function is used to set the channel number
10277 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010278static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -080010279 struct ieee80211_channel *chan,
10280 enum nl80211_channel_type channel_type
10281 )
10282{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010283 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -080010284 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -070010285 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -080010286 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010287 hdd_context_t *pHddCtx;
10288 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010289
10290 ENTER();
10291
10292 if( NULL == dev )
10293 {
10294 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010295 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010296 return -ENODEV;
10297 }
10298 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010299
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010300 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10301 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10302 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010303 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010304 "%s: device_mode = %s (%d) freq = %d", __func__,
10305 hdd_device_modetoString(pAdapter->device_mode),
10306 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010307
10308 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10309 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010310 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010311 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010312 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010313 }
10314
10315 /*
10316 * Do freq to chan conversion
10317 * TODO: for 11a
10318 */
10319
10320 channel = ieee80211_frequency_to_channel(freq);
10321
10322 /* Check freq range */
10323 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10324 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10325 {
10326 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010327 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010328 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10329 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10330 return -EINVAL;
10331 }
10332
10333 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10334
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010335 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10336 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010337 {
10338 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10339 {
10340 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010341 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010342 return -EINVAL;
10343 }
10344 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10345 "%s: set channel to [%d] for device mode =%d",
10346 __func__, channel,pAdapter->device_mode);
10347 }
10348 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010349 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010350 )
10351 {
10352 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10353 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10354 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10355
10356 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10357 {
10358 /* Link is up then return cant set channel*/
10359 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010360 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010361 return -EINVAL;
10362 }
10363
10364 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10365 pHddStaCtx->conn_info.operationChannel = channel;
10366 pRoamProfile->ChannelInfo.ChannelList =
10367 &pHddStaCtx->conn_info.operationChannel;
10368 }
10369 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010370 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010371 )
10372 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010373 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10374 {
10375 if(VOS_STATUS_SUCCESS !=
10376 wlan_hdd_validate_operation_channel(pAdapter,channel))
10377 {
10378 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010379 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010380 return -EINVAL;
10381 }
10382 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10383 }
10384 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010385 {
10386 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10387
10388 /* If auto channel selection is configured as enable/ 1 then ignore
10389 channel set by supplicant
10390 */
10391 if ( cfg_param->apAutoChannelSelection )
10392 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010393 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10394 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010395 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010396 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10397 __func__, hdd_device_modetoString(pAdapter->device_mode),
10398 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010399 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010400 else
10401 {
10402 if(VOS_STATUS_SUCCESS !=
10403 wlan_hdd_validate_operation_channel(pAdapter,channel))
10404 {
10405 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010406 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010407 return -EINVAL;
10408 }
10409 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10410 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010411 }
10412 }
10413 else
10414 {
10415 hddLog(VOS_TRACE_LEVEL_FATAL,
10416 "%s: Invalid device mode failed to set valid channel", __func__);
10417 return -EINVAL;
10418 }
10419 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010420 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010421}
10422
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010423static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10424 struct net_device *dev,
10425 struct ieee80211_channel *chan,
10426 enum nl80211_channel_type channel_type
10427 )
10428{
10429 int ret;
10430
10431 vos_ssr_protect(__func__);
10432 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10433 vos_ssr_unprotect(__func__);
10434
10435 return ret;
10436}
10437
Anurag Chouhan83026002016-12-13 22:46:21 +053010438#ifdef DHCP_SERVER_OFFLOAD
10439void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10440 VOS_STATUS status)
10441{
10442 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10443
10444 ENTER();
10445
10446 if (NULL == adapter)
10447 {
10448 hddLog(VOS_TRACE_LEVEL_ERROR,
10449 "%s: adapter is NULL",__func__);
10450 return;
10451 }
10452
10453 adapter->dhcp_status.dhcp_offload_status = status;
10454 vos_event_set(&adapter->dhcp_status.vos_event);
10455 return;
10456}
10457
10458/**
10459 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10460 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010461 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010462 *
10463 * Return: None
10464 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010465VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10466 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010467{
10468 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10469 sir_dhcp_srv_offload_info dhcp_srv_info;
10470 tANI_U8 num_entries = 0;
10471 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10472 tANI_U8 num;
10473 tANI_U32 temp;
10474 VOS_STATUS ret;
10475
10476 ENTER();
10477
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010478 if (!re_init) {
10479 ret = wlan_hdd_validate_context(hdd_ctx);
10480 if (0 != ret)
10481 return VOS_STATUS_E_INVAL;
10482 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010483
10484 /* Prepare the request to send to SME */
10485 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10486 if (NULL == dhcp_srv_info) {
10487 hddLog(VOS_TRACE_LEVEL_ERROR,
10488 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10489 return VOS_STATUS_E_NOMEM;
10490 }
10491
10492 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10493
10494 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10495 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10496 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10497 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10498 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10499 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10500
10501 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10502 srv_ip,
10503 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010504 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010505 if (num_entries != IPADDR_NUM_ENTRIES) {
10506 hddLog(VOS_TRACE_LEVEL_ERROR,
10507 "%s: incorrect IP address (%s) assigned for DHCP server!",
10508 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10509 vos_mem_free(dhcp_srv_info);
10510 return VOS_STATUS_E_FAILURE;
10511 }
10512
10513 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10514 hddLog(VOS_TRACE_LEVEL_ERROR,
10515 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10516 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10517 vos_mem_free(dhcp_srv_info);
10518 return VOS_STATUS_E_FAILURE;
10519 }
10520
10521 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10522 hddLog(VOS_TRACE_LEVEL_ERROR,
10523 "%s: invalid IP address (%s)! The last field must be less than 100!",
10524 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10525 vos_mem_free(dhcp_srv_info);
10526 return VOS_STATUS_E_FAILURE;
10527 }
10528
10529 for (num = 0; num < num_entries; num++) {
10530 temp = srv_ip[num];
10531 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10532 }
10533
10534 if (eHAL_STATUS_SUCCESS !=
10535 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10536 hddLog(VOS_TRACE_LEVEL_ERROR,
10537 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10538 vos_mem_free(dhcp_srv_info);
10539 return VOS_STATUS_E_FAILURE;
10540 }
10541
10542 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10543 "%s: enable DHCP Server offload successfully!", __func__);
10544
10545 vos_mem_free(dhcp_srv_info);
10546 return 0;
10547}
10548#endif /* DHCP_SERVER_OFFLOAD */
10549
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010550/*
10551 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10552 * @wiphy_chan: wiphy channel number
10553 * @rfChannel: channel hw value
10554 * @disable: Disable/enable the flags
10555 *
10556 * Modify wiphy flags and cds state if channel is indoor.
10557 *
10558 * Return: void
10559 */
10560void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
10561 v_U32_t rfChannel, bool disable)
10562{
10563 v_U32_t channelLoop;
10564 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10565
10566 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10567
10568 if (rfChannels[channelLoop].channelNum == rfChannel) {
10569 channelEnum = (eRfChannels)channelLoop;
10570 break;
10571 }
10572 }
10573
10574 if (INVALID_RF_CHANNEL == channelEnum)
10575 return;
10576
10577 if (disable) {
10578 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10579 wiphy_chan->flags |=
10580 IEEE80211_CHAN_DISABLED;
10581 regChannels[channelEnum].enabled =
10582 NV_CHANNEL_DISABLE;
10583 }
10584 } else {
10585 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10586 wiphy_chan->flags &=
10587 ~IEEE80211_CHAN_DISABLED;
10588 /*
10589 * Indoor channels are marked as DFS
10590 * during regulatory processing
10591 */
10592
10593 regChannels[channelEnum].enabled =
10594 NV_CHANNEL_DFS;
10595 }
10596 }
10597
10598}
10599
10600void hdd_update_indoor_channel(hdd_context_t *hdd_ctx,
10601 bool disable)
10602{
10603 int band_num;
10604 int chan_num;
10605 v_U32_t rfChannel;
10606 struct ieee80211_channel *wiphy_chan;
10607 struct wiphy *wiphy;
10608
10609 ENTER();
10610 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10611
10612 wiphy = hdd_ctx->wiphy;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010613 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010614
10615 if (wiphy->bands[band_num] == NULL)
10616 continue;
10617
10618 for (chan_num = 0;
10619 chan_num < wiphy->bands[band_num]->n_channels;
10620 chan_num++) {
10621
10622 wiphy_chan =
10623 &(wiphy->bands[band_num]->channels[chan_num]);
10624 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10625
10626 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
10627 disable);
10628 }
10629 }
10630 EXIT();
10631}
10632
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010633/*
10634 * FUNCTION: wlan_hdd_disconnect
10635 * This function is used to issue a disconnect request to SME
10636 */
10637int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10638{
10639 int status, result = 0;
10640 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10641 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10642 long ret;
10643 eConnectionState prev_conn_state;
10644 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
10645
10646 ENTER();
10647
10648 status = wlan_hdd_validate_context(pHddCtx);
10649 if (0 != status)
10650 {
10651 return status;
10652 }
10653 /* Indicate sme of disconnect so that in progress connection or preauth
10654 * can be aborted
10655 */
10656 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10657 pAdapter->sessionId);
10658 pHddCtx->isAmpAllowed = VOS_TRUE;
10659
10660 /* Need to apply spin lock before decreasing active sessions
10661 * as there can be chance for double decrement if context switch
10662 * Calls hdd_DisConnectHandler.
10663 */
10664
10665 prev_conn_state = pHddStaCtx->conn_info.connState;
10666
10667 spin_lock_bh(&pAdapter->lock_for_active_session);
10668 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10669 {
10670 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10671 }
10672 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10673 spin_unlock_bh(&pAdapter->lock_for_active_session);
10674 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
10675
10676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10677 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10678
10679 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10680
10681 /*
10682 * stop tx queues before deleting STA/BSS context from the firmware.
10683 * tx has to be disabled because the firmware can get busy dropping
10684 * the tx frames after BSS/STA has been deleted and will not send
10685 * back a response resulting in WDI timeout
10686 */
10687 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10688 netif_tx_disable(pAdapter->dev);
10689 netif_carrier_off(pAdapter->dev);
10690
10691 wlan_hdd_check_and_stop_mon(pAdapter, true);
10692
10693 /*issue disconnect*/
10694 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10695 pAdapter->sessionId, reason);
10696 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
10697 prev_conn_state != eConnectionState_Connecting)
10698 {
10699 hddLog(LOG1,
10700 FL("status = %d, already disconnected"), status);
10701 result = 0;
10702 /*
10703 * Wait here instead of returning directly. This will block the
10704 * next connect command and allow processing of the disconnect
10705 * in SME else we might hit some race conditions leading to SME
10706 * and HDD out of sync. As disconnect is already in progress,
10707 * wait here for 1 sec instead of 5 sec.
10708 */
10709 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
10710 goto wait_for_disconnect;
10711 }
10712 /*
10713 * Wait here instead of returning directly, this will block the next
10714 * connect command and allow processing of the scan for ssid and
10715 * the previous connect command in CSR. Else we might hit some
10716 * race conditions leading to SME and HDD out of sync.
10717 */
10718 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10719 {
10720 hddLog(LOG1,
10721 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
10722 }
10723 else if ( 0 != status )
10724 {
10725 hddLog(LOGE,
10726 FL("csrRoamDisconnect failure, returned %d"),
10727 (int)status);
10728 result = -EINVAL;
10729 goto disconnected;
10730 }
10731wait_for_disconnect:
10732 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
10733 msecs_to_jiffies(wait_time));
10734 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
10735 {
10736 hddLog(LOGE,
10737 "%s: Failed to disconnect, timed out", __func__);
10738 result = -ETIMEDOUT;
10739 }
10740disconnected:
10741 hddLog(LOG1,
10742 FL("Set HDD connState to eConnectionState_NotConnected"));
10743 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10744#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
10745 /* Sending disconnect event to userspace for kernel version < 3.11
10746 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
10747 */
10748 hddLog(LOG1, FL("Send disconnected event to userspace"));
10749
10750 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
10751 WLAN_REASON_UNSPECIFIED);
10752#endif
10753
10754 EXIT();
10755 return result;
10756}
10757
10758/*
10759 * hdd_check_and_disconnect_sta_on_invalid_channel() - Disconnect STA if it is
10760 * on indoor channel
10761 * @hdd_ctx: pointer to hdd context
10762 *
10763 * STA should be disconnected before starting the SAP if it is on indoor
10764 * channel.
10765 *
10766 * Return: void
10767 */
10768void hdd_check_and_disconnect_sta_on_invalid_channel(hdd_context_t *hdd_ctx)
10769{
10770
10771 hdd_adapter_t *sta_adapter;
10772 tANI_U8 sta_chan;
10773
10774 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
10775
10776 if (!sta_chan) {
10777 hddLog(LOG1, FL("STA not connected"));
10778 return;
10779 }
10780
10781 hddLog(LOG1, FL("STA connected on chan %hu"), sta_chan);
10782
10783 if (sme_IsChannelValid(hdd_ctx->hHal, sta_chan)) {
10784 hddLog(LOG1, FL("STA connected on chan %hu and it is valid"),
10785 sta_chan);
10786 return;
10787 }
10788
10789 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
10790
10791 if (!sta_adapter) {
10792 hddLog(LOG1, FL("STA adapter doesn't exist"));
10793 return;
10794 }
10795
10796 hddLog(LOG1, FL("chan %hu not valid, issue disconnect"), sta_chan);
10797 /* Issue Disconnect request */
10798 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10799}
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010800
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010801int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx)
10802{
10803 struct hdd_cache_channels *cache_chann;
10804 struct wiphy *wiphy;
10805 int freq, status, rfChannel;
10806 int i, band_num, channel_num;
10807 struct ieee80211_channel *wiphy_channel;
10808
10809 ENTER();
10810
10811 if (!hdd_ctx) {
10812 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10813 return -EINVAL;
10814 }
10815
10816 wiphy = hdd_ctx->wiphy;
10817
10818 mutex_lock(&hdd_ctx->cache_channel_lock);
10819
10820 cache_chann = hdd_ctx->orginal_channels;
10821
10822 if (!cache_chann || !cache_chann->num_channels) {
10823 hddLog(VOS_TRACE_LEVEL_INFO,
10824 "%s channel list is NULL or num channels are zero",
10825 __func__);
10826 mutex_unlock(&hdd_ctx->cache_channel_lock);
10827 return -EINVAL;
10828 }
10829
10830 for (i = 0; i < cache_chann->num_channels; i++) {
10831 status = hdd_wlan_get_freq(
10832 cache_chann->channel_info[i].channel_num,
10833 &freq);
10834
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010835 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
10836 band_num++) {
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010837 for (channel_num = 0; channel_num <
10838 wiphy->bands[band_num]->n_channels;
10839 channel_num++) {
10840 wiphy_channel = &(wiphy->bands[band_num]->
10841 channels[channel_num]);
10842 if (wiphy_channel->center_freq == freq) {
10843 rfChannel = wiphy_channel->hw_value;
10844 /*
10845 *Restore the orginal states
10846 *of the channels
10847 */
10848 vos_nv_set_channel_state(
10849 rfChannel,
10850 cache_chann->
10851 channel_info[i].reg_status);
10852 wiphy_channel->flags =
10853 cache_chann->
10854 channel_info[i].wiphy_status;
10855 break;
10856 }
10857 }
10858 if (channel_num < wiphy->bands[band_num]->n_channels)
10859 break;
10860 }
10861 }
10862
10863 mutex_unlock(&hdd_ctx->cache_channel_lock);
10864
10865 status = sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10866 if (status)
10867 hddLog(VOS_TRACE_LEVEL_ERROR, "Can't Restore channel list");
10868 EXIT();
10869
10870 return 0;
10871}
10872
10873/*
10874 * wlan_hdd_disable_channels() - Cache the the channels
10875 * and current state of the channels from the channel list
10876 * received in the command and disable the channels on the
10877 * wiphy and NV table.
10878 * @hdd_ctx: Pointer to hdd context
10879 *
10880 * @return: 0 on success, Error code on failure
10881 */
10882
10883static int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx)
10884{
10885 struct hdd_cache_channels *cache_chann;
10886 struct wiphy *wiphy;
10887 int freq, status, rfChannel;
10888 int i, band_num, band_ch_num;
10889 struct ieee80211_channel *wiphy_channel;
10890
10891 if (!hdd_ctx) {
10892 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10893 return -EINVAL;
10894 }
10895
10896 wiphy = hdd_ctx->wiphy;
10897
10898 mutex_lock(&hdd_ctx->cache_channel_lock);
10899 cache_chann = hdd_ctx->orginal_channels;
10900
10901 if (!cache_chann || !cache_chann->num_channels) {
10902 hddLog(VOS_TRACE_LEVEL_INFO,
10903 "%s channel list is NULL or num channels are zero",
10904 __func__);
10905 mutex_unlock(&hdd_ctx->cache_channel_lock);
10906 return -EINVAL;
10907 }
10908
10909 for (i = 0; i < cache_chann->num_channels; i++) {
10910 status = hdd_wlan_get_freq(
10911 cache_chann->channel_info[i].channel_num,
10912 &freq);
10913
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010914 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010915 band_num++) {
10916 for (band_ch_num = 0; band_ch_num <
10917 wiphy->bands[band_num]->n_channels;
10918 band_ch_num++) {
10919 wiphy_channel = &(wiphy->bands[band_num]->
10920 channels[band_ch_num]);
10921 if (wiphy_channel->center_freq == freq) {
10922 rfChannel = wiphy_channel->hw_value;
10923 /*
10924 * Cache the current states of
10925 * the channels
10926 */
10927 cache_chann->
10928 channel_info[i].reg_status =
10929 vos_nv_getChannelEnabledState(
10930 rfChannel);
10931
10932 cache_chann->
10933 channel_info[i].wiphy_status =
10934 wiphy_channel->flags;
10935 hddLog(VOS_TRACE_LEVEL_INFO,
10936 "Disable channel %d reg_stat %d wiphy_stat 0x%x",
10937 cache_chann->
10938 channel_info[i].channel_num,
10939 cache_chann->
10940 channel_info[i].reg_status,
10941 wiphy_channel->flags);
10942
10943 vos_nv_set_channel_state(
10944 rfChannel,
10945 NV_CHANNEL_DISABLE);
10946 wiphy_channel->flags |=
10947 IEEE80211_CHAN_DISABLED;
10948 break;
10949 }
10950 }
10951 if (band_ch_num < wiphy->bands[band_num]->n_channels)
10952 break;
10953 }
10954 }
10955
10956 mutex_unlock(&hdd_ctx->cache_channel_lock);
10957 sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10958 return 0;
10959}
10960
Jeff Johnson295189b2012-06-20 16:38:30 -070010961#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10962static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10963 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010964#else
10965static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10966 struct cfg80211_beacon_data *params,
10967 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010968 enum nl80211_hidden_ssid hidden_ssid,
10969 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010970#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010971{
10972 tsap_Config_t *pConfig;
10973 beacon_data_t *pBeacon = NULL;
10974 struct ieee80211_mgmt *pMgmt_frame;
10975 v_U8_t *pIe=NULL;
10976 v_U16_t capab_info;
10977 eCsrAuthType RSNAuthType;
10978 eCsrEncryptionType RSNEncryptType;
10979 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010980 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010981 tpWLAN_SAPEventCB pSapEventCallback;
10982 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070010983 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010984 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010985 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010986 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070010987 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080010988 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +053010989 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070010990 v_BOOL_t MFPCapable = VOS_FALSE;
10991 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010992 v_BOOL_t sapEnable11AC =
10993 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053010994 u_int16_t prev_rsn_length = 0;
10995
Jeff Johnson295189b2012-06-20 16:38:30 -070010996 ENTER();
10997
Nitesh Shah9b066282017-06-06 18:05:52 +053010998 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010999 iniConfig = pHddCtx->cfg_ini;
11000
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011001 /* Mark the indoor channel (passive) to disable */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011002 if (iniConfig->disable_indoor_channel &&
11003 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011004 hdd_update_indoor_channel(pHddCtx, true);
11005
11006 if (!VOS_IS_STATUS_SUCCESS(
11007 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
11008 hdd_update_indoor_channel(pHddCtx, false);
11009 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
11010 FL("Can't start BSS: update channel list failed"));
11011 return eHAL_STATUS_FAILURE;
11012 }
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053011013
11014 /* check if STA is on indoor channel */
11015 if (hdd_is_sta_sap_scc_allowed_on_dfs_chan(pHddCtx))
11016 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011017 }
11018
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011019 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
11020 /* Disable the channels received in command SET_DISABLE_CHANNEL_LIST*/
11021 wlan_hdd_disable_channels(pHddCtx);
11022 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
11023 }
11024
Jeff Johnson295189b2012-06-20 16:38:30 -070011025 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
11026
11027 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
11028
11029 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
11030
11031 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
11032
11033 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
11034
11035 //channel is already set in the set_channel Call back
11036 //pConfig->channel = pCommitConfig->channel;
11037
11038 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011039 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070011040 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
11041
11042 pConfig->dtim_period = pBeacon->dtim_period;
11043
Arif Hussain6d2a3322013-11-17 19:50:10 -080011044 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070011045 pConfig->dtim_period);
11046
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080011047 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070011048 {
11049 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011050 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053011051 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
11052 {
11053 tANI_BOOLEAN restartNeeded;
11054 pConfig->ieee80211d = 1;
11055 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
11056 sme_setRegInfo(hHal, pConfig->countryCode);
11057 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
11058 }
11059 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070011060 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070011061 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070011062 pConfig->ieee80211d = 1;
11063 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
11064 sme_setRegInfo(hHal, pConfig->countryCode);
11065 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070011066 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011067 else
11068 {
11069 pConfig->ieee80211d = 0;
11070 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011071 /*
11072 * If auto channel is configured i.e. channel is 0,
11073 * so skip channel validation.
11074 */
11075 if( AUTO_CHANNEL_SELECT != pConfig->channel )
11076 {
11077 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
11078 {
11079 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011080 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011081 ret = -EINVAL;
11082 goto error;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011083 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011084 pConfig->user_config_channel = pConfig->channel;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011085 }
11086 else
11087 {
11088 if(1 != pHddCtx->is_dynamic_channel_range_set)
11089 {
11090 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
11091 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
11092 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
11093 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011094 pHddCtx->is_dynamic_channel_range_set = 0;
11095 pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011096 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011097 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011098 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011099 {
11100 pConfig->ieee80211d = 0;
11101 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011102
11103#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11104 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11105 pConfig->authType = eSAP_OPEN_SYSTEM;
11106 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11107 pConfig->authType = eSAP_SHARED_KEY;
11108 else
11109 pConfig->authType = eSAP_AUTO_SWITCH;
11110#else
11111 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11112 pConfig->authType = eSAP_OPEN_SYSTEM;
11113 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11114 pConfig->authType = eSAP_SHARED_KEY;
11115 else
11116 pConfig->authType = eSAP_AUTO_SWITCH;
11117#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011118
11119 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011120
11121 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070011122 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053011123#ifdef SAP_AUTH_OFFLOAD
11124 /* In case of sap offload, hostapd.conf is configuted with open mode and
11125 * security is configured from ini file. Due to open mode in hostapd.conf
11126 * privacy bit is set to false which will result in not sending,
11127 * data packets as encrypted.
11128 * If enable_sap_auth_offload is enabled in ini and
11129 * sap_auth_offload_sec_type is type of WPA2-PSK,
11130 * driver will set privacy bit to 1.
11131 */
11132 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
11133 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
11134 pConfig->privacy = VOS_TRUE;
11135#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011136
11137 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
11138
11139 /*Set wps station to configured*/
11140 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
11141
11142 if(pIe)
11143 {
11144 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
11145 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011146 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011147 ret = -EINVAL;
11148 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011149 }
11150 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
11151 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070011152 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070011153 /* Check 15 bit of WPS IE as it contain information for wps state
11154 * WPS state
11155 */
11156 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
11157 {
11158 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
11159 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
11160 {
11161 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
11162 }
11163 }
11164 }
11165 else
11166 {
11167 pConfig->wps_state = SAP_WPS_DISABLED;
11168 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011169 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070011170
c_hpothufe599e92014-06-16 11:38:55 +053011171 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11172 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11173 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
11174 eCSR_ENCRYPT_TYPE_NONE;
11175
Jeff Johnson295189b2012-06-20 16:38:30 -070011176 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053011177 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011178 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011179 WLAN_EID_RSN);
11180 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011181 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011182 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011183 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11184 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11185 pConfig->RSNWPAReqIELength);
11186 else
11187 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11188 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011189 /* The actual processing may eventually be more extensive than
11190 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070011191 * by the app.
11192 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011193 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011194 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11195 &RSNEncryptType,
11196 &mcRSNEncryptType,
11197 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011198 &MFPCapable,
11199 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011200 pConfig->RSNWPAReqIE[1]+2,
11201 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011202
11203 if( VOS_STATUS_SUCCESS == status )
11204 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011205 /* Now copy over all the security attributes you have
11206 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011207 * */
11208 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11209 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11210 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11211 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011212 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011213 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011214 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11215 }
11216 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011217
Jeff Johnson295189b2012-06-20 16:38:30 -070011218 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11219 pBeacon->tail, pBeacon->tail_len);
11220
11221 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
11222 {
Kapil Gupta137ef892016-12-13 19:38:00 +053011223 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011224 {
11225 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053011226 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070011227 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011228 if (pConfig->RSNWPAReqIELength <=
11229 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
11230 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
11231 pIe[1] + 2);
11232 else
11233 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11234 pConfig->RSNWPAReqIELength);
11235
Jeff Johnson295189b2012-06-20 16:38:30 -070011236 }
11237 else
11238 {
11239 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011240 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11241 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11242 pConfig->RSNWPAReqIELength);
11243 else
11244 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11245 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011246 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011247 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11248 &RSNEncryptType,
11249 &mcRSNEncryptType,
11250 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011251 &MFPCapable,
11252 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011253 pConfig->RSNWPAReqIE[1]+2,
11254 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011255
11256 if( VOS_STATUS_SUCCESS == status )
11257 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011258 /* Now copy over all the security attributes you have
11259 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011260 * */
11261 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11262 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11263 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11264 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011265 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011266 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011267 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11268 }
11269 }
11270 }
11271
Kapil Gupta137ef892016-12-13 19:38:00 +053011272 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070011273 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011274 ret = -EINVAL;
11275 goto error;
Jeff Johnson4416a782013-03-25 14:17:50 -070011276 }
11277
Jeff Johnson295189b2012-06-20 16:38:30 -070011278 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
11279
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011280#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011281 if (params->ssid != NULL)
11282 {
11283 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
11284 pConfig->SSIDinfo.ssid.length = params->ssid_len;
11285 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11286 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11287 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011288#else
11289 if (ssid != NULL)
11290 {
11291 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
11292 pConfig->SSIDinfo.ssid.length = ssid_len;
11293 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11294 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11295 }
11296#endif
11297
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011298 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070011299 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011300
Jeff Johnson295189b2012-06-20 16:38:30 -070011301 /* default value */
11302 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
11303 pConfig->num_accept_mac = 0;
11304 pConfig->num_deny_mac = 0;
11305
11306 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11307 pBeacon->tail, pBeacon->tail_len);
11308
11309 /* pIe for black list is following form:
11310 type : 1 byte
11311 length : 1 byte
11312 OUI : 4 bytes
11313 acl type : 1 byte
11314 no of mac addr in black list: 1 byte
11315 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011316 */
11317 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011318 {
11319 pConfig->SapMacaddr_acl = pIe[6];
11320 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011321 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011322 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011323 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
11324 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011325 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11326 for (i = 0; i < pConfig->num_deny_mac; i++)
11327 {
11328 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11329 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011330 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011331 }
11332 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11333 pBeacon->tail, pBeacon->tail_len);
11334
11335 /* pIe for white list is following form:
11336 type : 1 byte
11337 length : 1 byte
11338 OUI : 4 bytes
11339 acl type : 1 byte
11340 no of mac addr in white list: 1 byte
11341 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011342 */
11343 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011344 {
11345 pConfig->SapMacaddr_acl = pIe[6];
11346 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011347 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011348 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011349 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
11350 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011351 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11352 for (i = 0; i < pConfig->num_accept_mac; i++)
11353 {
11354 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11355 acl_entry++;
11356 }
11357 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011358
Jeff Johnson295189b2012-06-20 16:38:30 -070011359 wlan_hdd_set_sapHwmode(pHostapdAdapter);
11360
Jeff Johnsone7245742012-09-05 17:12:55 -070011361#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011362 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011363 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
11364 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053011365 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
11366 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011367 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
11368 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011369 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
11370 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070011371 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011372 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070011373 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011374 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011375
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011376 /* If ACS disable and selected channel <= 14
11377 * OR
11378 * ACS enabled and ACS operating band is choosen as 2.4
11379 * AND
11380 * VHT in 2.4G Disabled
11381 * THEN
11382 * Fallback to 11N mode
11383 */
11384 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
11385 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053011386 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011387 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011388 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011389 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
11390 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011391 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
11392 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011393 }
11394#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011395
Jeff Johnson295189b2012-06-20 16:38:30 -070011396 // ht_capab is not what the name conveys,this is used for protection bitmap
11397 pConfig->ht_capab =
11398 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
11399
Kapil Gupta137ef892016-12-13 19:38:00 +053011400 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070011401 {
11402 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011403 ret = -EINVAL;
11404 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011405 }
11406
11407 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011408 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070011409 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
11410 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011411 pConfig->obssProtEnabled =
11412 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070011413
Chet Lanctot8cecea22014-02-11 19:09:36 -080011414#ifdef WLAN_FEATURE_11W
11415 pConfig->mfpCapable = MFPCapable;
11416 pConfig->mfpRequired = MFPRequired;
11417 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
11418 pConfig->mfpCapable, pConfig->mfpRequired);
11419#endif
11420
Arif Hussain6d2a3322013-11-17 19:50:10 -080011421 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070011422 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011423 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
11424 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
11425 (int)pConfig->channel);
11426 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
11427 pConfig->SapHw_mode, pConfig->privacy,
11428 pConfig->authType);
11429 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
11430 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
11431 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
11432 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070011433
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011434 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070011435 {
11436 //Bss already started. just return.
11437 //TODO Probably it should update some beacon params.
11438 hddLog( LOGE, "Bss Already started...Ignore the request");
11439 EXIT();
11440 return 0;
11441 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011442
Agarwal Ashish51325b52014-06-16 16:50:49 +053011443 if (vos_max_concurrent_connections_reached()) {
11444 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011445 ret = -EINVAL;
11446 goto error;
Agarwal Ashish51325b52014-06-16 16:50:49 +053011447 }
11448
Jeff Johnson295189b2012-06-20 16:38:30 -070011449 pConfig->persona = pHostapdAdapter->device_mode;
11450
Peng Xu2446a892014-09-05 17:21:18 +053011451 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
11452 if ( NULL != psmeConfig)
11453 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011454 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053011455 sme_GetConfigParam(hHal, psmeConfig);
11456 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011457#ifdef WLAN_FEATURE_AP_HT40_24G
11458 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11459 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
11460 && pHddCtx->cfg_ini->apHT40_24GEnabled)
11461 {
11462 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
11463 sme_UpdateConfig (hHal, psmeConfig);
11464 }
11465#endif
Peng Xu2446a892014-09-05 17:21:18 +053011466 vos_mem_free(psmeConfig);
11467 }
Peng Xuafc34e32014-09-25 13:23:55 +053011468 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053011469
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011470 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
11471
Jeff Johnson295189b2012-06-20 16:38:30 -070011472 pSapEventCallback = hdd_hostapd_SAPEventCB;
11473 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
11474 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
11475 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011476 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011477 ret = -EINVAL;
11478 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011479 }
11480
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011481 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070011482 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
11483
11484 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011485
Jeff Johnson295189b2012-06-20 16:38:30 -070011486 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011487 {
11488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011489 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070011490 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011491 VOS_ASSERT(0);
11492 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011493
Jeff Johnson295189b2012-06-20 16:38:30 -070011494 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053011495 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
11496 VOS_STATUS_SUCCESS)
11497 {
11498 hddLog(LOGE,FL("Fail to get Softap sessionID"));
11499 VOS_ASSERT(0);
11500 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053011501 /* Initialize WMM configuation */
11502 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011503 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011504
Anurag Chouhan83026002016-12-13 22:46:21 +053011505#ifdef DHCP_SERVER_OFFLOAD
11506 /* set dhcp server offload */
11507 if (iniConfig->enable_dhcp_srv_offload &&
11508 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011509 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053011510 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053011511 if (!VOS_IS_STATUS_SUCCESS(status))
11512 {
11513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11514 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011515 vos_event_reset(&pHostapdState->vosEvent);
11516 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11517 status = vos_wait_single_event(&pHostapdState->vosEvent,
11518 10000);
11519 if (!VOS_IS_STATUS_SUCCESS(status)) {
11520 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011521 ret = -EINVAL;
11522 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011523 }
11524 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011525 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011526 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
11527 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
11528 {
11529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11530 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
11531 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011532 vos_event_reset(&pHostapdState->vosEvent);
11533 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11534 status = vos_wait_single_event(&pHostapdState->vosEvent,
11535 10000);
11536 if (!VOS_IS_STATUS_SUCCESS(status)) {
11537 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011538 ret = -EINVAL;
11539 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011540 }
11541 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011542 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011543#ifdef MDNS_OFFLOAD
11544 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011545 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011546 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
11547 if (VOS_IS_STATUS_SUCCESS(status))
11548 {
11549 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11550 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011551 vos_event_reset(&pHostapdState->vosEvent);
11552 if (VOS_STATUS_SUCCESS ==
11553 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11554 status = vos_wait_single_event(&pHostapdState->vosEvent,
11555 10000);
11556 if (!VOS_IS_STATUS_SUCCESS(status)) {
11557 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011558 ret = -EINVAL;
11559 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011560 }
11561 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011562 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011563 status = vos_wait_single_event(&pHostapdAdapter->
11564 mdns_status.vos_event, 2000);
11565 if (!VOS_IS_STATUS_SUCCESS(status) ||
11566 pHostapdAdapter->mdns_status.mdns_enable_status ||
11567 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
11568 pHostapdAdapter->mdns_status.mdns_resp_status)
11569 {
11570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11571 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
11572 pHostapdAdapter->mdns_status.mdns_enable_status,
11573 pHostapdAdapter->mdns_status.mdns_fqdn_status,
11574 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011575 vos_event_reset(&pHostapdState->vosEvent);
11576 if (VOS_STATUS_SUCCESS ==
11577 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11578 status = vos_wait_single_event(&pHostapdState->vosEvent,
11579 10000);
11580 if (!VOS_IS_STATUS_SUCCESS(status)) {
11581 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011582 ret = -EINVAL;
11583 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011584 }
11585 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011586 }
11587 }
11588#endif /* MDNS_OFFLOAD */
11589 } else {
11590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11591 ("DHCP Disabled ini %d, FW %d"),
11592 iniConfig->enable_dhcp_srv_offload,
11593 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053011594 }
11595#endif /* DHCP_SERVER_OFFLOAD */
11596
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011597#ifdef WLAN_FEATURE_P2P_DEBUG
11598 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
11599 {
11600 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
11601 {
11602 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11603 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011604 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011605 }
11606 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
11607 {
11608 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11609 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011610 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011611 }
11612 }
11613#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053011614 /* Check and restart SAP if it is on Unsafe channel */
11615 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011616
Jeff Johnson295189b2012-06-20 16:38:30 -070011617 pHostapdState->bCommit = TRUE;
11618 EXIT();
11619
11620 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011621error:
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011622 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11623 wlan_hdd_restore_channels(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011624 /* Revert the indoor to passive marking if START BSS fails */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011625 if (iniConfig->disable_indoor_channel &&
11626 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011627 hdd_update_indoor_channel(pHddCtx, false);
11628 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
11629 }
11630
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011631 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
11632 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011633}
11634
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011635#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011636static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011637 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011638 struct beacon_parameters *params)
11639{
11640 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011641 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011642 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011643
11644 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011645
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011646 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11647 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11648 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011649 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11650 hdd_device_modetoString(pAdapter->device_mode),
11651 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011652
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011653 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11654 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011655 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011656 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011657 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011658 }
11659
Agarwal Ashish51325b52014-06-16 16:50:49 +053011660 if (vos_max_concurrent_connections_reached()) {
11661 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11662 return -EINVAL;
11663 }
11664
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011665 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011666 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011667 )
11668 {
11669 beacon_data_t *old,*new;
11670
11671 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011672
Jeff Johnson295189b2012-06-20 16:38:30 -070011673 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011674 {
11675 hddLog(VOS_TRACE_LEVEL_WARN,
11676 FL("already beacon info added to session(%d)"),
11677 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011678 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011679 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011680
11681 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11682
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011683 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011684 {
11685 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011686 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011687 return -EINVAL;
11688 }
11689
11690 pAdapter->sessionCtx.ap.beacon = new;
11691
11692 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11693 }
11694
11695 EXIT();
11696 return status;
11697}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011698
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011699static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11700 struct net_device *dev,
11701 struct beacon_parameters *params)
11702{
11703 int ret;
11704
11705 vos_ssr_protect(__func__);
11706 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11707 vos_ssr_unprotect(__func__);
11708
11709 return ret;
11710}
11711
11712static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011713 struct net_device *dev,
11714 struct beacon_parameters *params)
11715{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011716 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011717 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11718 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011719 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011720
11721 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011722
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011723 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11724 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11725 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11726 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11727 __func__, hdd_device_modetoString(pAdapter->device_mode),
11728 pAdapter->device_mode);
11729
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011730 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11731 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011732 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011733 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011734 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011735 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011736
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011737 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011738 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011739 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011740 {
11741 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011742
Jeff Johnson295189b2012-06-20 16:38:30 -070011743 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011744
Jeff Johnson295189b2012-06-20 16:38:30 -070011745 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011746 {
11747 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11748 FL("session(%d) old and new heads points to NULL"),
11749 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011750 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011751 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011752
11753 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11754
11755 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011756 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011757 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011758 return -EINVAL;
11759 }
11760
11761 pAdapter->sessionCtx.ap.beacon = new;
11762
11763 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11764 }
11765
11766 EXIT();
11767 return status;
11768}
11769
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011770static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11771 struct net_device *dev,
11772 struct beacon_parameters *params)
11773{
11774 int ret;
11775
11776 vos_ssr_protect(__func__);
11777 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11778 vos_ssr_unprotect(__func__);
11779
11780 return ret;
11781}
11782
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011783#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11784
11785#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011786static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011787 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011788#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011789static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011790 struct net_device *dev)
11791#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011792{
11793 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070011794 hdd_context_t *pHddCtx = NULL;
11795 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011796 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011797 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011798
11799 ENTER();
11800
11801 if (NULL == pAdapter)
11802 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011804 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011805 return -ENODEV;
11806 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011807
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011808 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11809 TRACE_CODE_HDD_CFG80211_STOP_AP,
11810 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011811 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11812 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011813 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011814 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011815 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011816 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011817
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011818 pScanInfo = &pHddCtx->scan_info;
11819
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011820 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11821 __func__, hdd_device_modetoString(pAdapter->device_mode),
11822 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011823
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011824 ret = wlan_hdd_scan_abort(pAdapter);
11825
Girish Gowli4bf7a632014-06-12 13:42:11 +053011826 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011827 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011828 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11829 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011830
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011831 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011832 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11834 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011835
Jeff Johnsone7245742012-09-05 17:12:55 -070011836 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011837 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011838 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011839 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011840 }
11841
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011842 /* Delete all associated STAs before stopping AP/P2P GO */
11843 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011844 hdd_hostapd_stop(dev);
11845
Jeff Johnson295189b2012-06-20 16:38:30 -070011846 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011847 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011848 )
11849 {
11850 beacon_data_t *old;
11851
11852 old = pAdapter->sessionCtx.ap.beacon;
11853
11854 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011855 {
11856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11857 FL("session(%d) beacon data points to NULL"),
11858 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011859 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011860 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011861
Jeff Johnson295189b2012-06-20 16:38:30 -070011862 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011863
11864 mutex_lock(&pHddCtx->sap_lock);
11865 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11866 {
Abhishek Singh10e17cf2018-03-12 14:34:22 +053011867 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
11868 hdd_wait_for_ecsa_complete(pHddCtx);
Jeff Johnson4416a782013-03-25 14:17:50 -070011869 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011870 {
11871 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11872
11873 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11874
11875 if (!VOS_IS_STATUS_SUCCESS(status))
11876 {
11877 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011878 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011879 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011880 }
11881 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011882 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011883 /* BSS stopped, clear the active sessions for this device mode */
11884 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011885 }
11886 mutex_unlock(&pHddCtx->sap_lock);
11887
11888 if(status != VOS_STATUS_SUCCESS)
11889 {
11890 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011891 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011892 return -EINVAL;
11893 }
11894
Jeff Johnson4416a782013-03-25 14:17:50 -070011895 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011896 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11897 ==eHAL_STATUS_FAILURE)
11898 {
11899 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011900 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011901 }
11902
Jeff Johnson4416a782013-03-25 14:17:50 -070011903 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011904 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11905 eANI_BOOLEAN_FALSE) )
11906 {
11907 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011908 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011909 }
11910
11911 // Reset WNI_CFG_PROBE_RSP Flags
11912 wlan_hdd_reset_prob_rspies(pAdapter);
11913
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011914 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11915
Jeff Johnson295189b2012-06-20 16:38:30 -070011916 pAdapter->sessionCtx.ap.beacon = NULL;
11917 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011918#ifdef WLAN_FEATURE_P2P_DEBUG
11919 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11920 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11921 {
11922 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11923 "GO got removed");
11924 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11925 }
11926#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011927 }
11928 EXIT();
11929 return status;
11930}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011931
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011932#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11933static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
11934 struct net_device *dev)
11935{
11936 int ret;
11937
11938 vos_ssr_protect(__func__);
11939 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
11940 vos_ssr_unprotect(__func__);
11941
11942 return ret;
11943}
11944#else
11945static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
11946 struct net_device *dev)
11947{
11948 int ret;
11949
11950 vos_ssr_protect(__func__);
11951 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
11952 vos_ssr_unprotect(__func__);
11953
11954 return ret;
11955}
11956#endif
11957
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011958#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
11959
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011960static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011961 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011962 struct cfg80211_ap_settings *params)
11963{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011964 hdd_adapter_t *pAdapter;
11965 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011966 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011967
11968 ENTER();
11969
Girish Gowlib143d7a2015-02-18 19:39:55 +053011970 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011971 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011972 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053011973 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011974 return -ENODEV;
11975 }
11976
11977 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11978 if (NULL == pAdapter)
11979 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011980 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011981 "%s: HDD adapter is Null", __func__);
11982 return -ENODEV;
11983 }
11984
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011985 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11986 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
11987 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011988 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
11989 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011990 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011991 "%s: HDD adapter magic is invalid", __func__);
11992 return -ENODEV;
11993 }
11994
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011995 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11996
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011997 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011998 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011999 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012000 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012001 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012002 }
12003
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012004 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
12005 __func__, hdd_device_modetoString(pAdapter->device_mode),
12006 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012007
12008 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012009 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012010 )
12011 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012012 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012013
12014 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012015
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012016 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012017 {
12018 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12019 FL("already beacon info added to session(%d)"),
12020 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012021 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012022 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012023
Girish Gowlib143d7a2015-02-18 19:39:55 +053012024#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
12025 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12026 &new,
12027 &params->beacon);
12028#else
12029 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12030 &new,
12031 &params->beacon,
12032 params->dtim_period);
12033#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012034
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012035 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012036 {
12037 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012038 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012039 return -EINVAL;
12040 }
12041 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080012042#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070012043 wlan_hdd_cfg80211_set_channel(wiphy, dev,
12044#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
12045 params->channel, params->channel_type);
12046#else
12047 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
12048#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080012049#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012050 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012051 params->ssid_len, params->hidden_ssid,
12052 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012053 }
12054
12055 EXIT();
12056 return status;
12057}
12058
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012059static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
12060 struct net_device *dev,
12061 struct cfg80211_ap_settings *params)
12062{
12063 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012064
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012065 vos_ssr_protect(__func__);
12066 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
12067 vos_ssr_unprotect(__func__);
12068
12069 return ret;
12070}
12071
12072static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012073 struct net_device *dev,
12074 struct cfg80211_beacon_data *params)
12075{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012076 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012077 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012078 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012079
12080 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012081
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012082 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12083 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
12084 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080012085 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012086 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012087
12088 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12089 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012090 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012091 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012092 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012093 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012094
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012095 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012096 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012097 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012098 {
12099 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012100
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012101 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012102
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012103 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012104 {
12105 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12106 FL("session(%d) beacon data points to NULL"),
12107 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012108 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012109 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012110
12111 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
12112
12113 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012114 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012115 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012116 return -EINVAL;
12117 }
12118
12119 pAdapter->sessionCtx.ap.beacon = new;
12120
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012121 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
12122 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012123 }
12124
12125 EXIT();
12126 return status;
12127}
12128
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012129static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
12130 struct net_device *dev,
12131 struct cfg80211_beacon_data *params)
12132{
12133 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012134
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012135 vos_ssr_protect(__func__);
12136 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
12137 vos_ssr_unprotect(__func__);
12138
12139 return ret;
12140}
12141
12142#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070012143
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012144static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012145 struct net_device *dev,
12146 struct bss_parameters *params)
12147{
12148 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012149 hdd_context_t *pHddCtx;
12150 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012151
12152 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012153
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012154 if (NULL == pAdapter)
12155 {
12156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12157 "%s: HDD adapter is Null", __func__);
12158 return -ENODEV;
12159 }
12160 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012161 ret = wlan_hdd_validate_context(pHddCtx);
12162 if (0 != ret)
12163 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012164 return ret;
12165 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012166 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12167 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
12168 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012169 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12170 __func__, hdd_device_modetoString(pAdapter->device_mode),
12171 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012172
12173 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012174 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012175 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012176 {
12177 /* ap_isolate == -1 means that in change bss, upper layer doesn't
12178 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012179 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070012180 {
12181 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012182 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012183 }
12184
12185 EXIT();
12186 return 0;
12187}
12188
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012189static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
12190 struct net_device *dev,
12191 struct bss_parameters *params)
12192{
12193 int ret;
12194
12195 vos_ssr_protect(__func__);
12196 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
12197 vos_ssr_unprotect(__func__);
12198
12199 return ret;
12200}
Kiet Lam10841362013-11-01 11:36:50 +053012201/* FUNCTION: wlan_hdd_change_country_code_cd
12202* to wait for contry code completion
12203*/
12204void* wlan_hdd_change_country_code_cb(void *pAdapter)
12205{
12206 hdd_adapter_t *call_back_pAdapter = pAdapter;
12207 complete(&call_back_pAdapter->change_country_code);
12208 return NULL;
12209}
12210
Jeff Johnson295189b2012-06-20 16:38:30 -070012211/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012212 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070012213 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
12214 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012215int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012216 struct net_device *ndev,
12217 enum nl80211_iftype type,
12218 u32 *flags,
12219 struct vif_params *params
12220 )
12221{
12222 struct wireless_dev *wdev;
12223 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012224 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070012225 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012226 tCsrRoamProfile *pRoamProfile = NULL;
12227 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012228 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012229 eMib_dot11DesiredBssType connectedBssType;
12230 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012231 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012232
12233 ENTER();
12234
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012235 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012236 {
12237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12238 "%s: Adapter context is null", __func__);
12239 return VOS_STATUS_E_FAILURE;
12240 }
12241
12242 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12243 if (!pHddCtx)
12244 {
12245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12246 "%s: HDD context is null", __func__);
12247 return VOS_STATUS_E_FAILURE;
12248 }
12249
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012250 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12251 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
12252 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012253 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012254 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012255 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012256 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012257 }
12258
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012259 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12260 __func__, hdd_device_modetoString(pAdapter->device_mode),
12261 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012262
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012263 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
12264 hddLog(VOS_TRACE_LEVEL_FATAL,
12265 "%s: STA + MON is in progress, cannot change interface",
12266 __func__);
12267 }
12268
Agarwal Ashish51325b52014-06-16 16:50:49 +053012269 if (vos_max_concurrent_connections_reached()) {
12270 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12271 return -EINVAL;
12272 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012273 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012274 wdev = ndev->ieee80211_ptr;
12275
12276#ifdef WLAN_BTAMP_FEATURE
12277 if((NL80211_IFTYPE_P2P_CLIENT == type)||
12278 (NL80211_IFTYPE_ADHOC == type)||
12279 (NL80211_IFTYPE_AP == type)||
12280 (NL80211_IFTYPE_P2P_GO == type))
12281 {
12282 pHddCtx->isAmpAllowed = VOS_FALSE;
12283 // stop AMP traffic
12284 status = WLANBAP_StopAmp();
12285 if(VOS_STATUS_SUCCESS != status )
12286 {
12287 pHddCtx->isAmpAllowed = VOS_TRUE;
12288 hddLog(VOS_TRACE_LEVEL_FATAL,
12289 "%s: Failed to stop AMP", __func__);
12290 return -EINVAL;
12291 }
12292 }
12293#endif //WLAN_BTAMP_FEATURE
12294 /* Reset the current device mode bit mask*/
12295 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
12296
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053012297 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
12298 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
12299 (type == NL80211_IFTYPE_P2P_GO)))
12300 {
12301 /* Notify Mode change in case of concurrency.
12302 * Below function invokes TDLS teardown Functionality Since TDLS is
12303 * not Supported in case of concurrency i.e Once P2P session
12304 * is detected disable offchannel and teardown TDLS links
12305 */
12306 hddLog(LOG1,
12307 FL("Device mode = %d Interface type = %d"),
12308 pAdapter->device_mode, type);
12309 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
12310 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053012311
Jeff Johnson295189b2012-06-20 16:38:30 -070012312 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012313 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070012314 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012315 )
12316 {
12317 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012318 if (!pWextState)
12319 {
12320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12321 "%s: pWextState is null", __func__);
12322 return VOS_STATUS_E_FAILURE;
12323 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012324 pRoamProfile = &pWextState->roamProfile;
12325 LastBSSType = pRoamProfile->BSSType;
12326
12327 switch (type)
12328 {
12329 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012330 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012331 hddLog(VOS_TRACE_LEVEL_INFO,
12332 "%s: setting interface Type to INFRASTRUCTURE", __func__);
12333 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012334#ifdef WLAN_FEATURE_11AC
12335 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
12336 {
12337 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
12338 }
12339#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012340 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070012341 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012342 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012343 //Check for sub-string p2p to confirm its a p2p interface
12344 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012345 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053012346#ifdef FEATURE_WLAN_TDLS
12347 mutex_lock(&pHddCtx->tdls_lock);
12348 wlan_hdd_tdls_exit(pAdapter, TRUE);
12349 mutex_unlock(&pHddCtx->tdls_lock);
12350#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012351 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12352 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12353 }
12354 else
12355 {
12356 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012357 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012358 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012359 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053012360
Jeff Johnson295189b2012-06-20 16:38:30 -070012361 case NL80211_IFTYPE_ADHOC:
12362 hddLog(VOS_TRACE_LEVEL_INFO,
12363 "%s: setting interface Type to ADHOC", __func__);
12364 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
12365 pRoamProfile->phyMode =
12366 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070012367 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012368 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053012369 hdd_set_ibss_ops( pAdapter );
12370 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053012371
12372 status = hdd_sta_id_hash_attach(pAdapter);
12373 if (VOS_STATUS_SUCCESS != status) {
12374 hddLog(VOS_TRACE_LEVEL_ERROR,
12375 FL("Failed to initialize hash for IBSS"));
12376 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012377 break;
12378
12379 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012380 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012381 {
12382 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12383 "%s: setting interface Type to %s", __func__,
12384 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
12385
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012386 //Cancel any remain on channel for GO mode
12387 if (NL80211_IFTYPE_P2P_GO == type)
12388 {
12389 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
12390 }
Mohit Khanna0f232092012-09-11 14:46:08 -070012391 if (NL80211_IFTYPE_AP == type)
12392 {
12393 /* As Loading WLAN Driver one interface being created for p2p device
12394 * address. This will take one HW STA and the max number of clients
12395 * that can connect to softAP will be reduced by one. so while changing
12396 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
12397 * interface as it is not required in SoftAP mode.
12398 */
12399
12400 // Get P2P Adapter
12401 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
12402
12403 if (pP2pAdapter)
12404 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053012405 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053012406 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070012407 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12408 }
12409 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053012410 //Disable IMPS & BMPS for SAP/GO
12411 if(VOS_STATUS_E_FAILURE ==
12412 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
12413 {
12414 //Fail to Exit BMPS
12415 VOS_ASSERT(0);
12416 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053012417
12418 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
12419
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012420#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070012421
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012422 /* A Mutex Lock is introduced while changing the mode to
12423 * protect the concurrent access for the Adapters by TDLS
12424 * module.
12425 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012426 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012427#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012428 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053012429 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012430 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070012431 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12432 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012433#ifdef FEATURE_WLAN_TDLS
12434 mutex_unlock(&pHddCtx->tdls_lock);
12435#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012436 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
12437 (pConfig->apRandomBssidEnabled))
12438 {
12439 /* To meet Android requirements create a randomized
12440 MAC address of the form 02:1A:11:Fx:xx:xx */
12441 get_random_bytes(&ndev->dev_addr[3], 3);
12442 ndev->dev_addr[0] = 0x02;
12443 ndev->dev_addr[1] = 0x1A;
12444 ndev->dev_addr[2] = 0x11;
12445 ndev->dev_addr[3] |= 0xF0;
12446 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
12447 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080012448 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
12449 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012450 }
12451
Jeff Johnson295189b2012-06-20 16:38:30 -070012452 hdd_set_ap_ops( pAdapter->dev );
12453
Kiet Lam10841362013-11-01 11:36:50 +053012454 /* This is for only SAP mode where users can
12455 * control country through ini.
12456 * P2P GO follows station country code
12457 * acquired during the STA scanning. */
12458 if((NL80211_IFTYPE_AP == type) &&
12459 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
12460 {
12461 int status = 0;
12462 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
12463 "%s: setting country code from INI ", __func__);
12464 init_completion(&pAdapter->change_country_code);
12465 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
12466 (void *)(tSmeChangeCountryCallback)
12467 wlan_hdd_change_country_code_cb,
12468 pConfig->apCntryCode, pAdapter,
12469 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012470 eSIR_FALSE,
12471 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053012472 if (eHAL_STATUS_SUCCESS == status)
12473 {
12474 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012475 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053012476 &pAdapter->change_country_code,
12477 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012478 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053012479 {
12480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012481 FL("SME Timed out while setting country code %ld"),
12482 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080012483
12484 if (pHddCtx->isLogpInProgress)
12485 {
12486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12487 "%s: LOGP in Progress. Ignore!!!", __func__);
12488 return -EAGAIN;
12489 }
Kiet Lam10841362013-11-01 11:36:50 +053012490 }
12491 }
12492 else
12493 {
12494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012495 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053012496 return -EINVAL;
12497 }
12498 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053012499 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070012500 if(status != VOS_STATUS_SUCCESS)
12501 {
12502 hddLog(VOS_TRACE_LEVEL_FATAL,
12503 "%s: Error initializing the ap mode", __func__);
12504 return -EINVAL;
12505 }
12506 hdd_set_conparam(1);
12507
Nirav Shah7e3c8132015-06-22 23:51:42 +053012508 status = hdd_sta_id_hash_attach(pAdapter);
12509 if (VOS_STATUS_SUCCESS != status)
12510 {
12511 hddLog(VOS_TRACE_LEVEL_ERROR,
12512 FL("Failed to initialize hash for AP"));
12513 return -EINVAL;
12514 }
12515
Jeff Johnson295189b2012-06-20 16:38:30 -070012516 /*interface type changed update in wiphy structure*/
12517 if(wdev)
12518 {
12519 wdev->iftype = type;
12520 pHddCtx->change_iface = type;
12521 }
12522 else
12523 {
12524 hddLog(VOS_TRACE_LEVEL_ERROR,
12525 "%s: ERROR !!!! Wireless dev is NULL", __func__);
12526 return -EINVAL;
12527 }
12528 goto done;
12529 }
12530
12531 default:
12532 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12533 __func__);
12534 return -EOPNOTSUPP;
12535 }
12536 }
12537 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012538 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070012539 )
12540 {
12541 switch(type)
12542 {
12543 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012544 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012545 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053012546
12547 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012548#ifdef FEATURE_WLAN_TDLS
12549
12550 /* A Mutex Lock is introduced while changing the mode to
12551 * protect the concurrent access for the Adapters by TDLS
12552 * module.
12553 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012554 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012555#endif
c_hpothu002231a2015-02-05 14:58:51 +053012556 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012557 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012558 //Check for sub-string p2p to confirm its a p2p interface
12559 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012560 {
12561 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12562 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12563 }
12564 else
12565 {
12566 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012567 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012568 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053012569
12570 /* set con_mode to STA only when no SAP concurrency mode */
12571 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
12572 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012573 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012574 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
12575 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012576#ifdef FEATURE_WLAN_TDLS
12577 mutex_unlock(&pHddCtx->tdls_lock);
12578#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053012579 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070012580 if( VOS_STATUS_SUCCESS != status )
12581 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070012582 /* In case of JB, for P2P-GO, only change interface will be called,
12583 * This is the right place to enable back bmps_imps()
12584 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012585 if (pHddCtx->hdd_wlan_suspended)
12586 {
12587 hdd_set_pwrparams(pHddCtx);
12588 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012589 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012590 goto done;
12591 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012592 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012593 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012594 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12595 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012596 goto done;
12597 default:
12598 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12599 __func__);
12600 return -EOPNOTSUPP;
12601
12602 }
12603
12604 }
12605 else
12606 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012607 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
12608 __func__, hdd_device_modetoString(pAdapter->device_mode),
12609 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012610 return -EOPNOTSUPP;
12611 }
12612
12613
12614 if(pRoamProfile)
12615 {
12616 if ( LastBSSType != pRoamProfile->BSSType )
12617 {
12618 /*interface type changed update in wiphy structure*/
12619 wdev->iftype = type;
12620
12621 /*the BSS mode changed, We need to issue disconnect
12622 if connected or in IBSS disconnect state*/
12623 if ( hdd_connGetConnectedBssType(
12624 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
12625 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
12626 {
12627 /*need to issue a disconnect to CSR.*/
12628 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12629 if( eHAL_STATUS_SUCCESS ==
12630 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12631 pAdapter->sessionId,
12632 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12633 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012634 ret = wait_for_completion_interruptible_timeout(
12635 &pAdapter->disconnect_comp_var,
12636 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12637 if (ret <= 0)
12638 {
12639 hddLog(VOS_TRACE_LEVEL_ERROR,
12640 FL("wait on disconnect_comp_var failed %ld"), ret);
12641 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012642 }
12643 }
12644 }
12645 }
12646
12647done:
12648 /*set bitmask based on updated value*/
12649 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012650
12651 /* Only STA mode support TM now
12652 * all other mode, TM feature should be disabled */
12653 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12654 (~VOS_STA & pHddCtx->concurrency_mode) )
12655 {
12656 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12657 }
12658
Jeff Johnson295189b2012-06-20 16:38:30 -070012659#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012660 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012661 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012662 {
12663 //we are ok to do AMP
12664 pHddCtx->isAmpAllowed = VOS_TRUE;
12665 }
12666#endif //WLAN_BTAMP_FEATURE
12667 EXIT();
12668 return 0;
12669}
12670
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012671/*
12672 * FUNCTION: wlan_hdd_cfg80211_change_iface
12673 * wrapper function to protect the actual implementation from SSR.
12674 */
12675int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12676 struct net_device *ndev,
12677 enum nl80211_iftype type,
12678 u32 *flags,
12679 struct vif_params *params
12680 )
12681{
12682 int ret;
12683
12684 vos_ssr_protect(__func__);
12685 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12686 vos_ssr_unprotect(__func__);
12687
12688 return ret;
12689}
12690
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012691#ifdef FEATURE_WLAN_TDLS
12692static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012693 struct net_device *dev,
12694#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12695 const u8 *mac,
12696#else
12697 u8 *mac,
12698#endif
12699 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012700{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012701 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012702 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012703 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012704 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012705 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012706 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012707
12708 ENTER();
12709
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012710 if (!dev) {
12711 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12712 return -EINVAL;
12713 }
12714
12715 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12716 if (!pAdapter) {
12717 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12718 return -EINVAL;
12719 }
12720
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012721 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012722 {
12723 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12724 "Invalid arguments");
12725 return -EINVAL;
12726 }
Hoonki Lee27511902013-03-14 18:19:06 -070012727
12728 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12729 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12730 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012731 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012732 "%s: TDLS mode is disabled OR not enabled in FW."
12733 MAC_ADDRESS_STR " Request declined.",
12734 __func__, MAC_ADDR_ARRAY(mac));
12735 return -ENOTSUPP;
12736 }
12737
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012738 if (pHddCtx->isLogpInProgress)
12739 {
12740 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12741 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012742 wlan_hdd_tdls_set_link_status(pAdapter,
12743 mac,
12744 eTDLS_LINK_IDLE,
12745 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012746 return -EBUSY;
12747 }
12748
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012749 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012750 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012751
12752 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012754 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12755 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012756 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012757 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012758 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012759
12760 /* in add station, we accept existing valid staId if there is */
12761 if ((0 == update) &&
12762 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12763 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012764 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012766 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012767 " link_status %d. staId %d. add station ignored.",
12768 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012769 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012770 return 0;
12771 }
12772 /* in change station, we accept only when staId is valid */
12773 if ((1 == update) &&
12774 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12775 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12776 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012777 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012778 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012779 "%s: " MAC_ADDRESS_STR
12780 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012781 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12782 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12783 mutex_unlock(&pHddCtx->tdls_lock);
12784 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012785 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012786 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012787
12788 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012789 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012790 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12792 "%s: " MAC_ADDRESS_STR
12793 " TDLS setup is ongoing. Request declined.",
12794 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012795 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012796 }
12797
12798 /* first to check if we reached to maximum supported TDLS peer.
12799 TODO: for now, return -EPERM looks working fine,
12800 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012801 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12802 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012803 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12805 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012806 " TDLS Max peer already connected. Request declined."
12807 " Num of peers (%d), Max allowed (%d).",
12808 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12809 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012810 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012811 }
12812 else
12813 {
12814 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012815 mutex_lock(&pHddCtx->tdls_lock);
12816 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012817 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012818 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012819 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12821 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12822 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012823 return -EPERM;
12824 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012825 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012826 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012827 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012828 wlan_hdd_tdls_set_link_status(pAdapter,
12829 mac,
12830 eTDLS_LINK_CONNECTING,
12831 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012832
Jeff Johnsond75fe012013-04-06 10:53:06 -070012833 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012834 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012835 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012837 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012838 if(StaParams->htcap_present)
12839 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012840 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012841 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012843 "ht_capa->extended_capabilities: %0x",
12844 StaParams->HTCap.extendedHtCapInfo);
12845 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012847 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012849 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012850 if(StaParams->vhtcap_present)
12851 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012853 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12854 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12855 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12856 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012857 {
12858 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012859 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012860 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012862 "[%d]: %x ", i, StaParams->supported_rates[i]);
12863 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012864 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012865 else if ((1 == update) && (NULL == StaParams))
12866 {
12867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12868 "%s : update is true, but staParams is NULL. Error!", __func__);
12869 return -EPERM;
12870 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012871
12872 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12873
12874 if (!update)
12875 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012876 /*Before adding sta make sure that device exited from BMPS*/
12877 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12878 {
12879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12880 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12881 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12882 if (status != VOS_STATUS_SUCCESS) {
12883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12884 }
12885 }
12886
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012887 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012888 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012889 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012890 hddLog(VOS_TRACE_LEVEL_ERROR,
12891 FL("Failed to add TDLS peer STA. Enable Bmps"));
12892 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012893 return -EPERM;
12894 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012895 }
12896 else
12897 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012898 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012899 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012900 if (ret != eHAL_STATUS_SUCCESS) {
12901 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12902 return -EPERM;
12903 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012904 }
12905
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012906 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012907 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12908
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012909 mutex_lock(&pHddCtx->tdls_lock);
12910 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12911
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012912 if ((pTdlsPeer != NULL) &&
12913 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012914 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012915 hddLog(VOS_TRACE_LEVEL_ERROR,
12916 FL("peer link status %u"), pTdlsPeer->link_status);
12917 mutex_unlock(&pHddCtx->tdls_lock);
12918 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012919 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012920 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012921
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012922 if (ret <= 0)
12923 {
12924 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12925 "%s: timeout waiting for tdls add station indication %ld",
12926 __func__, ret);
12927 goto error;
12928 }
12929
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012930 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12931 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012933 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012934 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012935 }
12936
12937 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012938
12939error:
Atul Mittal115287b2014-07-08 13:26:33 +053012940 wlan_hdd_tdls_set_link_status(pAdapter,
12941 mac,
12942 eTDLS_LINK_IDLE,
12943 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012944 return -EPERM;
12945
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012946}
12947#endif
12948
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053012949VOS_STATUS wlan_hdd_send_sta_authorized_event(
12950 hdd_adapter_t *adapter,
12951 hdd_context_t *hdd_ctx,
12952 const v_MACADDR_t *mac_addr)
12953{
12954 struct sk_buff *vendor_event;
12955 uint32_t sta_flags = 0;
12956 VOS_STATUS status;
12957
12958 ENTER();
12959
12960 if (!hdd_ctx) {
12961 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null"));
12962 return -EINVAL;
12963 }
12964
12965 vendor_event =
12966 cfg80211_vendor_event_alloc(
Ashish Kumar Dhanotiyac99fbef2018-04-11 12:23:32 +053012967 hdd_ctx->wiphy,
12968#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
12969 &adapter->wdev,
12970#endif
12971 sizeof(sta_flags) +
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053012972 VOS_MAC_ADDR_SIZE + NLMSG_HDRLEN,
12973 QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX,
12974 GFP_KERNEL);
12975 if (!vendor_event) {
12976 hddLog(VOS_TRACE_LEVEL_ERROR,
12977 FL("cfg80211_vendor_event_alloc failed"));
12978 return -EINVAL;
12979 }
12980
12981 sta_flags |= BIT(NL80211_STA_FLAG_AUTHORIZED);
12982
12983 status = nla_put_u32(vendor_event,
12984 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS,
12985 sta_flags);
12986 if (status) {
12987 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA flag put fails"));
12988 kfree_skb(vendor_event);
12989 return VOS_STATUS_E_FAILURE;
12990 }
12991 status = nla_put(vendor_event,
12992 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_MAC,
12993 VOS_MAC_ADDR_SIZE, mac_addr->bytes);
12994 if (status) {
12995 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA MAC put fails"));
12996 kfree_skb(vendor_event);
12997 return VOS_STATUS_E_FAILURE;
12998 }
12999
13000 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
13001
13002 EXIT();
13003 return 0;
13004}
13005
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013006static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013007 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013008#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13009 const u8 *mac,
13010#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013011 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013012#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013013 struct station_parameters *params)
13014{
13015 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013016 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013017 hdd_context_t *pHddCtx;
13018 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013019 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013020 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013021#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013022 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013023 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013024 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013025 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013026#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013027
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013028 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013029
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013030 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013031 if ((NULL == pAdapter))
13032 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013034 "invalid adapter ");
13035 return -EINVAL;
13036 }
13037
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013038 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13039 TRACE_CODE_HDD_CHANGE_STATION,
13040 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053013041 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013042
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013043 ret = wlan_hdd_validate_context(pHddCtx);
13044 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053013045 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013046 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013047 }
13048
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013049 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13050
13051 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013052 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013053 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13054 "invalid HDD station context");
13055 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013056 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013057 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
13058
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013059 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
13060 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070013061 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013062 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070013063 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013064 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070013065 WLANTL_STA_AUTHENTICATED);
13066
Gopichand Nakkala29149562013-05-10 21:43:41 +053013067 if (status != VOS_STATUS_SUCCESS)
13068 {
13069 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13070 "%s: Not able to change TL state to AUTHENTICATED", __func__);
13071 return -EINVAL;
13072 }
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013073 status = wlan_hdd_send_sta_authorized_event(pAdapter, pHddCtx,
13074 &STAMacAddress);
13075 if (status != VOS_STATUS_SUCCESS)
13076 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013077 }
13078 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070013079 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
13080 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013081#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013082 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13083 StaParams.capability = params->capability;
13084 StaParams.uapsd_queues = params->uapsd_queues;
13085 StaParams.max_sp = params->max_sp;
13086
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013087 /* Convert (first channel , number of channels) tuple to
13088 * the total list of channels. This goes with the assumption
13089 * that if the first channel is < 14, then the next channels
13090 * are an incremental of 1 else an incremental of 4 till the number
13091 * of channels.
13092 */
13093 if (0 != params->supported_channels_len) {
13094 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013095 for ( i = 0 ; i < params->supported_channels_len
13096 && j < SIR_MAC_MAX_SUPP_CHANNELS; i+=2)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013097 {
13098 int wifi_chan_index;
13099 StaParams.supported_channels[j] = params->supported_channels[i];
13100 wifi_chan_index =
13101 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
13102 no_of_channels = params->supported_channels[i+1];
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013103 for(k=1; k <= no_of_channels
13104 && j < SIR_MAC_MAX_SUPP_CHANNELS - 1; k++)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013105 {
13106 StaParams.supported_channels[j+1] =
13107 StaParams.supported_channels[j] + wifi_chan_index;
13108 j+=1;
13109 }
13110 }
13111 StaParams.supported_channels_len = j;
13112 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053013113 if (params->supported_oper_classes_len >
13114 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
13115 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13116 "received oper classes:%d, resetting it to max supported %d",
13117 params->supported_oper_classes_len,
13118 SIR_MAC_MAX_SUPP_OPER_CLASSES);
13119 params->supported_oper_classes_len =
13120 SIR_MAC_MAX_SUPP_OPER_CLASSES;
13121 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013122 vos_mem_copy(StaParams.supported_oper_classes,
13123 params->supported_oper_classes,
13124 params->supported_oper_classes_len);
13125 StaParams.supported_oper_classes_len =
13126 params->supported_oper_classes_len;
13127
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013128 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
13129 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13130 "received extn capabilities:%d, resetting it to max supported",
13131 params->ext_capab_len);
13132 params->ext_capab_len = sizeof(StaParams.extn_capability);
13133 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013134 if (0 != params->ext_capab_len)
13135 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013136 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013137
13138 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013139 {
13140 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013141 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013142 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013143
13144 StaParams.supported_rates_len = params->supported_rates_len;
13145
13146 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
13147 * The supported_rates array , for all the structures propogating till Add Sta
13148 * to the firmware has to be modified , if the supplicant (ieee80211) is
13149 * modified to send more rates.
13150 */
13151
13152 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
13153 */
13154 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
13155 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
13156
13157 if (0 != StaParams.supported_rates_len) {
13158 int i = 0;
13159 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
13160 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013161 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013162 "Supported Rates with Length %d", StaParams.supported_rates_len);
13163 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013165 "[%d]: %0x", i, StaParams.supported_rates[i]);
13166 }
13167
13168 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013169 {
13170 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013171 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013172 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013173
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013174 if (0 != params->ext_capab_len ) {
13175 /*Define A Macro : TODO Sunil*/
13176 if ((1<<4) & StaParams.extn_capability[3]) {
13177 isBufSta = 1;
13178 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013179 /* TDLS Channel Switching Support */
13180 if ((1<<6) & StaParams.extn_capability[3]) {
13181 isOffChannelSupported = 1;
13182 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013183 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013184
13185 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053013186 (params->ht_capa || params->vht_capa ||
13187 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013188 /* TDLS Peer is WME/QoS capable */
13189 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013190
13191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13192 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
13193 __func__, isQosWmmSta, StaParams.htcap_present);
13194
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013195 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
13196 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013197 isOffChannelSupported,
13198 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013199
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013200 if (VOS_STATUS_SUCCESS != status) {
13201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13202 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
13203 return -EINVAL;
13204 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013205 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
13206
13207 if (VOS_STATUS_SUCCESS != status) {
13208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13209 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
13210 return -EINVAL;
13211 }
13212 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013213#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053013214 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013215 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013216 return status;
13217}
13218
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013219#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13220static int wlan_hdd_change_station(struct wiphy *wiphy,
13221 struct net_device *dev,
13222 const u8 *mac,
13223 struct station_parameters *params)
13224#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013225static int wlan_hdd_change_station(struct wiphy *wiphy,
13226 struct net_device *dev,
13227 u8 *mac,
13228 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013229#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013230{
13231 int ret;
13232
13233 vos_ssr_protect(__func__);
13234 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
13235 vos_ssr_unprotect(__func__);
13236
13237 return ret;
13238}
13239
Jeff Johnson295189b2012-06-20 16:38:30 -070013240/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013241 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013242 * This function is used to initialize the key information
13243 */
13244#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013245static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013246 struct net_device *ndev,
13247 u8 key_index, bool pairwise,
13248 const u8 *mac_addr,
13249 struct key_params *params
13250 )
13251#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013252static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013253 struct net_device *ndev,
13254 u8 key_index, const u8 *mac_addr,
13255 struct key_params *params
13256 )
13257#endif
13258{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013259 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013260 tCsrRoamSetKey setKey;
13261 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013262 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013263 v_U32_t roamId= 0xFF;
13264 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013265 hdd_hostapd_state_t *pHostapdState;
13266 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013267 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013268 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013269 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013270 v_MACADDR_t *peerMacAddr;
13271 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013272 uint8_t staid = HDD_MAX_STA_COUNT;
13273 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013274
13275 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013276
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013277 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13278 TRACE_CODE_HDD_CFG80211_ADD_KEY,
13279 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013280 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13281 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013282 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013283 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013284 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013285 }
13286
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013287 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13288 __func__, hdd_device_modetoString(pAdapter->device_mode),
13289 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013290
13291 if (CSR_MAX_NUM_KEY <= key_index)
13292 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013293 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013294 key_index);
13295
13296 return -EINVAL;
13297 }
13298
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013299 if (CSR_MAX_KEY_LEN < params->key_len)
13300 {
13301 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
13302 params->key_len);
13303
13304 return -EINVAL;
13305 }
13306
Jingxiang Gec438aea2017-10-26 16:44:00 +080013307 if (CSR_MAX_RSC_LEN < params->seq_len)
13308 {
13309 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
13310 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053013311
13312 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080013313 }
13314
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013315 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080013316 "%s: called with key index = %d & key length %d & seq length %d",
13317 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013318
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013319 peerMacAddr = (v_MACADDR_t *)mac_addr;
13320
Jeff Johnson295189b2012-06-20 16:38:30 -070013321 /*extract key idx, key len and key*/
13322 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13323 setKey.keyId = key_index;
13324 setKey.keyLength = params->key_len;
13325 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080013326 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013327
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013328 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013329 {
13330 case WLAN_CIPHER_SUITE_WEP40:
13331 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13332 break;
13333
13334 case WLAN_CIPHER_SUITE_WEP104:
13335 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
13336 break;
13337
13338 case WLAN_CIPHER_SUITE_TKIP:
13339 {
13340 u8 *pKey = &setKey.Key[0];
13341 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
13342
13343 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
13344
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013345 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070013346
13347 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013348 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013349 |--------------|----------|----------|
13350 <---16bytes---><--8bytes--><--8bytes-->
13351
13352 */
13353 /*Sme expects the 32 bytes key to be in the below order
13354
13355 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013356 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013357 |--------------|----------|----------|
13358 <---16bytes---><--8bytes--><--8bytes-->
13359 */
13360 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013361 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070013362
13363 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013364 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013365
13366 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013367 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013368
13369
13370 break;
13371 }
13372
13373 case WLAN_CIPHER_SUITE_CCMP:
13374 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
13375 break;
13376
13377#ifdef FEATURE_WLAN_WAPI
13378 case WLAN_CIPHER_SUITE_SMS4:
13379 {
13380 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13381 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
13382 params->key, params->key_len);
13383 return 0;
13384 }
13385#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013386
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013387#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013388 case WLAN_CIPHER_SUITE_KRK:
13389 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
13390 break;
13391#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013392
13393#ifdef WLAN_FEATURE_11W
13394 case WLAN_CIPHER_SUITE_AES_CMAC:
13395 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070013396 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070013397#endif
13398
Jeff Johnson295189b2012-06-20 16:38:30 -070013399 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013400 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070013401 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013402 status = -EOPNOTSUPP;
13403 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013404 }
13405
13406 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
13407 __func__, setKey.encType);
13408
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013409 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070013410#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13411 (!pairwise)
13412#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013413 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013414#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013415 )
13416 {
13417 /* set group key*/
13418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13419 "%s- %d: setting Broadcast key",
13420 __func__, __LINE__);
13421 setKey.keyDirection = eSIR_RX_ONLY;
13422 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13423 }
13424 else
13425 {
13426 /* set pairwise key*/
13427 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13428 "%s- %d: setting pairwise key",
13429 __func__, __LINE__);
13430 setKey.keyDirection = eSIR_TX_RX;
13431 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013432 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013433 }
13434 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
13435 {
13436 setKey.keyDirection = eSIR_TX_RX;
13437 /*Set the group key*/
13438 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13439 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070013440
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013441 if ( 0 != status )
13442 {
13443 hddLog(VOS_TRACE_LEVEL_ERROR,
13444 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013445 status = -EINVAL;
13446 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013447 }
13448 /*Save the keys here and call sme_RoamSetKey for setting
13449 the PTK after peer joins the IBSS network*/
13450 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
13451 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013452 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013453 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053013454 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
13455 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
13456 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013457 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013458 if( pHostapdState->bssState == BSS_START )
13459 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013460 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13461 vos_status = wlan_hdd_check_ula_done(pAdapter);
13462
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013463 if (peerMacAddr && (pairwise_set_key == true))
13464 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013465
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013466 if ( vos_status != VOS_STATUS_SUCCESS )
13467 {
13468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13469 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13470 __LINE__, vos_status );
13471
13472 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13473
13474 status = -EINVAL;
13475 goto end;
13476 }
13477
Jeff Johnson295189b2012-06-20 16:38:30 -070013478 status = WLANSAP_SetKeySta( pVosContext, &setKey);
13479
13480 if ( status != eHAL_STATUS_SUCCESS )
13481 {
13482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13483 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13484 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013485 status = -EINVAL;
13486 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013487 }
13488 }
13489
13490 /* Saving WEP keys */
13491 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
13492 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
13493 {
13494 //Save the wep key in ap context. Issue setkey after the BSS is started.
13495 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13496 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
13497 }
13498 else
13499 {
13500 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013501 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013502 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
13503 }
13504 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013505 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
13506 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013507 {
13508 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13509 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13510
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013511#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13512 if (!pairwise)
13513#else
13514 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
13515#endif
13516 {
13517 /* set group key*/
13518 if (pHddStaCtx->roam_info.deferKeyComplete)
13519 {
13520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13521 "%s- %d: Perform Set key Complete",
13522 __func__, __LINE__);
13523 hdd_PerformRoamSetKeyComplete(pAdapter);
13524 }
13525 }
13526
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013527 if (pairwise_set_key == true)
13528 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013529
Jeff Johnson295189b2012-06-20 16:38:30 -070013530 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
13531
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080013532 pWextState->roamProfile.Keys.defaultIndex = key_index;
13533
13534
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013535 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013536 params->key, params->key_len);
13537
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013538
Jeff Johnson295189b2012-06-20 16:38:30 -070013539 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13540
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013541 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013542 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013543 __func__, setKey.peerMac[0], setKey.peerMac[1],
13544 setKey.peerMac[2], setKey.peerMac[3],
13545 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013546 setKey.keyDirection);
13547
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013548 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053013549
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013550 if ( vos_status != VOS_STATUS_SUCCESS )
13551 {
13552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013553 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13554 __LINE__, vos_status );
13555
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013556 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013557
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013558 status = -EINVAL;
13559 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013560
13561 }
13562
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013563#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013564 /* The supplicant may attempt to set the PTK once pre-authentication
13565 is done. Save the key in the UMAC and include it in the ADD BSS
13566 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013567 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013568 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013569 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013570 hddLog(VOS_TRACE_LEVEL_INFO_MED,
13571 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013572 status = 0;
13573 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013574 }
13575 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
13576 {
13577 hddLog(VOS_TRACE_LEVEL_ERROR,
13578 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013579 status = -EINVAL;
13580 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013581 }
13582#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070013583
13584 /* issue set key request to SME*/
13585 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13586 pAdapter->sessionId, &setKey, &roamId );
13587
13588 if ( 0 != status )
13589 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013590 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013591 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
13592 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013593 status = -EINVAL;
13594 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013595 }
13596
13597
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013598 /* in case of IBSS as there was no information available about WEP keys during
13599 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070013600 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013601 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
13602 !( ( IW_AUTH_KEY_MGMT_802_1X
13603 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070013604 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
13605 )
13606 &&
13607 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
13608 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
13609 )
13610 )
13611 {
13612 setKey.keyDirection = eSIR_RX_ONLY;
13613 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13614
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013615 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013616 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013617 __func__, setKey.peerMac[0], setKey.peerMac[1],
13618 setKey.peerMac[2], setKey.peerMac[3],
13619 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013620 setKey.keyDirection);
13621
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013622 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013623 pAdapter->sessionId, &setKey, &roamId );
13624
13625 if ( 0 != status )
13626 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013627 hddLog(VOS_TRACE_LEVEL_ERROR,
13628 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013629 __func__, status);
13630 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013631 status = -EINVAL;
13632 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013633 }
13634 }
13635 }
13636
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013637 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013638 for (i = 0; i < params->seq_len; i++) {
13639 rsc_counter |= (params->seq[i] << i*8);
13640 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013641 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
13642 }
13643
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013644end:
13645 /* Need to clear any trace of key value in the memory.
13646 * Thus zero out the memory even though it is local
13647 * variable.
13648 */
13649 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013650 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013651 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013652}
13653
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013654#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13655static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13656 struct net_device *ndev,
13657 u8 key_index, bool pairwise,
13658 const u8 *mac_addr,
13659 struct key_params *params
13660 )
13661#else
13662static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13663 struct net_device *ndev,
13664 u8 key_index, const u8 *mac_addr,
13665 struct key_params *params
13666 )
13667#endif
13668{
13669 int ret;
13670 vos_ssr_protect(__func__);
13671#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13672 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
13673 mac_addr, params);
13674#else
13675 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
13676 params);
13677#endif
13678 vos_ssr_unprotect(__func__);
13679
13680 return ret;
13681}
13682
Jeff Johnson295189b2012-06-20 16:38:30 -070013683/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013684 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013685 * This function is used to get the key information
13686 */
13687#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013688static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013689 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013690 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013691 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013692 const u8 *mac_addr, void *cookie,
13693 void (*callback)(void *cookie, struct key_params*)
13694 )
13695#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013696static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013697 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013698 struct net_device *ndev,
13699 u8 key_index, const u8 *mac_addr, void *cookie,
13700 void (*callback)(void *cookie, struct key_params*)
13701 )
13702#endif
13703{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013704 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013705 hdd_wext_state_t *pWextState = NULL;
13706 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013707 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013708 hdd_context_t *pHddCtx;
13709 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013710
13711 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013712
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013713 if (NULL == pAdapter)
13714 {
13715 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13716 "%s: HDD adapter is Null", __func__);
13717 return -ENODEV;
13718 }
13719
13720 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13721 ret = wlan_hdd_validate_context(pHddCtx);
13722 if (0 != ret)
13723 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013724 return ret;
13725 }
13726
13727 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13728 pRoamProfile = &(pWextState->roamProfile);
13729
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013730 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13731 __func__, hdd_device_modetoString(pAdapter->device_mode),
13732 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013733
Jeff Johnson295189b2012-06-20 16:38:30 -070013734 memset(&params, 0, sizeof(params));
13735
13736 if (CSR_MAX_NUM_KEY <= key_index)
13737 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013738 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013739 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013740 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013741
13742 switch(pRoamProfile->EncryptionType.encryptionType[0])
13743 {
13744 case eCSR_ENCRYPT_TYPE_NONE:
13745 params.cipher = IW_AUTH_CIPHER_NONE;
13746 break;
13747
13748 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13749 case eCSR_ENCRYPT_TYPE_WEP40:
13750 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13751 break;
13752
13753 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13754 case eCSR_ENCRYPT_TYPE_WEP104:
13755 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13756 break;
13757
13758 case eCSR_ENCRYPT_TYPE_TKIP:
13759 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13760 break;
13761
13762 case eCSR_ENCRYPT_TYPE_AES:
13763 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13764 break;
13765
13766 default:
13767 params.cipher = IW_AUTH_CIPHER_NONE;
13768 break;
13769 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013770
c_hpothuaaf19692014-05-17 17:01:48 +053013771 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13772 TRACE_CODE_HDD_CFG80211_GET_KEY,
13773 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013774
Jeff Johnson295189b2012-06-20 16:38:30 -070013775 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13776 params.seq_len = 0;
13777 params.seq = NULL;
13778 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13779 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013780 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013781 return 0;
13782}
13783
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013784#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13785static int wlan_hdd_cfg80211_get_key(
13786 struct wiphy *wiphy,
13787 struct net_device *ndev,
13788 u8 key_index, bool pairwise,
13789 const u8 *mac_addr, void *cookie,
13790 void (*callback)(void *cookie, struct key_params*)
13791 )
13792#else
13793static int wlan_hdd_cfg80211_get_key(
13794 struct wiphy *wiphy,
13795 struct net_device *ndev,
13796 u8 key_index, const u8 *mac_addr, void *cookie,
13797 void (*callback)(void *cookie, struct key_params*)
13798 )
13799#endif
13800{
13801 int ret;
13802
13803 vos_ssr_protect(__func__);
13804#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13805 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13806 mac_addr, cookie, callback);
13807#else
13808 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13809 callback);
13810#endif
13811 vos_ssr_unprotect(__func__);
13812
13813 return ret;
13814}
13815
Jeff Johnson295189b2012-06-20 16:38:30 -070013816/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013817 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013818 * This function is used to delete the key information
13819 */
13820#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013821static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013822 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013823 u8 key_index,
13824 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013825 const u8 *mac_addr
13826 )
13827#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013828static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013829 struct net_device *ndev,
13830 u8 key_index,
13831 const u8 *mac_addr
13832 )
13833#endif
13834{
13835 int status = 0;
13836
13837 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013838 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013839 //it is observed that this is invalidating peer
13840 //key index whenever re-key is done. This is affecting data link.
13841 //It should be ok to ignore del_key.
13842#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013843 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13844 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013845 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13846 tCsrRoamSetKey setKey;
13847 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013848
Jeff Johnson295189b2012-06-20 16:38:30 -070013849 ENTER();
13850
13851 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13852 __func__,pAdapter->device_mode);
13853
13854 if (CSR_MAX_NUM_KEY <= key_index)
13855 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013856 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013857 key_index);
13858
13859 return -EINVAL;
13860 }
13861
13862 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13863 setKey.keyId = key_index;
13864
13865 if (mac_addr)
13866 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13867 else
13868 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13869
13870 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13871
13872 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013873 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013874 )
13875 {
13876
13877 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013878 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13879 if( pHostapdState->bssState == BSS_START)
13880 {
13881 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013882
Jeff Johnson295189b2012-06-20 16:38:30 -070013883 if ( status != eHAL_STATUS_SUCCESS )
13884 {
13885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13886 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13887 __LINE__, status );
13888 }
13889 }
13890 }
13891 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013892 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013893 )
13894 {
13895 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13896
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013897 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13898
13899 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013900 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013901 __func__, setKey.peerMac[0], setKey.peerMac[1],
13902 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013903 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013904 if(pAdapter->sessionCtx.station.conn_info.connState ==
13905 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013906 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013907 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013908 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013909
Jeff Johnson295189b2012-06-20 16:38:30 -070013910 if ( 0 != status )
13911 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013912 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013913 "%s: sme_RoamSetKey failure, returned %d",
13914 __func__, status);
13915 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13916 return -EINVAL;
13917 }
13918 }
13919 }
13920#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013921 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013922 return status;
13923}
13924
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013925#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13926static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13927 struct net_device *ndev,
13928 u8 key_index,
13929 bool pairwise,
13930 const u8 *mac_addr
13931 )
13932#else
13933static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13934 struct net_device *ndev,
13935 u8 key_index,
13936 const u8 *mac_addr
13937 )
13938#endif
13939{
13940 int ret;
13941
13942 vos_ssr_protect(__func__);
13943#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13944 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
13945 mac_addr);
13946#else
13947 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
13948#endif
13949 vos_ssr_unprotect(__func__);
13950
13951 return ret;
13952}
13953
Jeff Johnson295189b2012-06-20 16:38:30 -070013954/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013955 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013956 * This function is used to set the default tx key index
13957 */
13958#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013959static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013960 struct net_device *ndev,
13961 u8 key_index,
13962 bool unicast, bool multicast)
13963#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013964static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013965 struct net_device *ndev,
13966 u8 key_index)
13967#endif
13968{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013969 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013970 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013971 hdd_wext_state_t *pWextState;
13972 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013973 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013974
13975 ENTER();
13976
Gopichand Nakkala29149562013-05-10 21:43:41 +053013977 if ((NULL == pAdapter))
13978 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013980 "invalid adapter");
13981 return -EINVAL;
13982 }
13983
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013984 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13985 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
13986 pAdapter->sessionId, key_index));
13987
Gopichand Nakkala29149562013-05-10 21:43:41 +053013988 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13989 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13990
13991 if ((NULL == pWextState) || (NULL == pHddStaCtx))
13992 {
13993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13994 "invalid Wext state or HDD context");
13995 return -EINVAL;
13996 }
13997
Arif Hussain6d2a3322013-11-17 19:50:10 -080013998 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013999 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014000
Jeff Johnson295189b2012-06-20 16:38:30 -070014001 if (CSR_MAX_NUM_KEY <= key_index)
14002 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014003 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014004 key_index);
14005
14006 return -EINVAL;
14007 }
14008
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014009 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14010 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014011 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014012 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014013 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014014 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014015
Jeff Johnson295189b2012-06-20 16:38:30 -070014016 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070014017 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014018 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014019 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053014020 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080014021 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080014022#ifdef FEATURE_WLAN_WAPI
14023 (eCSR_ENCRYPT_TYPE_WPI !=
14024 pHddStaCtx->conn_info.ucEncryptionType) &&
14025#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014026 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080014027 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070014028 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014029 {
14030 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070014031 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014032
Jeff Johnson295189b2012-06-20 16:38:30 -070014033 tCsrRoamSetKey setKey;
14034 v_U32_t roamId= 0xFF;
14035 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014036
14037 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014038 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014039
Jeff Johnson295189b2012-06-20 16:38:30 -070014040 Keys->defaultIndex = (u8)key_index;
14041 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
14042 setKey.keyId = key_index;
14043 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014044
14045 vos_mem_copy(&setKey.Key[0],
14046 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014047 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014048
Gopichand Nakkala29149562013-05-10 21:43:41 +053014049 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014050
14051 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070014052 &pHddStaCtx->conn_info.bssId[0],
14053 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014054
Gopichand Nakkala29149562013-05-10 21:43:41 +053014055 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
14056 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
14057 eCSR_ENCRYPT_TYPE_WEP104)
14058 {
14059 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
14060 even though ap is configured for WEP-40 encryption. In this canse the key length
14061 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
14062 type(104) and switching encryption type to 40*/
14063 pWextState->roamProfile.EncryptionType.encryptionType[0] =
14064 eCSR_ENCRYPT_TYPE_WEP40;
14065 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
14066 eCSR_ENCRYPT_TYPE_WEP40;
14067 }
14068
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014069 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014070 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014071
Jeff Johnson295189b2012-06-20 16:38:30 -070014072 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014073 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014074 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014075
Jeff Johnson295189b2012-06-20 16:38:30 -070014076 if ( 0 != status )
14077 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014078 hddLog(VOS_TRACE_LEVEL_ERROR,
14079 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014080 status);
14081 return -EINVAL;
14082 }
14083 }
14084 }
14085
14086 /* In SoftAp mode setting key direction for default mode */
14087 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
14088 {
14089 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
14090 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
14091 (eCSR_ENCRYPT_TYPE_AES !=
14092 pWextState->roamProfile.EncryptionType.encryptionType[0])
14093 )
14094 {
14095 /* Saving key direction for default key index to TX default */
14096 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
14097 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
14098 }
14099 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014100 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014101 return status;
14102}
14103
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014104#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14105static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14106 struct net_device *ndev,
14107 u8 key_index,
14108 bool unicast, bool multicast)
14109#else
14110static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14111 struct net_device *ndev,
14112 u8 key_index)
14113#endif
14114{
14115 int ret;
14116 vos_ssr_protect(__func__);
14117#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14118 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
14119 multicast);
14120#else
14121 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
14122#endif
14123 vos_ssr_unprotect(__func__);
14124
14125 return ret;
14126}
14127
Jeff Johnson295189b2012-06-20 16:38:30 -070014128/*
14129 * FUNCTION: wlan_hdd_cfg80211_inform_bss
14130 * This function is used to inform the BSS details to nl80211 interface.
14131 */
14132static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
14133 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
14134{
14135 struct net_device *dev = pAdapter->dev;
14136 struct wireless_dev *wdev = dev->ieee80211_ptr;
14137 struct wiphy *wiphy = wdev->wiphy;
14138 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
14139 int chan_no;
14140 int ie_length;
14141 const char *ie;
14142 unsigned int freq;
14143 struct ieee80211_channel *chan;
14144 int rssi = 0;
14145 struct cfg80211_bss *bss = NULL;
14146
Jeff Johnson295189b2012-06-20 16:38:30 -070014147 if( NULL == pBssDesc )
14148 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014149 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014150 return bss;
14151 }
14152
14153 chan_no = pBssDesc->channelId;
14154 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
14155 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
14156
14157 if( NULL == ie )
14158 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014159 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014160 return bss;
14161 }
14162
14163#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
14164 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
14165 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014166 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014167 }
14168 else
14169 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014170 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014171 }
14172#else
14173 freq = ieee80211_channel_to_frequency(chan_no);
14174#endif
14175
14176 chan = __ieee80211_get_channel(wiphy, freq);
14177
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053014178 if (!chan) {
14179 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
14180 return NULL;
14181 }
14182
Abhishek Singhaee43942014-06-16 18:55:47 +053014183 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070014184
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014185 return cfg80211_inform_bss(wiphy, chan,
14186#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14187 CFG80211_BSS_FTYPE_UNKNOWN,
14188#endif
14189 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014190 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070014191 pBssDesc->capabilityInfo,
14192 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053014193 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070014194}
14195
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014196/*
14197 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
14198 * interface that BSS might have been lost.
14199 * @pAdapter: adaptor
14200 * @bssid: bssid which might have been lost
14201 *
14202 * Return: bss which is unlinked from kernel cache
14203 */
14204struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
14205 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
14206{
14207 struct net_device *dev = pAdapter->dev;
14208 struct wireless_dev *wdev = dev->ieee80211_ptr;
14209 struct wiphy *wiphy = wdev->wiphy;
14210 struct cfg80211_bss *bss = NULL;
14211
Abhishek Singh5a597e62016-12-05 15:16:30 +053014212 bss = hdd_get_bss_entry(wiphy,
14213 NULL, bssid,
14214 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014215 if (bss == NULL) {
14216 hddLog(LOGE, FL("BSS not present"));
14217 } else {
14218 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
14219 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
14220 cfg80211_unlink_bss(wiphy, bss);
14221 }
14222 return bss;
14223}
Jeff Johnson295189b2012-06-20 16:38:30 -070014224
14225
14226/*
14227 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
14228 * This function is used to inform the BSS details to nl80211 interface.
14229 */
14230struct cfg80211_bss*
14231wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
14232 tSirBssDescription *bss_desc
14233 )
14234{
14235 /*
14236 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
14237 already exists in bss data base of cfg80211 for that particular BSS ID.
14238 Using cfg80211_inform_bss_frame to update the bss entry instead of
14239 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
14240 now there is no possibility to get the mgmt(probe response) frame from PE,
14241 converting bss_desc to ieee80211_mgmt(probe response) and passing to
14242 cfg80211_inform_bss_frame.
14243 */
14244 struct net_device *dev = pAdapter->dev;
14245 struct wireless_dev *wdev = dev->ieee80211_ptr;
14246 struct wiphy *wiphy = wdev->wiphy;
14247 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014248#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14249 qcom_ie_age *qie_age = NULL;
14250 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
14251#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014252 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014253#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014254 const char *ie =
14255 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
14256 unsigned int freq;
14257 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014258 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014259 struct cfg80211_bss *bss_status = NULL;
14260 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
14261 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070014262 hdd_context_t *pHddCtx;
14263 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070014264#ifdef WLAN_OPEN_SOURCE
14265 struct timespec ts;
14266#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014267
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014268
Wilson Yangf80a0542013-10-07 13:02:37 -070014269 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14270 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070014271 if (0 != status)
14272 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014273 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014274 }
14275
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014276 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070014277 if (!mgmt)
14278 {
14279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14280 "%s: memory allocation failed ", __func__);
14281 return NULL;
14282 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014283
Jeff Johnson295189b2012-06-20 16:38:30 -070014284 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014285
14286#ifdef WLAN_OPEN_SOURCE
14287 /* Android does not want the timestamp from the frame.
14288 Instead it wants a monotonic increasing value */
14289 get_monotonic_boottime(&ts);
14290 mgmt->u.probe_resp.timestamp =
14291 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
14292#else
14293 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014294 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
14295 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070014296
14297#endif
14298
Jeff Johnson295189b2012-06-20 16:38:30 -070014299 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
14300 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014301
14302#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14303 /* GPS Requirement: need age ie per entry. Using vendor specific. */
14304 /* Assuming this is the last IE, copy at the end */
14305 ie_length -=sizeof(qcom_ie_age);
14306 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
14307 qie_age->element_id = QCOM_VENDOR_IE_ID;
14308 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
14309 qie_age->oui_1 = QCOM_OUI1;
14310 qie_age->oui_2 = QCOM_OUI2;
14311 qie_age->oui_3 = QCOM_OUI3;
14312 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053014313 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
14314 * bss related timestamp is in units of ms. Due to this when scan results
14315 * are sent to lowi the scan age is high.To address this, send age in units
14316 * of 1/10 ms.
14317 */
14318 qie_age->age = (vos_timer_get_system_time() -
14319 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014320#endif
14321
Jeff Johnson295189b2012-06-20 16:38:30 -070014322 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053014323 if (bss_desc->fProbeRsp)
14324 {
14325 mgmt->frame_control |=
14326 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
14327 }
14328 else
14329 {
14330 mgmt->frame_control |=
14331 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
14332 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014333
14334#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014335 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014336 (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014337 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014338 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014339 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014340 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014341 (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014342
14343 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014344 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014345 }
14346 else
14347 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014348 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
14349 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070014350 kfree(mgmt);
14351 return NULL;
14352 }
14353#else
14354 freq = ieee80211_channel_to_frequency(chan_no);
14355#endif
14356 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014357 /*when the band is changed on the fly using the GUI, three things are done
14358 * 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)
14359 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
14360 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
14361 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
14362 * and discards the channels correponding to previous band and calls back with zero bss results.
14363 * 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
14364 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
14365 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
14366 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
14367 * So drop the bss and continue to next bss.
14368 */
14369 if(chan == NULL)
14370 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053014371 hddLog(VOS_TRACE_LEVEL_ERROR,
14372 FL("chan pointer is NULL, chan_no: %d freq: %d"),
14373 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070014374 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014375 return NULL;
14376 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053014377 /*To keep the rssi icon of the connected AP in the scan window
14378 *and the rssi icon of the wireless networks in sync
14379 * */
14380 if (( eConnectionState_Associated ==
14381 pAdapter->sessionCtx.station.conn_info.connState ) &&
14382 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
14383 pAdapter->sessionCtx.station.conn_info.bssId,
14384 WNI_CFG_BSSID_LEN)) &&
14385 (pHddCtx->hdd_wlan_suspended == FALSE))
14386 {
14387 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
14388 rssi = (pAdapter->rssi * 100);
14389 }
14390 else
14391 {
14392 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
14393 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014394
Nirav Shah20ac06f2013-12-12 18:14:06 +053014395 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053014396 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
14397 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053014398
Jeff Johnson295189b2012-06-20 16:38:30 -070014399 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
14400 frame_len, rssi, GFP_KERNEL);
14401 kfree(mgmt);
14402 return bss_status;
14403}
14404
14405/*
14406 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
14407 * This function is used to update the BSS data base of CFG8011
14408 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014409struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014410 tCsrRoamInfo *pRoamInfo
14411 )
14412{
14413 tCsrRoamConnectedProfile roamProfile;
14414 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14415 struct cfg80211_bss *bss = NULL;
14416
14417 ENTER();
14418
14419 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
14420 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
14421
14422 if (NULL != roamProfile.pBssDesc)
14423 {
Girish Gowlif4b68022014-08-28 23:18:57 +053014424 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14425 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070014426
14427 if (NULL == bss)
14428 {
14429 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
14430 __func__);
14431 }
14432
14433 sme_RoamFreeConnectProfile(hHal, &roamProfile);
14434 }
14435 else
14436 {
14437 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
14438 __func__);
14439 }
14440 return bss;
14441}
14442
14443/*
14444 * FUNCTION: wlan_hdd_cfg80211_update_bss
14445 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014446static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
14447 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070014448 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014449{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014450 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014451 tCsrScanResultInfo *pScanResult;
14452 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014453 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014454 tScanResultHandle pResult;
14455 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014456 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014457 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070014458 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014459
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014460 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14461 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
14462 NO_SESSION, pAdapter->sessionId));
14463
Wilson Yangf80a0542013-10-07 13:02:37 -070014464 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014465 ret = wlan_hdd_validate_context(pHddCtx);
14466 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070014467 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014468 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070014469 }
14470
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014471 if (pAdapter->request != NULL)
14472 {
14473 if ((pAdapter->request->n_ssids == 1)
14474 && (pAdapter->request->ssids != NULL)
14475 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
14476 is_p2p_scan = true;
14477 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014478 /*
14479 * start getting scan results and populate cgf80211 BSS database
14480 */
14481 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
14482
14483 /* no scan results */
14484 if (NULL == pResult)
14485 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014486 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
14487 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014488 wlan_hdd_get_frame_logs(pAdapter,
14489 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070014490 return status;
14491 }
14492
14493 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
14494
14495 while (pScanResult)
14496 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014497 /*
14498 * cfg80211_inform_bss() is not updating ie field of bss entry, if
14499 * entry already exists in bss data base of cfg80211 for that
14500 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
14501 * bss entry instead of cfg80211_inform_bss, But this call expects
14502 * mgmt packet as input. As of now there is no possibility to get
14503 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070014504 * ieee80211_mgmt(probe response) and passing to c
14505 * fg80211_inform_bss_frame.
14506 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014507 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
14508 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
14509 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014510 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14511 continue; //Skip the non p2p bss entries
14512 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014513 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14514 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014515
Jeff Johnson295189b2012-06-20 16:38:30 -070014516
14517 if (NULL == bss_status)
14518 {
14519 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014520 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014521 }
14522 else
14523 {
Yue Maf49ba872013-08-19 12:04:25 -070014524 cfg80211_put_bss(
14525#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
14526 wiphy,
14527#endif
14528 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070014529 }
14530
14531 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14532 }
14533
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014534 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014535 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014536 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014537}
14538
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014539void
14540hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
14541{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014542 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080014543 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014544} /****** end hddPrintMacAddr() ******/
14545
14546void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014547hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014548{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014549 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014550 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014551 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
14552 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
14553 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014554} /****** end hddPrintPmkId() ******/
14555
14556//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
14557//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
14558
14559//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
14560//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
14561
14562#define dump_bssid(bssid) \
14563 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014564 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
14565 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014566 }
14567
14568#define dump_pmkid(pMac, pmkid) \
14569 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014570 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
14571 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014572 }
14573
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070014574#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014575/*
14576 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
14577 * This function is used to notify the supplicant of a new PMKSA candidate.
14578 */
14579int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014580 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014581 int index, bool preauth )
14582{
Jeff Johnsone7245742012-09-05 17:12:55 -070014583#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014584 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014585 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014586
14587 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070014588 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014589
14590 if( NULL == pRoamInfo )
14591 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014592 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014593 return -EINVAL;
14594 }
14595
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014596 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
14597 {
14598 dump_bssid(pRoamInfo->bssid);
14599 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014600 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014601 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014602#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014603 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014604}
14605#endif //FEATURE_WLAN_LFR
14606
Yue Maef608272013-04-08 23:09:17 -070014607#ifdef FEATURE_WLAN_LFR_METRICS
14608/*
14609 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
14610 * 802.11r/LFR metrics reporting function to report preauth initiation
14611 *
14612 */
14613#define MAX_LFR_METRICS_EVENT_LENGTH 100
14614VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
14615 tCsrRoamInfo *pRoamInfo)
14616{
14617 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14618 union iwreq_data wrqu;
14619
14620 ENTER();
14621
14622 if (NULL == pAdapter)
14623 {
14624 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14625 return VOS_STATUS_E_FAILURE;
14626 }
14627
14628 /* create the event */
14629 memset(&wrqu, 0, sizeof(wrqu));
14630 memset(metrics_notification, 0, sizeof(metrics_notification));
14631
14632 wrqu.data.pointer = metrics_notification;
14633 wrqu.data.length = scnprintf(metrics_notification,
14634 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
14635 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14636
14637 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14638
14639 EXIT();
14640
14641 return VOS_STATUS_SUCCESS;
14642}
14643
14644/*
14645 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
14646 * 802.11r/LFR metrics reporting function to report preauth completion
14647 * or failure
14648 */
14649VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
14650 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
14651{
14652 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14653 union iwreq_data wrqu;
14654
14655 ENTER();
14656
14657 if (NULL == pAdapter)
14658 {
14659 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14660 return VOS_STATUS_E_FAILURE;
14661 }
14662
14663 /* create the event */
14664 memset(&wrqu, 0, sizeof(wrqu));
14665 memset(metrics_notification, 0, sizeof(metrics_notification));
14666
14667 scnprintf(metrics_notification, sizeof(metrics_notification),
14668 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
14669 MAC_ADDR_ARRAY(pRoamInfo->bssid));
14670
14671 if (1 == preauth_status)
14672 strncat(metrics_notification, " TRUE", 5);
14673 else
14674 strncat(metrics_notification, " FALSE", 6);
14675
14676 wrqu.data.pointer = metrics_notification;
14677 wrqu.data.length = strlen(metrics_notification);
14678
14679 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14680
14681 EXIT();
14682
14683 return VOS_STATUS_SUCCESS;
14684}
14685
14686/*
14687 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
14688 * 802.11r/LFR metrics reporting function to report handover initiation
14689 *
14690 */
14691VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
14692 tCsrRoamInfo *pRoamInfo)
14693{
14694 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14695 union iwreq_data wrqu;
14696
14697 ENTER();
14698
14699 if (NULL == pAdapter)
14700 {
14701 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14702 return VOS_STATUS_E_FAILURE;
14703 }
14704
14705 /* create the event */
14706 memset(&wrqu, 0, sizeof(wrqu));
14707 memset(metrics_notification, 0, sizeof(metrics_notification));
14708
14709 wrqu.data.pointer = metrics_notification;
14710 wrqu.data.length = scnprintf(metrics_notification,
14711 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14712 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14713
14714 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14715
14716 EXIT();
14717
14718 return VOS_STATUS_SUCCESS;
14719}
14720#endif
14721
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014722
14723/**
14724 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14725 * @scan_req: scan request to be checked
14726 *
14727 * Return: true or false
14728 */
14729#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14730static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14731 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014732 *scan_req, hdd_context_t
14733 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014734{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014735 if (!scan_req || !scan_req->wiphy ||
14736 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014737 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14738 return false;
14739 }
14740 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14741 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14742 return false;
14743 }
14744 return true;
14745}
14746#else
14747static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14748 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014749 *scan_req, hdd_context_t
14750 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014751{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014752 if (!scan_req || !scan_req->wiphy ||
14753 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014754 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14755 return false;
14756 }
14757 return true;
14758}
14759#endif
14760
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014761#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
14762/**
14763 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14764 * @adapter: Pointer to the adapter
14765 * @req : Scan request
14766 * @aborted : true scan aborted false scan success
14767 *
14768 * This function notifies scan done to cfg80211
14769 *
14770 * Return: none
14771 */
14772static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14773 struct cfg80211_scan_request *req,
14774 bool aborted)
14775{
14776 struct cfg80211_scan_info info = {
14777 .aborted = aborted
14778 };
14779
14780 if (adapter->dev->flags & IFF_UP)
14781 cfg80211_scan_done(req, &info);
14782 else
14783 hddLog(LOGW,
14784 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14785}
14786#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14787/**
14788 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14789 * @adapter: Pointer to the adapter
14790 * @req : Scan request
14791 * @aborted : true scan aborted false scan success
14792 *
14793 * This function notifies scan done to cfg80211
14794 *
14795 * Return: none
14796 */
14797static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14798 struct cfg80211_scan_request *req,
14799 bool aborted)
14800{
14801 if (adapter->dev->flags & IFF_UP)
14802 cfg80211_scan_done(req, aborted);
14803 else
14804 hddLog(LOGW,
14805 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14806}
14807#else
14808/**
14809 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14810 * @adapter: Pointer to the adapter
14811 * @req : Scan request
14812 * @aborted : true scan aborted false scan success
14813 *
14814 * This function notifies scan done to cfg80211
14815 *
14816 * Return: none
14817 */
14818static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14819 struct cfg80211_scan_request *req,
14820 bool aborted)
14821{
14822 cfg80211_scan_done(req, aborted);
14823}
14824#endif
14825
Mukul Sharmab392b642017-08-17 17:45:29 +053014826#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014827/*
14828 * FUNCTION: hdd_cfg80211_scan_done_callback
14829 * scanning callback function, called after finishing scan
14830 *
14831 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014832static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014833 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14834{
14835 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014836 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014837 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014838 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014839 struct cfg80211_scan_request *req = NULL;
14840 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014841 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014842 long waitRet = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014843 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014844
14845 ENTER();
14846
c_manjee1b4ab9a2016-10-26 11:36:55 +053014847 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14848 !pAdapter->dev) {
14849 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14850 return 0;
14851 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014852 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014853 if (NULL == pHddCtx) {
14854 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014855 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014856 }
14857
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014858#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014859 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014860 {
14861 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014862 }
14863#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014864 pScanInfo = &pHddCtx->scan_info;
14865
Jeff Johnson295189b2012-06-20 16:38:30 -070014866 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014867 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014868 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014869 __func__, halHandle, pContext, (int) scanId, (int) status);
14870
Kiet Lamac06e2c2013-10-23 16:25:07 +053014871 pScanInfo->mScanPendingCounter = 0;
14872
Jeff Johnson295189b2012-06-20 16:38:30 -070014873 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014874 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014875 &pScanInfo->scan_req_completion_event,
14876 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014877 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014878 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014879 hddLog(VOS_TRACE_LEVEL_ERROR,
14880 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014881 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014882 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014883 }
14884
Yue Maef608272013-04-08 23:09:17 -070014885 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014886 {
14887 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014888 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014889 }
14890
14891 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014892 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014893 {
14894 hddLog(VOS_TRACE_LEVEL_INFO,
14895 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014896 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014897 (int) scanId);
14898 }
14899
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014900#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014901 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014902#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014903 {
14904 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14905 pAdapter);
14906 if (0 > ret)
14907 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014908 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014909
Jeff Johnson295189b2012-06-20 16:38:30 -070014910 /* If any client wait scan result through WEXT
14911 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014912 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014913 {
14914 /* The other scan request waiting for current scan finish
14915 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014916 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014917 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014918 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014919 }
14920 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014921 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014922 {
14923 struct net_device *dev = pAdapter->dev;
14924 union iwreq_data wrqu;
14925 int we_event;
14926 char *msg;
14927
14928 memset(&wrqu, '\0', sizeof(wrqu));
14929 we_event = SIOCGIWSCAN;
14930 msg = NULL;
14931 wireless_send_event(dev, we_event, &wrqu, msg);
14932 }
14933 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014934 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014935
14936 /* Get the Scan Req */
14937 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014938 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014939
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014940 /* Scan is no longer pending */
14941 pScanInfo->mScanPending = VOS_FALSE;
14942
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014943 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070014944 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014945#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
14946 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053014947 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014948#endif
14949
14950 if (pAdapter->dev) {
14951 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
14952 pAdapter->dev->name);
14953 }
mukul sharmae7041822015-12-03 15:09:21 +053014954 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070014955 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014956 }
14957
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014958 /* last_scan_timestamp is used to decide if new scan
14959 * is needed or not on station interface. If last station
14960 * scan time and new station scan time is less then
14961 * last_scan_timestamp ; driver will return cached scan.
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014962 * Also only last_scan_timestamp is updated here last_scan_channellist
14963 * is updated on receiving scan request itself to make sure kernel
14964 * allocated scan request(scan_req) object is not dereferenced here,
14965 * because interface down, where kernel frees scan_req, may happen any
14966 * time while driver is processing scan_done_callback. So it's better
14967 * not to access scan_req in this routine.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014968 */
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014969 if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
14970 if (status == eCSR_SCAN_SUCCESS)
14971 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
14972 else {
14973 vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
14974 sizeof(pHddCtx->scan_info.last_scan_channelList));
14975 pHddCtx->scan_info.last_scan_numChannels = 0;
14976 pScanInfo->last_scan_timestamp = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014977 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014978 }
14979
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070014980 /*
14981 * cfg80211_scan_done informing NL80211 about completion
14982 * of scanning
14983 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014984 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
14985 {
14986 aborted = true;
14987 }
mukul sharmae7041822015-12-03 15:09:21 +053014988
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014989#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014990 if (NET_DEV_IS_IFF_UP(pAdapter) &&
14991 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014992#endif
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014993 hdd_cfg80211_scan_done(pAdapter, req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053014994
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080014995 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070014996
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014997allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014998 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
14999 ) && (pHddCtx->spoofMacAddr.isEnabled
15000 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053015001 /* Generate new random mac addr for next scan */
15002 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053015003
15004 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
15005 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053015006 }
15007
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015008 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015009 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015010
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015011 /* Acquire wakelock to handle the case where APP's tries to suspend
15012 * immediatly after the driver gets connect request(i.e after scan)
15013 * from supplicant, this result in app's is suspending and not able
15014 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015015 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015016
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015017#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015018 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015019#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015020#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015021 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015022#endif
15023
Jeff Johnson295189b2012-06-20 16:38:30 -070015024 EXIT();
15025 return 0;
15026}
15027
15028/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053015029 * FUNCTION: hdd_isConnectionInProgress
15030 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015031 *
15032 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015033v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
15034 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015035{
15036 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15037 hdd_station_ctx_t *pHddStaCtx = NULL;
15038 hdd_adapter_t *pAdapter = NULL;
15039 VOS_STATUS status = 0;
15040 v_U8_t staId = 0;
15041 v_U8_t *staMac = NULL;
15042
15043 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15044
15045 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15046 {
15047 pAdapter = pAdapterNode->pAdapter;
15048
15049 if( pAdapter )
15050 {
15051 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015052 "%s: Adapter with device mode %s (%d) exists",
15053 __func__, hdd_device_modetoString(pAdapter->device_mode),
15054 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015055 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053015056 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15057 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
15058 (eConnectionState_Connecting ==
15059 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
15060 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015061 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015062 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053015063 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015064 if (session_id && reason)
15065 {
15066 *session_id = pAdapter->sessionId;
15067 *reason = eHDD_CONNECTION_IN_PROGRESS;
15068 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015069 return VOS_TRUE;
15070 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015071 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053015072 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015073 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015074 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015075 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015076 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015077 if (session_id && reason)
15078 {
15079 *session_id = pAdapter->sessionId;
15080 *reason = eHDD_REASSOC_IN_PROGRESS;
15081 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015082 return VOS_TRUE;
15083 }
15084 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015085 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15086 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015087 {
15088 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15089 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015090 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015091 {
15092 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015093 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015094 "%s: client " MAC_ADDRESS_STR
15095 " is in the middle of WPS/EAPOL exchange.", __func__,
15096 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015097 if (session_id && reason)
15098 {
15099 *session_id = pAdapter->sessionId;
15100 *reason = eHDD_EAPOL_IN_PROGRESS;
15101 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015102 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015103 }
15104 }
15105 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
15106 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
15107 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015108 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15109 ptSapContext pSapCtx = NULL;
15110 pSapCtx = VOS_GET_SAP_CB(pVosContext);
15111 if(pSapCtx == NULL){
15112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15113 FL("psapCtx is NULL"));
15114 return VOS_FALSE;
15115 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015116 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
15117 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015118 if ((pSapCtx->aStaInfo[staId].isUsed) &&
15119 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015120 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015121 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015122
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015123 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015124 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
15125 "middle of WPS/EAPOL exchange.", __func__,
15126 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015127 if (session_id && reason)
15128 {
15129 *session_id = pAdapter->sessionId;
15130 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
15131 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015132 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015133 }
15134 }
15135 }
15136 }
15137 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15138 pAdapterNode = pNext;
15139 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015140 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015141}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015142
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015143/**
15144 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
15145 * to the Scan request
15146 * @scanRequest: Pointer to the csr scan request
15147 * @request: Pointer to the scan request from supplicant
15148 *
15149 * Return: None
15150 */
15151#ifdef CFG80211_SCAN_BSSID
15152static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15153 struct cfg80211_scan_request *request)
15154{
15155 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
15156}
15157#else
15158static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15159 struct cfg80211_scan_request *request)
15160{
15161}
15162#endif
15163
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015164/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015165 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070015166 * this scan respond to scan trigger and update cfg80211 scan database
15167 * later, scan dump command can be used to recieve scan results
15168 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015169int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015170#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15171 struct net_device *dev,
15172#endif
15173 struct cfg80211_scan_request *request)
15174{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015175 hdd_adapter_t *pAdapter = NULL;
15176 hdd_context_t *pHddCtx = NULL;
15177 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015178 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015179 tCsrScanRequest scanRequest;
15180 tANI_U8 *channelList = NULL, i;
15181 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015182 int status;
15183 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015184 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015185 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053015186 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015187 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015188 v_U8_t curr_session_id;
15189 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070015190
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015191#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
15192 struct net_device *dev = NULL;
15193 if (NULL == request)
15194 {
15195 hddLog(VOS_TRACE_LEVEL_ERROR,
15196 "%s: scan req param null", __func__);
15197 return -EINVAL;
15198 }
15199 dev = request->wdev->netdev;
15200#endif
15201
15202 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15203 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
15204 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15205
Jeff Johnson295189b2012-06-20 16:38:30 -070015206 ENTER();
15207
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015208 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
15209 __func__, hdd_device_modetoString(pAdapter->device_mode),
15210 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015211
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015212 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015213 if (0 != status)
15214 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015215 return status;
15216 }
15217
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015218 if (NULL == pwextBuf)
15219 {
15220 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
15221 __func__);
15222 return -EIO;
15223 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015224 cfg_param = pHddCtx->cfg_ini;
15225 pScanInfo = &pHddCtx->scan_info;
15226
Jeff Johnson295189b2012-06-20 16:38:30 -070015227#ifdef WLAN_BTAMP_FEATURE
15228 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015229 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070015230 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015231 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015232 "%s: No scanning when AMP is on", __func__);
15233 return -EOPNOTSUPP;
15234 }
15235#endif
15236 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015237 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070015238 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015239 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015240 "%s: Not scanning on device_mode = %s (%d)",
15241 __func__, hdd_device_modetoString(pAdapter->device_mode),
15242 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015243 return -EOPNOTSUPP;
15244 }
15245
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015246 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
15247 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
15248 return -EOPNOTSUPP;
15249 }
15250
Jeff Johnson295189b2012-06-20 16:38:30 -070015251 if (TRUE == pScanInfo->mScanPending)
15252 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015253 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
15254 {
15255 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
15256 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015257 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015258 }
15259
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053015260 // Don't allow scan if PNO scan is going on.
15261 if (pHddCtx->isPnoEnable)
15262 {
15263 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15264 FL("pno scan in progress"));
15265 return -EBUSY;
15266 }
15267
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015268 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070015269 //Channel and action frame is pending
15270 //Otherwise Cancel Remain On Channel and allow Scan
15271 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015272 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070015273 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015274 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070015275 return -EBUSY;
15276 }
15277
Jeff Johnson295189b2012-06-20 16:38:30 -070015278 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
15279 {
15280 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080015281 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015282 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015283 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015284 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
15285 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015286 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015287 "%s: MAX TM Level Scan not allowed", __func__);
15288 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015289 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015290 }
15291 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
15292
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015293 /* Check if scan is allowed at this point of time.
15294 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053015295 if (TRUE == pHddCtx->btCoexModeSet)
15296 {
15297 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15298 FL("BTCoex Mode operation in progress"));
15299 return -EBUSY;
15300 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015301 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015302 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015303
15304 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
15305 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
15306 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015307 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
15308 pHddCtx->last_scan_reject_reason != curr_reason ||
15309 !pHddCtx->last_scan_reject_timestamp)
15310 {
15311 pHddCtx->last_scan_reject_session_id = curr_session_id;
15312 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053015313 pHddCtx->last_scan_reject_timestamp =
15314 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015315 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053015316 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053015317 else
15318 {
15319 pHddCtx->scan_reject_cnt++;
15320
Abhishek Singhe4b12562017-06-20 16:53:39 +053015321 if ((pHddCtx->scan_reject_cnt >=
15322 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053015323 vos_system_time_after(jiffies_to_msecs(jiffies),
15324 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015325 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015326 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
15327 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
15328 vos_system_time_after(jiffies_to_msecs(jiffies),
15329 pHddCtx->last_scan_reject_timestamp));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015330 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015331 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015332 if (pHddCtx->cfg_ini->enableFatalEvent)
15333 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
15334 WLAN_LOG_INDICATOR_HOST_DRIVER,
15335 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
15336 FALSE, FALSE);
15337 else
15338 {
15339 hddLog(LOGE, FL("Triggering SSR"));
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +053015340 vos_wlanRestart(VOS_SCAN_REQ_EXPIRED);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015341 }
15342 }
15343 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015344 return -EBUSY;
15345 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015346 pHddCtx->last_scan_reject_timestamp = 0;
15347 pHddCtx->last_scan_reject_session_id = 0xFF;
15348 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015349 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015350
Jeff Johnson295189b2012-06-20 16:38:30 -070015351 vos_mem_zero( &scanRequest, sizeof(scanRequest));
15352
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015353 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
15354 * Becasue of this, driver is assuming that this is not wildcard scan and so
15355 * is not aging out the scan results.
15356 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053015357 if ((request->ssids) && (request->n_ssids == 1) &&
15358 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015359 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015360 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015361
15362 if ((request->ssids) && (0 < request->n_ssids))
15363 {
15364 tCsrSSIDInfo *SsidInfo;
15365 int j;
15366 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
15367 /* Allocate num_ssid tCsrSSIDInfo structure */
15368 SsidInfo = scanRequest.SSIDs.SSIDList =
15369 ( tCsrSSIDInfo *)vos_mem_malloc(
15370 request->n_ssids*sizeof(tCsrSSIDInfo));
15371
15372 if(NULL == scanRequest.SSIDs.SSIDList)
15373 {
15374 hddLog(VOS_TRACE_LEVEL_ERROR,
15375 "%s: memory alloc failed SSIDInfo buffer", __func__);
15376 return -ENOMEM;
15377 }
15378
15379 /* copy all the ssid's and their length */
15380 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
15381 {
15382 /* get the ssid length */
15383 SsidInfo->SSID.length = request->ssids[j].ssid_len;
15384 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
15385 SsidInfo->SSID.length);
15386 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
15387 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
15388 j, SsidInfo->SSID.ssId);
15389 }
15390 /* set the scan type to active */
15391 scanRequest.scanType = eSIR_ACTIVE_SCAN;
15392 }
15393 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015394 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015395 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15396 TRACE_CODE_HDD_CFG80211_SCAN,
15397 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070015398 /* set the scan type to active */
15399 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070015400 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015401 else
15402 {
15403 /*Set the scan type to default type, in this case it is ACTIVE*/
15404 scanRequest.scanType = pScanInfo->scan_mode;
15405 }
15406 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
15407 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070015408
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015409 csr_scan_request_assign_bssid(&scanRequest, request);
15410
Jeff Johnson295189b2012-06-20 16:38:30 -070015411 /* set BSSType to default type */
15412 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
15413
15414 /*TODO: scan the requested channels only*/
15415
15416 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015417 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070015418 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015419 hddLog(VOS_TRACE_LEVEL_WARN,
15420 "No of Scan Channels exceeded limit: %d", request->n_channels);
15421 request->n_channels = MAX_CHANNEL;
15422 }
15423
15424 hddLog(VOS_TRACE_LEVEL_INFO,
15425 "No of Scan Channels: %d", request->n_channels);
15426
15427
15428 if( request->n_channels )
15429 {
15430 char chList [(request->n_channels*5)+1];
15431 int len;
15432 channelList = vos_mem_malloc( request->n_channels );
15433 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053015434 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015435 hddLog(VOS_TRACE_LEVEL_ERROR,
15436 "%s: memory alloc failed channelList", __func__);
15437 status = -ENOMEM;
15438 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053015439 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015440
15441 for( i = 0, len = 0; i < request->n_channels ; i++ )
15442 {
15443 channelList[i] = request->channels[i]->hw_value;
15444 len += snprintf(chList+len, 5, "%d ", channelList[i]);
15445 }
15446
Nirav Shah20ac06f2013-12-12 18:14:06 +053015447 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015448 "Channel-List: %s ", chList);
15449 }
c_hpothu53512302014-04-15 18:49:53 +053015450
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015451 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
15452 scanRequest.ChannelInfo.ChannelList = channelList;
15453
15454 /* set requestType to full scan */
15455 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
15456
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015457 /* if there is back to back scan happening in driver with in
15458 * nDeferScanTimeInterval interval driver should defer new scan request
15459 * and should provide last cached scan results instead of new channel list.
15460 * This rule is not applicable if scan is p2p scan.
15461 * This condition will work only in case when last request no of channels
15462 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053015463 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053015464 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015465 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015466
Sushant Kaushik86592172015-04-27 16:35:03 +053015467 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
15468 /* if wps ie is NULL , then only defer scan */
15469 if ( pWpsIe == NULL &&
15470 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053015471 {
15472 if ( pScanInfo->last_scan_timestamp !=0 &&
15473 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
15474 {
15475 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
15476 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
15477 vos_mem_compare(pScanInfo->last_scan_channelList,
15478 channelList, pScanInfo->last_scan_numChannels))
15479 {
15480 hddLog(VOS_TRACE_LEVEL_WARN,
15481 " New and old station scan time differ is less then %u",
15482 pHddCtx->cfg_ini->nDeferScanTimeInterval);
15483
15484 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015485 pAdapter);
15486
Agarwal Ashish57e84372014-12-05 18:26:53 +053015487 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015488 "Return old cached scan as all channels and no of channels are same");
15489
Agarwal Ashish57e84372014-12-05 18:26:53 +053015490 if (0 > ret)
15491 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015492
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015493 hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015494
15495 status = eHAL_STATUS_SUCCESS;
15496 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053015497 }
15498 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015499 }
15500
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015501 /* Flush the scan results(only p2p beacons) for STA scan and P2P
15502 * search (Flush on both full scan and social scan but not on single
15503 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
15504 */
15505
15506 /* Supplicant does single channel scan after 8-way handshake
15507 * and in that case driver shoudnt flush scan results. If
15508 * driver flushes the scan results here and unfortunately if
15509 * the AP doesnt respond to our probe req then association
15510 * fails which is not desired
15511 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015512 if ((request->n_ssids == 1)
15513 && (request->ssids != NULL)
15514 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
15515 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015516
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015517 if( is_p2p_scan ||
15518 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015519 {
15520 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
15521 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
15522 pAdapter->sessionId );
15523 }
15524
15525 if( request->ie_len )
15526 {
15527 /* save this for future association (join requires this) */
15528 /*TODO: Array needs to be converted to dynamic allocation,
15529 * as multiple ie.s can be sent in cfg80211_scan_request structure
15530 * CR 597966
15531 */
15532 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
15533 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
15534 pScanInfo->scanAddIE.length = request->ie_len;
15535
15536 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15537 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15538 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015539 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015540 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070015541 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015542 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
15543 memcpy( pwextBuf->roamProfile.addIEScan,
15544 request->ie, request->ie_len);
15545 }
15546 else
15547 {
15548 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
15549 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070015550 }
15551
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015552 }
15553 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
15554 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
15555
15556 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
15557 request->ie_len);
15558 if (pP2pIe != NULL)
15559 {
15560#ifdef WLAN_FEATURE_P2P_DEBUG
15561 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
15562 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
15563 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053015564 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015565 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
15566 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15567 "Go nego completed to Connection is started");
15568 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15569 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053015570 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015571 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
15572 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015573 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015574 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
15575 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15576 "Disconnected state to Connection is started");
15577 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15578 "for 4way Handshake");
15579 }
15580#endif
15581
15582 /* no_cck will be set during p2p find to disable 11b rates */
15583 if(TRUE == request->no_cck)
15584 {
15585 hddLog(VOS_TRACE_LEVEL_INFO,
15586 "%s: This is a P2P Search", __func__);
15587 scanRequest.p2pSearch = 1;
15588
15589 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053015590 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015591 /* set requestType to P2P Discovery */
15592 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
15593 }
15594
15595 /*
15596 Skip Dfs Channel in case of P2P Search
15597 if it is set in ini file
15598 */
15599 if(cfg_param->skipDfsChnlInP2pSearch)
15600 {
15601 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015602 }
15603 else
15604 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015605 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015606 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015607
Agarwal Ashish4f616132013-12-30 23:32:50 +053015608 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015609 }
15610 }
15611
15612 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
15613
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015614#ifdef FEATURE_WLAN_TDLS
15615 /* if tdls disagree scan right now, return immediately.
15616 tdls will schedule the scan when scan is allowed. (return SUCCESS)
15617 or will reject the scan if any TDLS is in progress. (return -EBUSY)
15618 */
15619 status = wlan_hdd_tdls_scan_callback (pAdapter,
15620 wiphy,
15621#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15622 dev,
15623#endif
15624 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015625 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015626 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053015627 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015628 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
15629 "scan rejected %d", __func__, status);
15630 else
15631 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
15632 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015633 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053015634 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015635 }
15636#endif
15637
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015638 /* acquire the wakelock to avoid the apps suspend during the scan. To
15639 * address the following issues.
15640 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
15641 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
15642 * for long time, this result in apps running at full power for long time.
15643 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
15644 * be stuck in full power because of resume BMPS
15645 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015646 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015647
Nirav Shah20ac06f2013-12-12 18:14:06 +053015648 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
15649 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015650 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
15651 scanRequest.requestType, scanRequest.scanType,
15652 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053015653 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
15654
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015655 if (pHddCtx->spoofMacAddr.isEnabled &&
15656 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053015657 {
15658 hddLog(VOS_TRACE_LEVEL_INFO,
15659 "%s: MAC Spoofing enabled for current scan", __func__);
15660 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15661 * to fill TxBds for probe request during current scan
15662 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015663 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053015664 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015665
15666 if(status != VOS_STATUS_SUCCESS)
15667 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015668 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015669 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053015670#ifdef FEATURE_WLAN_TDLS
15671 wlan_hdd_tdls_scan_done_callback(pAdapter);
15672#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015673 goto free_mem;
15674 }
Siddharth Bhal76972212014-10-15 16:22:51 +053015675 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053015676 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070015677 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015678 pAdapter->sessionId, &scanRequest, &scanId,
15679 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070015680
Jeff Johnson295189b2012-06-20 16:38:30 -070015681 if (eHAL_STATUS_SUCCESS != status)
15682 {
15683 hddLog(VOS_TRACE_LEVEL_ERROR,
15684 "%s: sme_ScanRequest returned error %d", __func__, status);
15685 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015686 if(eHAL_STATUS_RESOURCES == status)
15687 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015688 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
15689 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015690 status = -EBUSY;
15691 } else {
15692 status = -EIO;
15693 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015694 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015695
15696#ifdef FEATURE_WLAN_TDLS
15697 wlan_hdd_tdls_scan_done_callback(pAdapter);
15698#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015699 goto free_mem;
15700 }
15701
15702 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015703 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070015704 pAdapter->request = request;
15705 pScanInfo->scanId = scanId;
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015706 pScanInfo->no_cck = request->no_cck;
15707 pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
15708 for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
15709 pHddCtx->scan_info.last_scan_channelList[i] =
15710 request->channels[i]->hw_value;
15711 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015712
15713 complete(&pScanInfo->scan_req_completion_event);
15714
15715free_mem:
15716 if( scanRequest.SSIDs.SSIDList )
15717 {
15718 vos_mem_free(scanRequest.SSIDs.SSIDList);
15719 }
15720
15721 if( channelList )
15722 vos_mem_free( channelList );
15723
15724 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015725 return status;
15726}
15727
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015728int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
15729#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15730 struct net_device *dev,
15731#endif
15732 struct cfg80211_scan_request *request)
15733{
15734 int ret;
15735
15736 vos_ssr_protect(__func__);
15737 ret = __wlan_hdd_cfg80211_scan(wiphy,
15738#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15739 dev,
15740#endif
15741 request);
15742 vos_ssr_unprotect(__func__);
15743
15744 return ret;
15745}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015746
15747void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
15748{
15749 v_U8_t iniDot11Mode =
15750 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
15751 eHddDot11Mode hddDot11Mode = iniDot11Mode;
15752
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015753 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
15754 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015755 switch ( iniDot11Mode )
15756 {
15757 case eHDD_DOT11_MODE_AUTO:
15758 case eHDD_DOT11_MODE_11ac:
15759 case eHDD_DOT11_MODE_11ac_ONLY:
15760#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053015761 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
15762 sme_IsFeatureSupportedByFW(DOT11AC) )
15763 hddDot11Mode = eHDD_DOT11_MODE_11ac;
15764 else
15765 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015766#else
15767 hddDot11Mode = eHDD_DOT11_MODE_11n;
15768#endif
15769 break;
15770 case eHDD_DOT11_MODE_11n:
15771 case eHDD_DOT11_MODE_11n_ONLY:
15772 hddDot11Mode = eHDD_DOT11_MODE_11n;
15773 break;
15774 default:
15775 hddDot11Mode = iniDot11Mode;
15776 break;
15777 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015778#ifdef WLAN_FEATURE_AP_HT40_24G
15779 if (operationChannel > SIR_11B_CHANNEL_END)
15780#endif
15781 {
15782 /* This call decides required channel bonding mode */
15783 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015784 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053015785 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015786 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015787}
15788
Jeff Johnson295189b2012-06-20 16:38:30 -070015789/*
15790 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015791 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015792 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015793int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053015794 const u8 *ssid, size_t ssid_len, const u8 *bssid,
15795 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070015796{
15797 int status = 0;
15798 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080015799 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015800 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015801 v_U32_t roamId;
15802 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070015803 eCsrAuthType RSNAuthType;
15804
15805 ENTER();
15806
15807 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015808 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015809 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015810
15811 status = wlan_hdd_validate_context(pHddCtx);
15812 if (status)
15813 {
Yue Mae36e3552014-03-05 17:06:20 -080015814 return status;
15815 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015816
Jeff Johnson295189b2012-06-20 16:38:30 -070015817 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
15818 {
15819 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
15820 return -EINVAL;
15821 }
15822
Nitesh Shah9b066282017-06-06 18:05:52 +053015823
Jeff Johnson295189b2012-06-20 16:38:30 -070015824 pRoamProfile = &pWextState->roamProfile;
15825
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015826 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070015827 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015828 hdd_station_ctx_t *pHddStaCtx;
15829 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053015830 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015831
Siddharth Bhalda0d1622015-04-24 15:47:49 +053015832 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
15833
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015834 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070015835 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
15836 {
15837 /*QoS not enabled in cfg file*/
15838 pRoamProfile->uapsd_mask = 0;
15839 }
15840 else
15841 {
15842 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015843 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070015844 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
15845 }
15846
15847 pRoamProfile->SSIDs.numOfSSIDs = 1;
15848 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
15849 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015850 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070015851 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
15852 ssid, ssid_len);
15853
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015854 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
15855 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
15856
Jeff Johnson295189b2012-06-20 16:38:30 -070015857 if (bssid)
15858 {
15859 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015860 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015861 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015862 /* Save BSSID in seperate variable as well, as RoamProfile
15863 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070015864 case of join failure we should send valid BSSID to supplicant
15865 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015866 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015867 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015868
Jeff Johnson295189b2012-06-20 16:38:30 -070015869 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015870 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070015871 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015872 /* Store bssid_hint to use in the scan filter. */
15873 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15874 WNI_CFG_BSSID_LEN);
15875 /*
15876 * Save BSSID in seperate variable as well, as RoamProfile
15877 * BSSID is getting zeroed out in the association process. And in
15878 * case of join failure we should send valid BSSID to supplicant
15879 */
15880 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15881 WNI_CFG_BSSID_LEN);
15882 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15883 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015884 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015885
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015886
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015887 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15888 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015889 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15890 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015891 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015892 /*set gen ie*/
15893 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15894 /*set auth*/
15895 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15896 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015897#ifdef FEATURE_WLAN_WAPI
15898 if (pAdapter->wapi_info.nWapiMode)
15899 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015900 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015901 switch (pAdapter->wapi_info.wapiAuthMode)
15902 {
15903 case WAPI_AUTH_MODE_PSK:
15904 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015905 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015906 pAdapter->wapi_info.wapiAuthMode);
15907 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15908 break;
15909 }
15910 case WAPI_AUTH_MODE_CERT:
15911 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015912 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015913 pAdapter->wapi_info.wapiAuthMode);
15914 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15915 break;
15916 }
15917 } // End of switch
15918 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15919 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15920 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015921 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015922 pRoamProfile->AuthType.numEntries = 1;
15923 pRoamProfile->EncryptionType.numEntries = 1;
15924 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15925 pRoamProfile->mcEncryptionType.numEntries = 1;
15926 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15927 }
15928 }
15929#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015930#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015931 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015932 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15933 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
15934 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015935 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
15936 sizeof (tSirGtkOffloadParams));
15937 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015938 }
15939#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015940 pRoamProfile->csrPersona = pAdapter->device_mode;
15941
Jeff Johnson32d95a32012-09-10 13:15:23 -070015942 if( operatingChannel )
15943 {
15944 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
15945 pRoamProfile->ChannelInfo.numOfChannels = 1;
15946 }
Chet Lanctot186b5732013-03-18 10:26:30 -070015947 else
15948 {
15949 pRoamProfile->ChannelInfo.ChannelList = NULL;
15950 pRoamProfile->ChannelInfo.numOfChannels = 0;
15951 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015952 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
15953 {
15954 hdd_select_cbmode(pAdapter,operatingChannel);
15955 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015956
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015957 /*
15958 * Change conn_state to connecting before sme_RoamConnect(),
15959 * because sme_RoamConnect() has a direct path to call
15960 * hdd_smeRoamCallback(), which will change the conn_state
15961 * If direct path, conn_state will be accordingly changed
15962 * to NotConnected or Associated by either
15963 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
15964 * in sme_RoamCallback()
15965 * if sme_RomConnect is to be queued,
15966 * Connecting state will remain until it is completed.
15967 * If connection state is not changed,
15968 * connection state will remain in eConnectionState_NotConnected state.
15969 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
15970 * if conn state is eConnectionState_NotConnected.
15971 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
15972 * informed of connect result indication which is an issue.
15973 */
15974
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015975 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15976 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053015977 {
15978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015979 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015980 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
15981 eConnectionState_Connecting);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053015982 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
15983 hdd_wait_for_ecsa_complete(pHddCtx);
Abhishek Singhf4669da2014-05-26 15:07:49 +053015984 }
Abhishek Singh10e17cf2018-03-12 14:34:22 +053015985
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015986 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015987 pAdapter->sessionId, pRoamProfile, &roamId);
15988
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015989 if ((eHAL_STATUS_SUCCESS != status) &&
15990 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15991 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015992
15993 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015994 hddLog(VOS_TRACE_LEVEL_ERROR,
15995 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
15996 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015997 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015998 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015999 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016000 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016001
16002 pRoamProfile->ChannelInfo.ChannelList = NULL;
16003 pRoamProfile->ChannelInfo.numOfChannels = 0;
16004
Jeff Johnson295189b2012-06-20 16:38:30 -070016005 }
16006 else
16007 {
16008 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
16009 return -EINVAL;
16010 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080016011 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016012 return status;
16013}
16014
16015/*
16016 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
16017 * This function is used to set the authentication type (OPEN/SHARED).
16018 *
16019 */
16020static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
16021 enum nl80211_auth_type auth_type)
16022{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016023 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016024 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16025
16026 ENTER();
16027
16028 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016029 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070016030 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016031 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016032 hddLog(VOS_TRACE_LEVEL_INFO,
16033 "%s: set authentication type to AUTOSWITCH", __func__);
16034 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
16035 break;
16036
16037 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016038#ifdef WLAN_FEATURE_VOWIFI_11R
16039 case NL80211_AUTHTYPE_FT:
16040#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016041 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016042 "%s: set authentication type to OPEN", __func__);
16043 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
16044 break;
16045
16046 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016047 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016048 "%s: set authentication type to SHARED", __func__);
16049 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
16050 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016051#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016052 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016053 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016054 "%s: set authentication type to CCKM WPA", __func__);
16055 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
16056 break;
16057#endif
16058
16059
16060 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016061 hddLog(VOS_TRACE_LEVEL_ERROR,
16062 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016063 auth_type);
16064 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
16065 return -EINVAL;
16066 }
16067
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016068 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016069 pHddStaCtx->conn_info.authType;
16070 return 0;
16071}
16072
16073/*
16074 * FUNCTION: wlan_hdd_set_akm_suite
16075 * This function is used to set the key mgmt type(PSK/8021x).
16076 *
16077 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016078static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016079 u32 key_mgmt
16080 )
16081{
16082 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16083 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053016084 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016085#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016086#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016087#endif
16088#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016089#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016090#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016091 /*set key mgmt type*/
16092 switch(key_mgmt)
16093 {
16094 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053016095 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016096#ifdef WLAN_FEATURE_VOWIFI_11R
16097 case WLAN_AKM_SUITE_FT_PSK:
16098#endif
16099 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070016100 __func__);
16101 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
16102 break;
16103
16104 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053016105 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016106#ifdef WLAN_FEATURE_VOWIFI_11R
16107 case WLAN_AKM_SUITE_FT_8021X:
16108#endif
16109 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070016110 __func__);
16111 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16112 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016113#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016114#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
16115#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
16116 case WLAN_AKM_SUITE_CCKM:
16117 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
16118 __func__);
16119 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
16120 break;
16121#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070016122#ifndef WLAN_AKM_SUITE_OSEN
16123#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
16124 case WLAN_AKM_SUITE_OSEN:
16125 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
16126 __func__);
16127 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16128 break;
16129#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016130
16131 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016132 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016133 __func__, key_mgmt);
16134 return -EINVAL;
16135
16136 }
16137 return 0;
16138}
16139
16140/*
16141 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016142 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070016143 * (NONE/WEP40/WEP104/TKIP/CCMP).
16144 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016145static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
16146 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070016147 bool ucast
16148 )
16149{
16150 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016151 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016152 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16153
16154 ENTER();
16155
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016156 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016157 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053016158 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070016159 __func__, cipher);
16160 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16161 }
16162 else
16163 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016164
Jeff Johnson295189b2012-06-20 16:38:30 -070016165 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016166 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016167 {
16168 case IW_AUTH_CIPHER_NONE:
16169 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16170 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016171
Jeff Johnson295189b2012-06-20 16:38:30 -070016172 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016173 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070016174 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016175
Jeff Johnson295189b2012-06-20 16:38:30 -070016176 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016177 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070016178 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016179
Jeff Johnson295189b2012-06-20 16:38:30 -070016180 case WLAN_CIPHER_SUITE_TKIP:
16181 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
16182 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016183
Jeff Johnson295189b2012-06-20 16:38:30 -070016184 case WLAN_CIPHER_SUITE_CCMP:
16185 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16186 break;
16187#ifdef FEATURE_WLAN_WAPI
16188 case WLAN_CIPHER_SUITE_SMS4:
16189 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
16190 break;
16191#endif
16192
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016193#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016194 case WLAN_CIPHER_SUITE_KRK:
16195 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
16196 break;
16197#endif
16198 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016199 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016200 __func__, cipher);
16201 return -EOPNOTSUPP;
16202 }
16203 }
16204
16205 if (ucast)
16206 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016207 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016208 __func__, encryptionType);
16209 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16210 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016211 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016212 encryptionType;
16213 }
16214 else
16215 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016216 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016217 __func__, encryptionType);
16218 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
16219 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
16220 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
16221 }
16222
16223 return 0;
16224}
16225
16226
16227/*
16228 * FUNCTION: wlan_hdd_cfg80211_set_ie
16229 * This function is used to parse WPA/RSN IE's.
16230 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016231int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016232#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16233 const u8 *ie,
16234#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016235 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016236#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016237 size_t ie_len
16238 )
16239{
16240 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016241#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16242 const u8 *genie = ie;
16243#else
Jeff Johnson295189b2012-06-20 16:38:30 -070016244 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016245#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016246 v_U16_t remLen = ie_len;
16247#ifdef FEATURE_WLAN_WAPI
16248 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
16249 u16 *tmp;
16250 v_U16_t akmsuiteCount;
16251 int *akmlist;
16252#endif
16253 ENTER();
16254
16255 /* clear previous assocAddIE */
16256 pWextState->assocAddIE.length = 0;
16257 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016258 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016259
16260 while (remLen >= 2)
16261 {
16262 v_U16_t eLen = 0;
16263 v_U8_t elementId;
16264 elementId = *genie++;
16265 eLen = *genie++;
16266 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016267
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053016268 /* Sanity check on eLen */
16269 if (eLen > remLen) {
16270 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
16271 __func__, eLen, elementId);
16272 VOS_ASSERT(0);
16273 return -EINVAL;
16274 }
16275
Arif Hussain6d2a3322013-11-17 19:50:10 -080016276 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070016277 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016278
16279 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070016280 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016281 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016282 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 -070016283 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016284 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016285 "%s: Invalid WPA IE", __func__);
16286 return -EINVAL;
16287 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016288 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070016289 {
16290 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016291 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016292 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016293
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016294 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016295 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016296 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
16297 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016298 VOS_ASSERT(0);
16299 return -ENOMEM;
16300 }
16301 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16302 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16303 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016304
Jeff Johnson295189b2012-06-20 16:38:30 -070016305 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
16306 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16307 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16308 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016309 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
16310 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053016311 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16312 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
16313 __func__, eLen);
16314 VOS_ASSERT(0);
16315 return -EINVAL;
16316 }
16317
Jeff Johnson295189b2012-06-20 16:38:30 -070016318 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
16319 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16320 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
16321 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
16322 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
16323 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016324 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053016325 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070016326 {
16327 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016328 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016329 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016330
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016331 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016332 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016333 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16334 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016335 VOS_ASSERT(0);
16336 return -ENOMEM;
16337 }
16338 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16339 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16340 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016341
Jeff Johnson295189b2012-06-20 16:38:30 -070016342 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16343 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16344 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016345#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016346 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
16347 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016348 /*Consider WFD IE, only for P2P Client */
16349 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
16350 {
16351 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016352 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016353 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016354
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016355 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016356 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016357 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16358 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016359 VOS_ASSERT(0);
16360 return -ENOMEM;
16361 }
16362 // WFD IE is saved to Additional IE ; it should be accumulated to handle
16363 // WPS IE + P2P IE + WFD IE
16364 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16365 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016366
Jeff Johnson295189b2012-06-20 16:38:30 -070016367 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16368 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16369 }
16370#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016371 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016372 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016373 HS20_OUI_TYPE_SIZE)) )
16374 {
16375 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016376 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016377 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016378
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016379 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016380 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016381 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16382 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016383 VOS_ASSERT(0);
16384 return -ENOMEM;
16385 }
16386 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16387 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016388
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016389 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16390 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16391 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016392 /* Appending OSEN Information Element in Assiciation Request */
16393 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
16394 OSEN_OUI_TYPE_SIZE)) )
16395 {
16396 v_U16_t curAddIELen = pWextState->assocAddIE.length;
16397 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
16398 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016399
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016400 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016401 {
16402 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16403 "Need bigger buffer space");
16404 VOS_ASSERT(0);
16405 return -ENOMEM;
16406 }
16407 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16408 pWextState->assocAddIE.length += eLen + 2;
16409
16410 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
16411 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16412 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16413 }
16414
Abhishek Singh4322e622015-06-10 15:42:54 +053016415 /* Update only for WPA IE */
16416 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
16417 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016418
16419 /* populating as ADDIE in beacon frames */
16420 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016421 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016422 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
16423 {
16424 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16425 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
16426 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16427 {
16428 hddLog(LOGE,
16429 "Coldn't pass "
16430 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
16431 }
16432 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
16433 else
16434 hddLog(LOGE,
16435 "Could not pass on "
16436 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
16437
16438 /* IBSS mode doesn't contain params->proberesp_ies still
16439 beaconIE's need to be populated in probe response frames */
16440 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
16441 {
16442 u16 rem_probe_resp_ie_len = eLen + 2;
16443 u8 probe_rsp_ie_len[3] = {0};
16444 u8 counter = 0;
16445
16446 /* Check Probe Resp Length if it is greater then 255 then
16447 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
16448 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
16449 not able Store More then 255 bytes into One Variable */
16450
16451 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
16452 {
16453 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
16454 {
16455 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
16456 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
16457 }
16458 else
16459 {
16460 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
16461 rem_probe_resp_ie_len = 0;
16462 }
16463 }
16464
16465 rem_probe_resp_ie_len = 0;
16466
16467 if (probe_rsp_ie_len[0] > 0)
16468 {
16469 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16470 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
16471 (tANI_U8*)(genie - 2),
16472 probe_rsp_ie_len[0], NULL,
16473 eANI_BOOLEAN_FALSE)
16474 == eHAL_STATUS_FAILURE)
16475 {
16476 hddLog(LOGE,
16477 "Could not pass"
16478 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
16479 }
16480 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
16481 }
16482
16483 if (probe_rsp_ie_len[1] > 0)
16484 {
16485 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16486 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
16487 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16488 probe_rsp_ie_len[1], NULL,
16489 eANI_BOOLEAN_FALSE)
16490 == eHAL_STATUS_FAILURE)
16491 {
16492 hddLog(LOGE,
16493 "Could not pass"
16494 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
16495 }
16496 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
16497 }
16498
16499 if (probe_rsp_ie_len[2] > 0)
16500 {
16501 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16502 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
16503 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16504 probe_rsp_ie_len[2], NULL,
16505 eANI_BOOLEAN_FALSE)
16506 == eHAL_STATUS_FAILURE)
16507 {
16508 hddLog(LOGE,
16509 "Could not pass"
16510 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
16511 }
16512 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
16513 }
16514
16515 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16516 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
16517 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16518 {
16519 hddLog(LOGE,
16520 "Could not pass"
16521 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
16522 }
16523 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016524 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070016525 break;
16526 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053016527 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16528 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
16529 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
16530 VOS_ASSERT(0);
16531 return -EINVAL;
16532 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016533 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
16534 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16535 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
16536 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
16537 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16538 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016539
Abhishek Singhb16f3562016-01-20 11:08:32 +053016540 /* Appending extended capabilities with Interworking or
16541 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016542 *
16543 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016544 * interworkingService or bsstransition bit is set to 1.
16545 * Driver is only interested in interworkingService and
16546 * bsstransition capability from supplicant.
16547 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016548 * required from supplicat, it needs to be handled while
16549 * sending Assoc Req in LIM.
16550 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016551 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016552 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016553 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016554 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016555 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016556
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016557 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016558 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016559 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16560 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016561 VOS_ASSERT(0);
16562 return -ENOMEM;
16563 }
16564 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16565 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016566
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016567 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16568 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16569 break;
16570 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016571#ifdef FEATURE_WLAN_WAPI
16572 case WLAN_EID_WAPI:
16573 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016574 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016575 pAdapter->wapi_info.nWapiMode);
16576 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016577 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016578 akmsuiteCount = WPA_GET_LE16(tmp);
16579 tmp = tmp + 1;
16580 akmlist = (int *)(tmp);
16581 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16582 {
16583 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16584 }
16585 else
16586 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016587 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016588 VOS_ASSERT(0);
16589 return -EINVAL;
16590 }
16591
16592 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16593 {
16594 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016595 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016596 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016597 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016598 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016599 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016600 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016601 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016602 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
16603 }
16604 break;
16605#endif
16606 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016607 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016608 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016609 /* when Unknown IE is received we should break and continue
16610 * to the next IE in the buffer instead we were returning
16611 * so changing this to break */
16612 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016613 }
16614 genie += eLen;
16615 remLen -= eLen;
16616 }
16617 EXIT();
16618 return 0;
16619}
16620
16621/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016622 * FUNCTION: hdd_isWPAIEPresent
16623 * Parse the received IE to find the WPA IE
16624 *
16625 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016626static bool hdd_isWPAIEPresent(
16627#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16628 const u8 *ie,
16629#else
16630 u8 *ie,
16631#endif
16632 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016633{
16634 v_U8_t eLen = 0;
16635 v_U16_t remLen = ie_len;
16636 v_U8_t elementId = 0;
16637
16638 while (remLen >= 2)
16639 {
16640 elementId = *ie++;
16641 eLen = *ie++;
16642 remLen -= 2;
16643 if (eLen > remLen)
16644 {
16645 hddLog(VOS_TRACE_LEVEL_ERROR,
16646 "%s: IE length is wrong %d", __func__, eLen);
16647 return FALSE;
16648 }
16649 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16650 {
16651 /* OUI - 0x00 0X50 0XF2
16652 WPA Information Element - 0x01
16653 WPA version - 0x01*/
16654 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16655 return TRUE;
16656 }
16657 ie += eLen;
16658 remLen -= eLen;
16659 }
16660 return FALSE;
16661}
16662
16663/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016664 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016665 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016666 * parameters during connect operation.
16667 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016668int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016669 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016670 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016671{
16672 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016673 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016674 ENTER();
16675
16676 /*set wpa version*/
16677 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
16678
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016679 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016680 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053016681 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016682 {
16683 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16684 }
16685 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
16686 {
16687 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16688 }
16689 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016690
16691 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016692 pWextState->wpaVersion);
16693
16694 /*set authentication type*/
16695 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
16696
16697 if (0 > status)
16698 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016699 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016700 "%s: failed to set authentication type ", __func__);
16701 return status;
16702 }
16703
16704 /*set key mgmt type*/
16705 if (req->crypto.n_akm_suites)
16706 {
16707 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
16708 if (0 > status)
16709 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016710 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070016711 __func__);
16712 return status;
16713 }
16714 }
16715
16716 /*set pairwise cipher type*/
16717 if (req->crypto.n_ciphers_pairwise)
16718 {
16719 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
16720 req->crypto.ciphers_pairwise[0], true);
16721 if (0 > status)
16722 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016723 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016724 "%s: failed to set unicast cipher type", __func__);
16725 return status;
16726 }
16727 }
16728 else
16729 {
16730 /*Reset previous cipher suite to none*/
16731 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
16732 if (0 > status)
16733 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016734 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016735 "%s: failed to set unicast cipher type", __func__);
16736 return status;
16737 }
16738 }
16739
16740 /*set group cipher type*/
16741 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
16742 false);
16743
16744 if (0 > status)
16745 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016746 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070016747 __func__);
16748 return status;
16749 }
16750
Chet Lanctot186b5732013-03-18 10:26:30 -070016751#ifdef WLAN_FEATURE_11W
16752 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
16753#endif
16754
Jeff Johnson295189b2012-06-20 16:38:30 -070016755 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
16756 if (req->ie_len)
16757 {
16758 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
16759 if ( 0 > status)
16760 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016761 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016762 __func__);
16763 return status;
16764 }
16765 }
16766
16767 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016768 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016769 {
16770 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
16771 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
16772 )
16773 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016774 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070016775 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
16776 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016777 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016778 __func__);
16779 return -EOPNOTSUPP;
16780 }
16781 else
16782 {
16783 u8 key_len = req->key_len;
16784 u8 key_idx = req->key_idx;
16785
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016786 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016787 && (CSR_MAX_NUM_KEY > key_idx)
16788 )
16789 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016790 hddLog(VOS_TRACE_LEVEL_INFO,
16791 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016792 __func__, key_idx, key_len);
16793 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016794 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070016795 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016796 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016797 (u8)key_len;
16798 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
16799 }
16800 }
16801 }
16802 }
16803
16804 return status;
16805}
16806
16807/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016808 * FUNCTION: wlan_hdd_try_disconnect
16809 * This function is used to disconnect from previous
16810 * connection
16811 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053016812int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016813{
16814 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016815 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016816 hdd_station_ctx_t *pHddStaCtx;
16817 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016818 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016819
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016820 ret = wlan_hdd_validate_context(pHddCtx);
16821 if (0 != ret)
16822 {
16823 return ret;
16824 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016825 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16826
16827 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
16828
16829 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
16830 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053016831 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016832 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
16833 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053016834 /* Indicate disconnect to SME so that in-progress connection or preauth
16835 * can be aborted
16836 */
16837 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
16838 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016839 spin_lock_bh(&pAdapter->lock_for_active_session);
16840 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16841 {
16842 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16843 }
16844 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053016845 hdd_connSetConnectionState(pHddStaCtx,
16846 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016847 /* Issue disconnect to CSR */
16848 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016849 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016850 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016851 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16852 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
16853 hddLog(LOG1,
16854 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
16855 } else if ( 0 != status ) {
16856 hddLog(LOGE,
16857 FL("csrRoamDisconnect failure, returned %d"),
16858 (int)status );
16859 result = -EINVAL;
16860 goto disconnected;
16861 }
16862 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016863 &pAdapter->disconnect_comp_var,
16864 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016865 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
16866 hddLog(LOGE,
16867 "%s: Failed to disconnect, timed out", __func__);
16868 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016869 }
16870 }
16871 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
16872 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016873 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016874 &pAdapter->disconnect_comp_var,
16875 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016876 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016877 {
16878 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016879 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016880 }
16881 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016882disconnected:
16883 hddLog(LOG1,
16884 FL("Set HDD connState to eConnectionState_NotConnected"));
16885 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16886 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016887}
16888
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016889/**
16890 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16891 * @adapter: Pointer to the HDD adapter
16892 * @req: Pointer to the structure cfg_connect_params receieved from user space
16893 *
16894 * This function will start reassociation if bssid hint, channel hint and
16895 * previous bssid parameters are present in the connect request
16896 *
16897 * Return: success if reassociation is happening
16898 * Error code if reassociation is not permitted or not happening
16899 */
16900#ifdef CFG80211_CONNECT_PREV_BSSID
16901static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16902 struct cfg80211_connect_params *req)
16903{
16904 int status = -EPERM;
16905 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
16906 hddLog(VOS_TRACE_LEVEL_INFO,
16907 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
16908 req->channel_hint->hw_value,
16909 MAC_ADDR_ARRAY(req->bssid_hint));
16910 status = hdd_reassoc(adapter, req->bssid_hint,
16911 req->channel_hint->hw_value,
16912 CONNECT_CMD_USERSPACE);
16913 }
16914 return status;
16915}
16916#else
16917static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16918 struct cfg80211_connect_params *req)
16919{
16920 return -EPERM;
16921}
16922#endif
16923
Abhishek Singhe3beee22017-07-31 15:35:40 +053016924/**
16925 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
16926 * connect in HT20 mode
16927 * @hdd_ctx: hdd context
16928 * @adapter: Pointer to the HDD adapter
16929 * @req: Pointer to the structure cfg_connect_params receieved from user space
16930 *
16931 * This function will check if supplicant has indicated to to connect in HT20
16932 * mode. this is currently applicable only for 2.4Ghz mode only.
16933 * if feature is enabled and supplicant indicate HT20 set
16934 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
16935 *
16936 * Return: void
16937 */
16938#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
16939static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16940 hdd_adapter_t *adapter,
16941 struct cfg80211_connect_params *req)
16942{
16943 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16944 tCsrRoamProfile *roam_profile;
16945
16946 roam_profile = &wext_state->roamProfile;
16947 roam_profile->force_24ghz_in_ht20 = false;
16948 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
16949 !(req->ht_capa.cap_info &
16950 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
16951 roam_profile->force_24ghz_in_ht20 = true;
16952
16953 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
16954 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
16955}
16956#else
16957static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16958 hdd_adapter_t *adapter,
16959 struct cfg80211_connect_params *req)
16960{
16961 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16962 tCsrRoamProfile *roam_profile;
16963
16964 roam_profile = &wext_state->roamProfile;
16965 roam_profile->force_24ghz_in_ht20 = false;
16966}
16967#endif
16968
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016969/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053016970 * FUNCTION: __wlan_hdd_cfg80211_connect
16971 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070016972 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016973static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016974 struct net_device *ndev,
16975 struct cfg80211_connect_params *req
16976 )
16977{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016978 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016979 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053016980#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
16981 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016982 const u8 *bssid_hint = req->bssid_hint;
16983#else
16984 const u8 *bssid_hint = NULL;
16985#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016986 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016987 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053016988 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016989
16990 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016991
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016992 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16993 TRACE_CODE_HDD_CFG80211_CONNECT,
16994 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016995 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016996 "%s: device_mode = %s (%d)", __func__,
16997 hdd_device_modetoString(pAdapter->device_mode),
16998 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016999
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017000 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017001 if (!pHddCtx)
17002 {
17003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17004 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053017005 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017006 }
17007
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017008 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017009 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017010 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017011 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017012 }
17013
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053017014 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
17015 return -EINVAL;
17016
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017017 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
17018 if (0 == status)
17019 return status;
17020
Agarwal Ashish51325b52014-06-16 16:50:49 +053017021
Jeff Johnson295189b2012-06-20 16:38:30 -070017022#ifdef WLAN_BTAMP_FEATURE
17023 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017024 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070017025 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017026 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017027 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080017028 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070017029 }
17030#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017031
17032 //If Device Mode is Station Concurrent Sessions Exit BMps
17033 //P2P Mode will be taken care in Open/close adapter
17034 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053017035 (vos_concurrent_open_sessions_running())) {
17036 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
17037 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017038 }
17039
17040 /*Try disconnecting if already in connected state*/
17041 status = wlan_hdd_try_disconnect(pAdapter);
17042 if ( 0 > status)
17043 {
17044 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17045 " connection"));
17046 return -EALREADY;
17047 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053017048 /* Check for max concurrent connections after doing disconnect if any*/
17049 if (vos_max_concurrent_connections_reached()) {
17050 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17051 return -ECONNREFUSED;
17052 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017053
Jeff Johnson295189b2012-06-20 16:38:30 -070017054 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017055 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070017056
17057 if ( 0 > status)
17058 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017059 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070017060 __func__);
17061 return status;
17062 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053017063
17064 if (pHddCtx->spoofMacAddr.isEnabled)
17065 {
17066 hddLog(VOS_TRACE_LEVEL_INFO,
17067 "%s: MAC Spoofing enabled ", __func__);
17068 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
17069 * to fill TxBds for probe request during SSID scan which may happen
17070 * as part of connect command
17071 */
17072 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
17073 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
17074 if (status != VOS_STATUS_SUCCESS)
17075 return -ECONNREFUSED;
17076 }
17077
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017078 if (req->channel)
17079 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070017080 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017081 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053017082
17083 /* Abort if any scan is going on */
17084 status = wlan_hdd_scan_abort(pAdapter);
17085 if (0 != status)
17086 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
17087
Abhishek Singhe3beee22017-07-31 15:35:40 +053017088 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
17089
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017090 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
17091 req->ssid_len, req->bssid,
17092 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017093
Sushant Kaushikd7083982015-03-18 14:33:24 +053017094 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017095 {
17096 //ReEnable BMPS if disabled
17097 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
17098 (NULL != pHddCtx))
17099 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053017100 if (pHddCtx->hdd_wlan_suspended)
17101 {
17102 hdd_set_pwrparams(pHddCtx);
17103 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017104 //ReEnable Bmps and Imps back
17105 hdd_enable_bmps_imps(pHddCtx);
17106 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053017107 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070017108 return status;
17109 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017110 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017111 EXIT();
17112 return status;
17113}
17114
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017115static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
17116 struct net_device *ndev,
17117 struct cfg80211_connect_params *req)
17118{
17119 int ret;
17120 vos_ssr_protect(__func__);
17121 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
17122 vos_ssr_unprotect(__func__);
17123
17124 return ret;
17125}
Jeff Johnson295189b2012-06-20 16:38:30 -070017126
17127/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017128 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070017129 * This function is used to issue a disconnect request to SME
17130 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017131static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017132 struct net_device *dev,
17133 u16 reason
17134 )
17135{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017136 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017137 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017138 tCsrRoamProfile *pRoamProfile;
17139 hdd_station_ctx_t *pHddStaCtx;
17140 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017141#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017142 tANI_U8 staIdx;
17143#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017144
Jeff Johnson295189b2012-06-20 16:38:30 -070017145 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017146
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017147 if (!pAdapter) {
17148 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17149 return -EINVAL;
17150 }
17151
17152 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17153 if (!pHddStaCtx) {
17154 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
17155 return -EINVAL;
17156 }
17157
17158 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17159 status = wlan_hdd_validate_context(pHddCtx);
17160 if (0 != status)
17161 {
17162 return status;
17163 }
17164
17165 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
17166
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017167 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17168 TRACE_CODE_HDD_CFG80211_DISCONNECT,
17169 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017170 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
17171 __func__, hdd_device_modetoString(pAdapter->device_mode),
17172 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017173
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017174 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
17175 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070017176
Jeff Johnson295189b2012-06-20 16:38:30 -070017177 if (NULL != pRoamProfile)
17178 {
17179 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017180 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
17181 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070017182 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017183 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070017184 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017185 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070017186 switch(reason)
17187 {
17188 case WLAN_REASON_MIC_FAILURE:
17189 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
17190 break;
17191
17192 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
17193 case WLAN_REASON_DISASSOC_AP_BUSY:
17194 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
17195 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
17196 break;
17197
17198 case WLAN_REASON_PREV_AUTH_NOT_VALID:
17199 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053017200 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070017201 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
17202 break;
17203
Jeff Johnson295189b2012-06-20 16:38:30 -070017204 default:
17205 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
17206 break;
17207 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017208 pScanInfo = &pHddCtx->scan_info;
17209 if (pScanInfo->mScanPending)
17210 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017211 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017212 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053017213 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017214 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017215 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053017216 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017217#ifdef FEATURE_WLAN_TDLS
17218 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017219 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017220 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017221 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
17222 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017223 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017224 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017225 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017227 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017228 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017229 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017230 status = sme_DeleteTdlsPeerSta(
17231 WLAN_HDD_GET_HAL_CTX(pAdapter),
17232 pAdapter->sessionId,
17233 mac);
17234 if (status != eHAL_STATUS_SUCCESS) {
17235 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
17236 return -EPERM;
17237 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017238 }
17239 }
17240#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053017241
17242 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
17243 reasonCode,
17244 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017245 status = wlan_hdd_disconnect(pAdapter, reasonCode);
17246 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070017247 {
17248 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017249 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017250 __func__, (int)status );
17251 return -EINVAL;
17252 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017253 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017254 else
17255 {
17256 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
17257 "called while in %d state", __func__,
17258 pHddStaCtx->conn_info.connState);
17259 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017260 }
17261 else
17262 {
17263 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
17264 }
17265
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017266 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017267 return status;
17268}
17269
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017270static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
17271 struct net_device *dev,
17272 u16 reason
17273 )
17274{
17275 int ret;
17276 vos_ssr_protect(__func__);
17277 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
17278 vos_ssr_unprotect(__func__);
17279
17280 return ret;
17281}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017282
Jeff Johnson295189b2012-06-20 16:38:30 -070017283/*
17284 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017285 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070017286 * settings in IBSS mode.
17287 */
17288static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017289 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070017290 struct cfg80211_ibss_params *params
17291 )
17292{
17293 int status = 0;
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017294 tANI_U32 ret;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017295 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070017296 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
17297 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017298
Jeff Johnson295189b2012-06-20 16:38:30 -070017299 ENTER();
17300
17301 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070017302 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070017303
17304 if (params->ie_len && ( NULL != params->ie) )
17305 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017306 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17307 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017308 {
17309 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
17310 encryptionType = eCSR_ENCRYPT_TYPE_AES;
17311 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017312 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017313 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017314 tDot11fIEWPA dot11WPAIE;
17315 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017316 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017317
Wilson Yang00256342013-10-10 23:13:38 -070017318 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017319 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17320 params->ie_len, DOT11F_EID_WPA);
17321 if ( NULL != ie )
17322 {
17323 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
17324 // Unpack the WPA IE
17325 //Skip past the EID byte and length byte - and four byte WiFi OUI
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017326 ret = dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017327 &ie[2+4],
17328 ie[1] - 4,
17329 &dot11WPAIE);
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017330 if (DOT11F_FAILED(ret))
17331 {
17332 hddLog(LOGE,
17333 FL("unpack failed status:(0x%08x)"),
17334 ret);
17335 return -EINVAL;
17336 }
17337
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017338 /*Extract the multicast cipher, the encType for unicast
17339 cipher for wpa-none is none*/
17340 encryptionType =
17341 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
17342 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017343 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017344
Jeff Johnson295189b2012-06-20 16:38:30 -070017345 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
17346
17347 if (0 > status)
17348 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017349 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070017350 __func__);
17351 return status;
17352 }
17353 }
17354
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017355 pWextState->roamProfile.AuthType.authType[0] =
17356 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070017357 eCSR_AUTH_TYPE_OPEN_SYSTEM;
Jeff Johnson295189b2012-06-20 16:38:30 -070017358 if (params->privacy)
17359 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017360 /* Security enabled IBSS, At this time there is no information available
17361 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070017362 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017363 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070017364 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017365 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070017366 *enable privacy bit in beacons */
17367
17368 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
17369 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017370 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17371 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070017372 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
17373 pWextState->roamProfile.EncryptionType.numEntries = 1;
17374 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070017375 return status;
17376}
17377
17378/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017379 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017380 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017381 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017382static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017383 struct net_device *dev,
17384 struct cfg80211_ibss_params *params
17385 )
17386{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017387 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017388 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17389 tCsrRoamProfile *pRoamProfile;
17390 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017391 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17392 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017393 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070017394
17395 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017396
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017397 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17398 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
17399 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017400 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017401 "%s: device_mode = %s (%d)", __func__,
17402 hdd_device_modetoString(pAdapter->device_mode),
17403 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017404
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017405 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017406 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017407 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017408 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017409 }
17410
17411 if (NULL == pWextState)
17412 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017413 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017414 __func__);
17415 return -EIO;
17416 }
17417
Agarwal Ashish51325b52014-06-16 16:50:49 +053017418 if (vos_max_concurrent_connections_reached()) {
17419 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17420 return -ECONNREFUSED;
17421 }
17422
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017423 /*Try disconnecting if already in connected state*/
17424 status = wlan_hdd_try_disconnect(pAdapter);
17425 if ( 0 > status)
17426 {
17427 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17428 " IBSS connection"));
17429 return -EALREADY;
17430 }
17431
Jeff Johnson295189b2012-06-20 16:38:30 -070017432 pRoamProfile = &pWextState->roamProfile;
17433
17434 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
17435 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017436 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017437 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017438 return -EINVAL;
17439 }
17440
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017441 /* BSSID is provided by upper layers hence no need to AUTO generate */
17442 if (NULL != params->bssid) {
17443 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17444 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
17445 hddLog (VOS_TRACE_LEVEL_ERROR,
17446 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17447 return -EIO;
17448 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017449 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017450 }
krunal sonie9002db2013-11-25 14:24:17 -080017451 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
17452 {
17453 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17454 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
17455 {
17456 hddLog (VOS_TRACE_LEVEL_ERROR,
17457 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17458 return -EIO;
17459 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017460
17461 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080017462 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017463 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080017464 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017465
Jeff Johnson295189b2012-06-20 16:38:30 -070017466 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070017467 if (NULL !=
17468#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17469 params->chandef.chan)
17470#else
17471 params->channel)
17472#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017473 {
17474 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017475 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17476 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
17477 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17478 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017479
17480 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017481 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070017482 ieee80211_frequency_to_channel(
17483#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17484 params->chandef.chan->center_freq);
17485#else
17486 params->channel->center_freq);
17487#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017488
17489 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17490 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070017491 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017492 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
17493 __func__);
17494 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070017495 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017496
17497 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017498 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017499 if (channelNum == validChan[indx])
17500 {
17501 break;
17502 }
17503 }
17504 if (indx >= numChans)
17505 {
17506 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017507 __func__, channelNum);
17508 return -EINVAL;
17509 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017510 /* Set the Operational Channel */
17511 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
17512 channelNum);
17513 pRoamProfile->ChannelInfo.numOfChannels = 1;
17514 pHddStaCtx->conn_info.operationChannel = channelNum;
17515 pRoamProfile->ChannelInfo.ChannelList =
17516 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070017517 }
17518
17519 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017520 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070017521 if (status < 0)
17522 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017523 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070017524 __func__);
17525 return status;
17526 }
17527
17528 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017529 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053017530 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017531 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017532
17533 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017534 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017535
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017536 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017537 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017538}
17539
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017540static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17541 struct net_device *dev,
17542 struct cfg80211_ibss_params *params
17543 )
17544{
17545 int ret = 0;
17546
17547 vos_ssr_protect(__func__);
17548 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17549 vos_ssr_unprotect(__func__);
17550
17551 return ret;
17552}
17553
Jeff Johnson295189b2012-06-20 16:38:30 -070017554/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017555 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017556 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017557 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017558static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017559 struct net_device *dev
17560 )
17561{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017562 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017563 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17564 tCsrRoamProfile *pRoamProfile;
17565 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017566 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017567 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017568#ifdef WLAN_FEATURE_RMC
17569 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17570#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017571
17572 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017573
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017574 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17575 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17576 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017577 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017578 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017579 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017580 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017581 }
17582
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017583 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17584 hdd_device_modetoString(pAdapter->device_mode),
17585 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017586 if (NULL == pWextState)
17587 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017588 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017589 __func__);
17590 return -EIO;
17591 }
17592
17593 pRoamProfile = &pWextState->roamProfile;
17594
17595 /* Issue disconnect only if interface type is set to IBSS */
17596 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17597 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017598 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017599 __func__);
17600 return -EINVAL;
17601 }
17602
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017603#ifdef WLAN_FEATURE_RMC
17604 /* Clearing add IE of beacon */
17605 if (ccmCfgSetStr(pHddCtx->hHal,
17606 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17607 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17608 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17609 {
17610 hddLog (VOS_TRACE_LEVEL_ERROR,
17611 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17612 return -EINVAL;
17613 }
17614 if (ccmCfgSetInt(pHddCtx->hHal,
17615 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17616 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17617 {
17618 hddLog (VOS_TRACE_LEVEL_ERROR,
17619 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17620 __func__);
17621 return -EINVAL;
17622 }
17623
17624 // Reset WNI_CFG_PROBE_RSP Flags
17625 wlan_hdd_reset_prob_rspies(pAdapter);
17626
17627 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17628 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17629 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17630 {
17631 hddLog (VOS_TRACE_LEVEL_ERROR,
17632 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17633 __func__);
17634 return -EINVAL;
17635 }
17636#endif
17637
Jeff Johnson295189b2012-06-20 16:38:30 -070017638 /* Issue Disconnect request */
17639 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017640 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17641 pAdapter->sessionId,
17642 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17643 if (!HAL_STATUS_SUCCESS(hal_status)) {
17644 hddLog(LOGE,
17645 FL("sme_RoamDisconnect failed hal_status(%d)"),
17646 hal_status);
17647 return -EAGAIN;
17648 }
17649 status = wait_for_completion_timeout(
17650 &pAdapter->disconnect_comp_var,
17651 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17652 if (!status) {
17653 hddLog(LOGE,
17654 FL("wait on disconnect_comp_var failed"));
17655 return -ETIMEDOUT;
17656 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017657
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017658 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017659 return 0;
17660}
17661
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017662static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17663 struct net_device *dev
17664 )
17665{
17666 int ret = 0;
17667
17668 vos_ssr_protect(__func__);
17669 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17670 vos_ssr_unprotect(__func__);
17671
17672 return ret;
17673}
17674
Jeff Johnson295189b2012-06-20 16:38:30 -070017675/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017676 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017677 * This function is used to set the phy parameters
17678 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17679 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017680static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017681 u32 changed)
17682{
17683 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17684 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017685 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017686
17687 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017688
17689 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017690 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17691 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017692
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017693 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017694 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017695 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017696 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017697 }
17698
Jeff Johnson295189b2012-06-20 16:38:30 -070017699 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17700 {
17701 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17702 WNI_CFG_RTS_THRESHOLD_STAMAX :
17703 wiphy->rts_threshold;
17704
17705 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017706 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017707 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017708 hddLog(VOS_TRACE_LEVEL_ERROR,
17709 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017710 __func__, rts_threshold);
17711 return -EINVAL;
17712 }
17713
17714 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17715 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017716 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017717 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017718 hddLog(VOS_TRACE_LEVEL_ERROR,
17719 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017720 __func__, rts_threshold);
17721 return -EIO;
17722 }
17723
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017724 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017725 rts_threshold);
17726 }
17727
17728 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17729 {
17730 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17731 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17732 wiphy->frag_threshold;
17733
17734 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017735 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017736 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017737 hddLog(VOS_TRACE_LEVEL_ERROR,
17738 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017739 frag_threshold);
17740 return -EINVAL;
17741 }
17742
17743 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
17744 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017745 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017746 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017747 hddLog(VOS_TRACE_LEVEL_ERROR,
17748 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017749 __func__, frag_threshold);
17750 return -EIO;
17751 }
17752
17753 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
17754 frag_threshold);
17755 }
17756
17757 if ((changed & WIPHY_PARAM_RETRY_SHORT)
17758 || (changed & WIPHY_PARAM_RETRY_LONG))
17759 {
17760 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
17761 wiphy->retry_short :
17762 wiphy->retry_long;
17763
17764 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17765 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17766 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017767 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017768 __func__, retry_value);
17769 return -EINVAL;
17770 }
17771
17772 if (changed & WIPHY_PARAM_RETRY_SHORT)
17773 {
17774 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17775 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017776 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017777 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017778 hddLog(VOS_TRACE_LEVEL_ERROR,
17779 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017780 __func__, retry_value);
17781 return -EIO;
17782 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017783 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017784 __func__, retry_value);
17785 }
17786 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17787 {
17788 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17789 retry_value, 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 short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017794 __func__, retry_value);
17795 return -EIO;
17796 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017797 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017798 __func__, retry_value);
17799 }
17800 }
17801
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017802 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017803 return 0;
17804}
17805
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017806static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17807 u32 changed)
17808{
17809 int ret;
17810
17811 vos_ssr_protect(__func__);
17812 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17813 vos_ssr_unprotect(__func__);
17814
17815 return ret;
17816}
17817
Jeff Johnson295189b2012-06-20 16:38:30 -070017818/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017819 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017820 * This function is used to set the txpower
17821 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017822static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017823#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17824 struct wireless_dev *wdev,
17825#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017826#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017827 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017828#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017829 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017830#endif
17831 int dbm)
17832{
17833 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017834 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017835 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17836 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017837 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017838
17839 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017840
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017841 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17842 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17843 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017844 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017845 if (0 != status)
17846 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017847 return status;
17848 }
17849
17850 hHal = pHddCtx->hHal;
17851
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017852 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17853 dbm, ccmCfgSetCallback,
17854 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017855 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017856 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017857 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17858 return -EIO;
17859 }
17860
17861 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17862 dbm);
17863
17864 switch(type)
17865 {
17866 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17867 /* Fall through */
17868 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17869 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17870 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017871 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17872 __func__);
17873 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017874 }
17875 break;
17876 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017877 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017878 __func__);
17879 return -EOPNOTSUPP;
17880 break;
17881 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017882 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17883 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017884 return -EIO;
17885 }
17886
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017887 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017888 return 0;
17889}
17890
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017891static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17892#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17893 struct wireless_dev *wdev,
17894#endif
17895#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17896 enum tx_power_setting type,
17897#else
17898 enum nl80211_tx_power_setting type,
17899#endif
17900 int dbm)
17901{
17902 int ret;
17903 vos_ssr_protect(__func__);
17904 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17905#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17906 wdev,
17907#endif
17908#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17909 type,
17910#else
17911 type,
17912#endif
17913 dbm);
17914 vos_ssr_unprotect(__func__);
17915
17916 return ret;
17917}
17918
Jeff Johnson295189b2012-06-20 16:38:30 -070017919/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017920 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017921 * This function is used to read the txpower
17922 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017923static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017924#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17925 struct wireless_dev *wdev,
17926#endif
17927 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070017928{
17929
17930 hdd_adapter_t *pAdapter;
17931 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017932 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017933
Jeff Johnsone7245742012-09-05 17:12:55 -070017934 ENTER();
17935
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017936 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017937 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017938 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017939 *dbm = 0;
17940 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017941 }
17942
Jeff Johnson295189b2012-06-20 16:38:30 -070017943 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
17944 if (NULL == pAdapter)
17945 {
17946 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
17947 return -ENOENT;
17948 }
17949
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017950 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17951 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
17952 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070017953 wlan_hdd_get_classAstats(pAdapter);
17954 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
17955
Jeff Johnsone7245742012-09-05 17:12:55 -070017956 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017957 return 0;
17958}
17959
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017960static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
17961#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17962 struct wireless_dev *wdev,
17963#endif
17964 int *dbm)
17965{
17966 int ret;
17967
17968 vos_ssr_protect(__func__);
17969 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
17970#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17971 wdev,
17972#endif
17973 dbm);
17974 vos_ssr_unprotect(__func__);
17975
17976 return ret;
17977}
17978
Dustin Brown8c1d4092017-07-28 18:08:01 +053017979/*
17980 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
17981 * @stats: summary stats to use as a source
17982 * @info: kernel station_info struct to use as a destination
17983 *
17984 * Return: None
17985 */
17986static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
17987 struct station_info *info)
17988{
17989 int i;
17990
17991 info->rx_packets = stats->rx_frm_cnt;
17992 info->tx_packets = 0;
17993 info->tx_retries = 0;
17994 info->tx_failed = 0;
17995
17996 for (i = 0; i < 4; ++i) {
17997 info->tx_packets += stats->tx_frm_cnt[i];
17998 info->tx_retries += stats->multiple_retry_cnt[i];
17999 info->tx_failed += stats->fail_cnt[i];
18000 }
18001
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018002#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18003 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018004 info->filled |= STATION_INFO_TX_PACKETS |
18005 STATION_INFO_TX_RETRIES |
18006 STATION_INFO_TX_FAILED |
18007 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018008#else
18009 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
18010 BIT(NL80211_STA_INFO_TX_RETRIES) |
18011 BIT(NL80211_STA_INFO_TX_FAILED) |
18012 BIT(NL80211_STA_INFO_RX_PACKETS);
18013#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053018014}
18015
18016/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018017 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
18018 * @adapter: sap adapter pointer
18019 * @staid: station id of the client
18020 * @rssi: rssi value to fill
18021 *
18022 * Return: None
18023 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053018024void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018025wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
18026{
18027 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
18028
18029 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
18030}
18031
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018032#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18033 !defined(WITH_BACKPORTS)
18034static inline void wlan_hdd_fill_station_info_signal(struct station_info
18035 *sinfo)
18036{
18037 sinfo->filled |= STATION_INFO_SIGNAL;
18038}
18039#else
18040static inline void wlan_hdd_fill_station_info_signal(struct station_info
18041 *sinfo)
18042{
18043 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
18044}
18045#endif
18046
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018047/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053018048 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
18049 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018050 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053018051 * @info: kernel station_info struct to populate
18052 *
18053 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
18054 * support "station dump" and "station get" for SAP vdevs, even though they
18055 * aren't technically stations.
18056 *
18057 * Return: errno
18058 */
18059static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018060wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
18061#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18062 const u8* mac,
18063#else
18064 u8* mac,
18065#endif
18066 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018067{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018068 v_MACADDR_t *peerMacAddr;
18069 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018070 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018071 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018072
18073 status = wlan_hdd_get_station_stats(adapter);
18074 if (!VOS_IS_STATUS_SUCCESS(status)) {
18075 hddLog(VOS_TRACE_LEVEL_ERROR,
18076 "Failed to get SAP stats; status:%d", status);
18077 return 0;
18078 }
18079
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018080 peerMacAddr = (v_MACADDR_t *)mac;
18081 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
18082 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
18083 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
18084
18085 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
18086 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018087 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018088 }
18089
Dustin Brown8c1d4092017-07-28 18:08:01 +053018090 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
18091
18092 return 0;
18093}
18094
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018095static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018096#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18097 const u8* mac,
18098#else
18099 u8* mac,
18100#endif
18101 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070018102{
18103 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
18104 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18105 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053018106 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018107
18108 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
18109 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070018110
18111 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
18112 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
18113 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
18114 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
18115 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
18116 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
18117 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018118 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018119 tANI_U16 myRate;
18120 tANI_U16 currentRate = 0;
18121 tANI_U8 maxSpeedMCS = 0;
18122 tANI_U8 maxMCSIdx = 0;
18123 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053018124 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070018125 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018126 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018127
Leo Chang6f8870f2013-03-26 18:11:36 -070018128#ifdef WLAN_FEATURE_11AC
18129 tANI_U32 vht_mcs_map;
18130 eDataRate11ACMaxMcs vhtMaxMcs;
18131#endif /* WLAN_FEATURE_11AC */
18132
Jeff Johnsone7245742012-09-05 17:12:55 -070018133 ENTER();
18134
Dustin Brown8c1d4092017-07-28 18:08:01 +053018135 status = wlan_hdd_validate_context(pHddCtx);
18136 if (0 != status)
18137 {
18138 return status;
18139 }
18140
18141 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018142 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053018143
Jeff Johnson295189b2012-06-20 16:38:30 -070018144 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
18145 (0 == ssidlen))
18146 {
18147 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
18148 " Invalid ssidlen, %d", __func__, ssidlen);
18149 /*To keep GUI happy*/
18150 return 0;
18151 }
18152
Mukul Sharma811205f2014-07-09 21:07:30 +053018153 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
18154 {
18155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18156 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053018157 /* return a cached value */
18158 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053018159 return 0;
18160 }
18161
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053018162 wlan_hdd_get_station_stats(pAdapter);
18163 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018164
Kiet Lam3b17fc82013-09-27 05:24:08 +053018165 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018166 wlan_hdd_get_snr(pAdapter, &snr);
18167 pHddStaCtx->conn_info.signal = sinfo->signal;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018168 pHddStaCtx->cache_conn_info.signal = sinfo->signal;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018169 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018170 pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018171 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053018172
c_hpothu09f19542014-05-30 21:53:31 +053018173 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053018174 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
18175 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053018176 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053018177 {
18178 rate_flags = pAdapter->maxRateFlags;
18179 }
c_hpothu44ff4e02014-05-08 00:13:57 +053018180
Jeff Johnson295189b2012-06-20 16:38:30 -070018181 //convert to the UI units of 100kbps
18182 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
18183
18184#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070018185 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 -070018186 sinfo->signal,
18187 pCfg->reportMaxLinkSpeed,
18188 myRate,
18189 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018190 (int) pCfg->linkSpeedRssiMid,
18191 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070018192 (int) rate_flags,
18193 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070018194#endif //LINKSPEED_DEBUG_ENABLED
18195
18196 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
18197 {
18198 // we do not want to necessarily report the current speed
18199 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
18200 {
18201 // report the max possible speed
18202 rssidx = 0;
18203 }
18204 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
18205 {
18206 // report the max possible speed with RSSI scaling
18207 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
18208 {
18209 // report the max possible speed
18210 rssidx = 0;
18211 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018212 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070018213 {
18214 // report middle speed
18215 rssidx = 1;
18216 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018217 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
18218 {
18219 // report middle speed
18220 rssidx = 2;
18221 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018222 else
18223 {
18224 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018225 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070018226 }
18227 }
18228 else
18229 {
18230 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
18231 hddLog(VOS_TRACE_LEVEL_ERROR,
18232 "%s: Invalid value for reportMaxLinkSpeed: %u",
18233 __func__, pCfg->reportMaxLinkSpeed);
18234 rssidx = 0;
18235 }
18236
18237 maxRate = 0;
18238
18239 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018240 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
18241 OperationalRates, &ORLeng))
18242 {
18243 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18244 /*To keep GUI happy*/
18245 return 0;
18246 }
18247
Jeff Johnson295189b2012-06-20 16:38:30 -070018248 for (i = 0; i < ORLeng; i++)
18249 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018250 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018251 {
18252 /* Validate Rate Set */
18253 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
18254 {
18255 currentRate = supported_data_rate[j].supported_rate[rssidx];
18256 break;
18257 }
18258 }
18259 /* Update MAX rate */
18260 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18261 }
18262
18263 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018264 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
18265 ExtendedRates, &ERLeng))
18266 {
18267 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18268 /*To keep GUI happy*/
18269 return 0;
18270 }
18271
Jeff Johnson295189b2012-06-20 16:38:30 -070018272 for (i = 0; i < ERLeng; i++)
18273 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018274 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018275 {
18276 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
18277 {
18278 currentRate = supported_data_rate[j].supported_rate[rssidx];
18279 break;
18280 }
18281 }
18282 /* Update MAX rate */
18283 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18284 }
c_hpothu79aab322014-07-14 21:11:01 +053018285
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018286 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053018287 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018288 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053018289 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070018290 {
c_hpothu79aab322014-07-14 21:11:01 +053018291 if (rate_flags & eHAL_TX_RATE_VHT80)
18292 mode = 2;
18293 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
18294 mode = 1;
18295 else
18296 mode = 0;
18297
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018298 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
18299 MCSRates, &MCSLeng))
18300 {
18301 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18302 /*To keep GUI happy*/
18303 return 0;
18304 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018305 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070018306#ifdef WLAN_FEATURE_11AC
18307 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018308 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070018309 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018310 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018311 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070018312 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070018313 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018314 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018315 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018316 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070018317 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018318 maxMCSIdx = 7;
18319 }
18320 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
18321 {
18322 maxMCSIdx = 8;
18323 }
18324 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
18325 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018326 //VHT20 is supporting 0~8
18327 if (rate_flags & eHAL_TX_RATE_VHT20)
18328 maxMCSIdx = 8;
18329 else
18330 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070018331 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018332
c_hpothu79aab322014-07-14 21:11:01 +053018333 if (0 != rssidx)/*check for scaled */
18334 {
18335 //get middle rate MCS index if rssi=1/2
18336 for (i=0; i <= maxMCSIdx; i++)
18337 {
18338 if (sinfo->signal <= rssiMcsTbl[mode][i])
18339 {
18340 maxMCSIdx = i;
18341 break;
18342 }
18343 }
18344 }
18345
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018346 if (rate_flags & eHAL_TX_RATE_VHT80)
18347 {
18348 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
18349 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
18350 }
18351 else if (rate_flags & eHAL_TX_RATE_VHT40)
18352 {
18353 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
18354 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
18355 }
18356 else if (rate_flags & eHAL_TX_RATE_VHT20)
18357 {
18358 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
18359 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
18360 }
18361
Leo Chang6f8870f2013-03-26 18:11:36 -070018362 maxSpeedMCS = 1;
18363 if (currentRate > maxRate)
18364 {
18365 maxRate = currentRate;
18366 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018367
Leo Chang6f8870f2013-03-26 18:11:36 -070018368 }
18369 else
18370#endif /* WLAN_FEATURE_11AC */
18371 {
18372 if (rate_flags & eHAL_TX_RATE_HT40)
18373 {
18374 rateFlag |= 1;
18375 }
18376 if (rate_flags & eHAL_TX_RATE_SGI)
18377 {
18378 rateFlag |= 2;
18379 }
18380
Girish Gowli01abcee2014-07-31 20:18:55 +053018381 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053018382 if (rssidx == 1 || rssidx == 2)
18383 {
18384 //get middle rate MCS index if rssi=1/2
18385 for (i=0; i <= 7; i++)
18386 {
18387 if (sinfo->signal <= rssiMcsTbl[mode][i])
18388 {
18389 temp = i+1;
18390 break;
18391 }
18392 }
18393 }
c_hpothu79aab322014-07-14 21:11:01 +053018394
18395 for (i = 0; i < MCSLeng; i++)
18396 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018397 for (j = 0; j < temp; j++)
18398 {
18399 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
18400 {
18401 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018402 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018403 break;
18404 }
18405 }
18406 if ((j < temp) && (currentRate > maxRate))
18407 {
18408 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070018409 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018410 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018411 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018412 }
18413 }
18414
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018415 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
18416 {
18417 maxRate = myRate;
18418 maxSpeedMCS = 1;
18419 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18420 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018421 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053018422 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070018423 {
18424 maxRate = myRate;
18425 if (rate_flags & eHAL_TX_RATE_LEGACY)
18426 {
18427 maxSpeedMCS = 0;
18428 }
18429 else
18430 {
18431 maxSpeedMCS = 1;
18432 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18433 }
18434 }
18435
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018436 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070018437 {
18438 sinfo->txrate.legacy = maxRate;
18439#ifdef LINKSPEED_DEBUG_ENABLED
18440 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
18441#endif //LINKSPEED_DEBUG_ENABLED
18442 }
18443 else
18444 {
18445 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070018446#ifdef WLAN_FEATURE_11AC
18447 sinfo->txrate.nss = 1;
18448 if (rate_flags & eHAL_TX_RATE_VHT80)
18449 {
18450 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018451#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18452 defined(WITH_BACKPORTS)
18453 sinfo->txrate.bw = RATE_INFO_BW_80;
18454#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018455 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018456#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018457 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018458 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070018459 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018460 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018461#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18462 defined(WITH_BACKPORTS)
18463 sinfo->txrate.bw = RATE_INFO_BW_40;
18464#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018465 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018466#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018467 }
18468 else if (rate_flags & eHAL_TX_RATE_VHT20)
18469 {
18470 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18471 }
18472#endif /* WLAN_FEATURE_11AC */
18473 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
18474 {
18475 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18476 if (rate_flags & eHAL_TX_RATE_HT40)
18477 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018478#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18479 defined(WITH_BACKPORTS)
18480 sinfo->txrate.bw = RATE_INFO_BW_40;
18481#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018482 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018483#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018484 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018485 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018486 if (rate_flags & eHAL_TX_RATE_SGI)
18487 {
18488 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18489 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018490
Jeff Johnson295189b2012-06-20 16:38:30 -070018491#ifdef LINKSPEED_DEBUG_ENABLED
18492 pr_info("Reporting MCS rate %d flags %x\n",
18493 sinfo->txrate.mcs,
18494 sinfo->txrate.flags );
18495#endif //LINKSPEED_DEBUG_ENABLED
18496 }
18497 }
18498 else
18499 {
18500 // report current rate instead of max rate
18501
18502 if (rate_flags & eHAL_TX_RATE_LEGACY)
18503 {
18504 //provide to the UI in units of 100kbps
18505 sinfo->txrate.legacy = myRate;
18506#ifdef LINKSPEED_DEBUG_ENABLED
18507 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
18508#endif //LINKSPEED_DEBUG_ENABLED
18509 }
18510 else
18511 {
18512 //must be MCS
18513 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018514#ifdef WLAN_FEATURE_11AC
18515 sinfo->txrate.nss = 1;
18516 if (rate_flags & eHAL_TX_RATE_VHT80)
18517 {
18518 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18519 }
18520 else
18521#endif /* WLAN_FEATURE_11AC */
18522 {
18523 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18524 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018525 if (rate_flags & eHAL_TX_RATE_SGI)
18526 {
18527 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18528 }
18529 if (rate_flags & eHAL_TX_RATE_HT40)
18530 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018531#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18532 defined(WITH_BACKPORTS)
18533 sinfo->txrate.bw = RATE_INFO_BW_40;
18534#else
Jeff Johnson295189b2012-06-20 16:38:30 -070018535 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018536#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018537 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018538#ifdef WLAN_FEATURE_11AC
18539 else if (rate_flags & eHAL_TX_RATE_VHT80)
18540 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018541#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18542 defined(WITH_BACKPORTS)
18543 sinfo->txrate.bw = RATE_INFO_BW_80;
18544#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018545 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018546#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018547 }
18548#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018549#ifdef LINKSPEED_DEBUG_ENABLED
18550 pr_info("Reporting actual MCS rate %d flags %x\n",
18551 sinfo->txrate.mcs,
18552 sinfo->txrate.flags );
18553#endif //LINKSPEED_DEBUG_ENABLED
18554 }
18555 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018556
18557#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18558 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018559 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018560#else
18561 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18562#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018563
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018564 sinfo->tx_packets =
18565 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18566 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18567 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18568 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18569
18570 sinfo->tx_retries =
18571 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18572 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18573 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18574 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18575
18576 sinfo->tx_failed =
18577 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18578 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18579 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18580 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18581
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018582#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18583 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018584 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018585 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018586 STATION_INFO_TX_PACKETS |
18587 STATION_INFO_TX_RETRIES |
18588 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018589#else
18590 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18591 BIT(NL80211_STA_INFO_TX_PACKETS) |
18592 BIT(NL80211_STA_INFO_TX_RETRIES) |
18593 BIT(NL80211_STA_INFO_TX_FAILED);
18594#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018595
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018596 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018597
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018598 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18599 &sinfo->txrate, sizeof(sinfo->txrate));
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018600 vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate,
18601 &sinfo->txrate, sizeof(sinfo->txrate));
18602
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018603 if (rate_flags & eHAL_TX_RATE_LEGACY)
18604 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18605 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18606 sinfo->rx_packets);
18607 else
18608 hddLog(LOG1,
18609 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18610 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18611 sinfo->tx_packets, sinfo->rx_packets);
18612
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018613 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18614 TRACE_CODE_HDD_CFG80211_GET_STA,
18615 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018616 EXIT();
18617 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018618}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018619#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18620static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18621 const u8* mac, struct station_info *sinfo)
18622#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018623static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18624 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018625#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018626{
18627 int ret;
18628
18629 vos_ssr_protect(__func__);
18630 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18631 vos_ssr_unprotect(__func__);
18632
18633 return ret;
18634}
18635
18636static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018637 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018638{
18639 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018640 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018641 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018642 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018643
Jeff Johnsone7245742012-09-05 17:12:55 -070018644 ENTER();
18645
Jeff Johnson295189b2012-06-20 16:38:30 -070018646 if (NULL == pAdapter)
18647 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018648 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018649 return -ENODEV;
18650 }
18651
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018652 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18653 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18654 pAdapter->sessionId, timeout));
18655
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018656 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018657 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018658 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018659 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018660 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018661 }
18662
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018663 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
18664 (TRUE == pHddCtx->hdd_wlan_suspended) &&
18665 (pHddCtx->cfg_ini->fhostArpOffload) &&
18666 (eConnectionState_Associated ==
18667 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
18668 {
Amar Singhald53568e2013-09-26 11:03:45 -070018669
18670 hddLog(VOS_TRACE_LEVEL_INFO,
18671 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053018672 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018673 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18674 {
18675 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018676 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018677 __func__, vos_status);
18678 }
18679 }
18680
Jeff Johnson295189b2012-06-20 16:38:30 -070018681 /**The get power cmd from the supplicant gets updated by the nl only
18682 *on successful execution of the function call
18683 *we are oppositely mapped w.r.t mode in the driver
18684 **/
18685 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
18686
18687 if (VOS_STATUS_E_FAILURE == vos_status)
18688 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018689 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18690 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018691 return -EINVAL;
18692 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018693 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018694 return 0;
18695}
18696
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018697static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
18698 struct net_device *dev, bool mode, int timeout)
18699{
18700 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018701
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018702 vos_ssr_protect(__func__);
18703 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
18704 vos_ssr_unprotect(__func__);
18705
18706 return ret;
18707}
Sushant Kaushik084f6592015-09-10 13:11:56 +053018708
Jeff Johnson295189b2012-06-20 16:38:30 -070018709#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018710static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
18711 struct net_device *netdev,
18712 u8 key_index)
18713{
18714 ENTER();
18715 return 0;
18716}
18717
Jeff Johnson295189b2012-06-20 16:38:30 -070018718static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018719 struct net_device *netdev,
18720 u8 key_index)
18721{
18722 int ret;
18723 vos_ssr_protect(__func__);
18724 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
18725 vos_ssr_unprotect(__func__);
18726 return ret;
18727}
18728#endif //LINUX_VERSION_CODE
18729
18730#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18731static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18732 struct net_device *dev,
18733 struct ieee80211_txq_params *params)
18734{
18735 ENTER();
18736 return 0;
18737}
18738#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18739static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18740 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018741{
Jeff Johnsone7245742012-09-05 17:12:55 -070018742 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070018743 return 0;
18744}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018745#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070018746
18747#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18748static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018749 struct net_device *dev,
18750 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018751{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018752 int ret;
18753
18754 vos_ssr_protect(__func__);
18755 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
18756 vos_ssr_unprotect(__func__);
18757 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018758}
18759#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18760static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
18761 struct ieee80211_txq_params *params)
18762{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018763 int ret;
18764
18765 vos_ssr_protect(__func__);
18766 ret = __wlan_hdd_set_txq_params(wiphy, params);
18767 vos_ssr_unprotect(__func__);
18768 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018769}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018770#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018771
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018772static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018773 struct net_device *dev,
18774 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070018775{
18776 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018777 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018778 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018779 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018780 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018781 v_CONTEXT_t pVosContext = NULL;
18782 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018783
Jeff Johnsone7245742012-09-05 17:12:55 -070018784 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018785
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018786 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070018787 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018788 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018789 return -EINVAL;
18790 }
18791
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018792 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18793 TRACE_CODE_HDD_CFG80211_DEL_STA,
18794 pAdapter->sessionId, pAdapter->device_mode));
18795
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018796 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18797 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018798 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018799 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018800 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018801 }
18802
Jeff Johnson295189b2012-06-20 16:38:30 -070018803 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018804 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018805 )
18806 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018807 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
18808 pSapCtx = VOS_GET_SAP_CB(pVosContext);
18809 if(pSapCtx == NULL){
18810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18811 FL("psapCtx is NULL"));
18812 return -ENOENT;
18813 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053018814 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
18815 {
18816 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
18817 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
18818 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
18819 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018820 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070018821 {
18822 v_U16_t i;
18823 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
18824 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018825 if ((pSapCtx->aStaInfo[i].isUsed) &&
18826 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070018827 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018828 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018829 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018830 ETHER_ADDR_LEN);
18831
Jeff Johnson295189b2012-06-20 16:38:30 -070018832 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018833 "%s: Delete STA with MAC::"
18834 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018835 __func__,
18836 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18837 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018838 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018839 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018840 }
18841 }
18842 }
18843 else
18844 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018845
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018846 vos_status = hdd_softap_GetStaId(pAdapter,
18847 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018848 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18849 {
18850 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018851 "%s: Skip this DEL STA as this is not used::"
18852 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018853 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018854 return -ENOENT;
18855 }
18856
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018857 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018858 {
18859 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018860 "%s: Skip this DEL STA as deauth is in progress::"
18861 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018862 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018863 return -ENOENT;
18864 }
18865
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018866 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018867
Jeff Johnson295189b2012-06-20 16:38:30 -070018868 hddLog(VOS_TRACE_LEVEL_INFO,
18869 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018870 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018871 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018872 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018873
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018874 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018875 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18876 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018877 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018878 hddLog(VOS_TRACE_LEVEL_INFO,
18879 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018880 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018881 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018882 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018883 return -ENOENT;
18884 }
18885
Jeff Johnson295189b2012-06-20 16:38:30 -070018886 }
18887 }
18888
18889 EXIT();
18890
18891 return 0;
18892}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018893
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018894#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018895int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018896 struct net_device *dev,
18897 struct station_del_parameters *param)
18898#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018899#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018900int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018901 struct net_device *dev, const u8 *mac)
18902#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018903int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018904 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018905#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018906#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018907{
18908 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018909 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018910
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018911 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018912
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018913#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018914 if (NULL == param) {
18915 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018916 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018917 return -EINVAL;
18918 }
18919
18920 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
18921 param->subtype, &delStaParams);
18922
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018923#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053018924 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018925 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018926#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018927 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
18928
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018929 vos_ssr_unprotect(__func__);
18930
18931 return ret;
18932}
18933
18934static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018935 struct net_device *dev,
18936#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18937 const u8 *mac,
18938#else
18939 u8 *mac,
18940#endif
18941 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018942{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018943 hdd_adapter_t *pAdapter;
18944 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018945 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018946#ifdef FEATURE_WLAN_TDLS
18947 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018948
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018949 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018950
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018951 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18952 if (NULL == pAdapter)
18953 {
18954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18955 "%s: Adapter is NULL",__func__);
18956 return -EINVAL;
18957 }
18958 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18959 status = wlan_hdd_validate_context(pHddCtx);
18960 if (0 != status)
18961 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018962 return status;
18963 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018964
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018965 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18966 TRACE_CODE_HDD_CFG80211_ADD_STA,
18967 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018968 mask = params->sta_flags_mask;
18969
18970 set = params->sta_flags_set;
18971
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018972 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018973 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
18974 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018975
18976 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
18977 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080018978 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018979 }
18980 }
18981#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018982 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018983 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018984}
18985
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018986#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18987static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18988 struct net_device *dev, const u8 *mac,
18989 struct station_parameters *params)
18990#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018991static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18992 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018993#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018994{
18995 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018996
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018997 vos_ssr_protect(__func__);
18998 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
18999 vos_ssr_unprotect(__func__);
19000
19001 return ret;
19002}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019003#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070019004
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019005static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070019006 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019007{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019008 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19009 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019010 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019011 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019012 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019013 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070019014
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019015 ENTER();
19016
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019017 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019018 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019019 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019020 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019021 return -EINVAL;
19022 }
19023
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019024 if (!pmksa) {
19025 hddLog(LOGE, FL("pmksa is NULL"));
19026 return -EINVAL;
19027 }
19028
19029 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070019030 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019031 pmksa->bssid, pmksa->pmkid);
19032 return -EINVAL;
19033 }
19034
19035 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
19036 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19037
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019038 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19039 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019040 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019041 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019042 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019043 }
19044
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019045 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019046 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19047
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019048 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
19049 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019050
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019051 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019052 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019053 &pmk_id, 1, FALSE);
19054
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019055 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19056 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
19057 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019058
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019059 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019060 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019061}
19062
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019063static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
19064 struct cfg80211_pmksa *pmksa)
19065{
19066 int ret;
19067
19068 vos_ssr_protect(__func__);
19069 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
19070 vos_ssr_unprotect(__func__);
19071
19072 return ret;
19073}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019074
Wilson Yang6507c4e2013-10-01 20:11:19 -070019075
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019076static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070019077 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019078{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019079 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19080 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019081 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019082 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019083
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019084 ENTER();
19085
Wilson Yang6507c4e2013-10-01 20:11:19 -070019086 /* Validate pAdapter */
19087 if (NULL == pAdapter)
19088 {
19089 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
19090 return -EINVAL;
19091 }
19092
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019093 if (!pmksa) {
19094 hddLog(LOGE, FL("pmksa is NULL"));
19095 return -EINVAL;
19096 }
19097
19098 if (!pmksa->bssid) {
19099 hddLog(LOGE, FL("pmksa->bssid is NULL"));
19100 return -EINVAL;
19101 }
19102
Kiet Lam98c46a12014-10-31 15:34:57 -070019103 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
19104 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19105
Wilson Yang6507c4e2013-10-01 20:11:19 -070019106 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19107 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019108 if (0 != status)
19109 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019110 return status;
19111 }
19112
19113 /*Retrieve halHandle*/
19114 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19115
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019116 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19117 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
19118 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019119 /* Delete the PMKID CSR cache */
19120 if (eHAL_STATUS_SUCCESS !=
19121 sme_RoamDelPMKIDfromCache(halHandle,
19122 pAdapter->sessionId, pmksa->bssid, FALSE)) {
19123 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
19124 MAC_ADDR_ARRAY(pmksa->bssid));
19125 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019126 }
19127
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019128 EXIT();
19129 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019130}
19131
Wilson Yang6507c4e2013-10-01 20:11:19 -070019132
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019133static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
19134 struct cfg80211_pmksa *pmksa)
19135{
19136 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019137
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019138 vos_ssr_protect(__func__);
19139 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
19140 vos_ssr_unprotect(__func__);
19141
19142 return ret;
19143
19144}
19145
19146static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019147{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019148 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19149 tHalHandle halHandle;
19150 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019151 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019152
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019153 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070019154
19155 /* Validate pAdapter */
19156 if (NULL == pAdapter)
19157 {
19158 hddLog(VOS_TRACE_LEVEL_ERROR,
19159 "%s: Invalid Adapter" ,__func__);
19160 return -EINVAL;
19161 }
19162
19163 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19164 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019165 if (0 != status)
19166 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019167 return status;
19168 }
19169
19170 /*Retrieve halHandle*/
19171 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19172
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019173 /* Flush the PMKID cache in CSR */
19174 if (eHAL_STATUS_SUCCESS !=
19175 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
19176 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
19177 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019178 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019179 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080019180 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019181}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019182
19183static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
19184{
19185 int ret;
19186
19187 vos_ssr_protect(__func__);
19188 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
19189 vos_ssr_unprotect(__func__);
19190
19191 return ret;
19192}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019193#endif
19194
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019195#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019196static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19197 struct net_device *dev,
19198 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019199{
19200 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19201 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019202 hdd_context_t *pHddCtx;
19203 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019204
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019205 ENTER();
19206
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019207 if (NULL == pAdapter)
19208 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019209 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019210 return -ENODEV;
19211 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019212 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19213 ret = wlan_hdd_validate_context(pHddCtx);
19214 if (0 != ret)
19215 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019216 return ret;
19217 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019218 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019219 if (NULL == pHddStaCtx)
19220 {
19221 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
19222 return -EINVAL;
19223 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019224
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019225 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19226 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
19227 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019228 // Added for debug on reception of Re-assoc Req.
19229 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
19230 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019231 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019232 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080019233 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019234 }
19235
19236#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080019237 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019238 ftie->ie_len);
19239#endif
19240
19241 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053019242 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
19243 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019244 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019245
19246 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019247 return 0;
19248}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019249
19250static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19251 struct net_device *dev,
19252 struct cfg80211_update_ft_ies_params *ftie)
19253{
19254 int ret;
19255
19256 vos_ssr_protect(__func__);
19257 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
19258 vos_ssr_unprotect(__func__);
19259
19260 return ret;
19261}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019262#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019263
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019264#ifdef FEATURE_WLAN_SCAN_PNO
19265
19266void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
19267 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
19268{
19269 int ret;
19270 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
19271 hdd_context_t *pHddCtx;
19272
Nirav Shah80830bf2013-12-31 16:35:12 +053019273 ENTER();
19274
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019275 if (NULL == pAdapter)
19276 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019277 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019278 "%s: HDD adapter is Null", __func__);
19279 return ;
19280 }
19281
19282 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19283 if (NULL == pHddCtx)
19284 {
19285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19286 "%s: HDD context is Null!!!", __func__);
19287 return ;
19288 }
19289
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019290 spin_lock(&pHddCtx->schedScan_lock);
19291 if (TRUE == pHddCtx->isWiphySuspended)
19292 {
19293 pHddCtx->isSchedScanUpdatePending = TRUE;
19294 spin_unlock(&pHddCtx->schedScan_lock);
19295 hddLog(VOS_TRACE_LEVEL_INFO,
19296 "%s: Update cfg80211 scan database after it resume", __func__);
19297 return ;
19298 }
19299 spin_unlock(&pHddCtx->schedScan_lock);
19300
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019301 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
19302
19303 if (0 > ret)
19304 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053019305 else
19306 {
19307 /* Acquire wakelock to handle the case where APP's tries to suspend
19308 * immediatly after the driver gets connect request(i.e after pno)
19309 * from supplicant, this result in app's is suspending and not able
19310 * to process the connect request to AP */
19311 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
19312 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019313 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19315 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019316}
19317
19318/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019319 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019320 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019321 */
19322static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
19323{
19324 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
19325 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019326 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019327 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19328 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053019329
19330 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
19331 {
19332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19333 "%s: PNO is allowed only in STA interface", __func__);
19334 return eHAL_STATUS_FAILURE;
19335 }
19336
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019337 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
19338
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019339 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053019340 * active sessions. PNO is allowed only in case when sap session
19341 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019342 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019343 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
19344 {
19345 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019346 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019347
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019348 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
19349 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
19350 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
19351 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053019352 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
19353 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053019354 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019355 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019356 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019357 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019358 }
19359 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19360 pAdapterNode = pNext;
19361 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019362 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019363}
19364
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019365void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
19366{
19367 hdd_adapter_t *pAdapter = callbackContext;
19368 hdd_context_t *pHddCtx;
19369
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019370 ENTER();
19371
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019372 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
19373 {
19374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19375 FL("Invalid adapter or adapter has invalid magic"));
19376 return;
19377 }
19378
19379 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19380 if (0 != wlan_hdd_validate_context(pHddCtx))
19381 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019382 return;
19383 }
19384
c_hpothub53c45d2014-08-18 16:53:14 +053019385 if (VOS_STATUS_SUCCESS != status)
19386 {
19387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019388 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053019389 pHddCtx->isPnoEnable = FALSE;
19390 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019391
19392 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
19393 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019394 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019395}
19396
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019397#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
19398 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
19399/**
19400 * hdd_config_sched_scan_plan() - configures the sched scan plans
19401 * from the framework.
19402 * @pno_req: pointer to PNO scan request
19403 * @request: pointer to scan request from framework
19404 *
19405 * Return: None
19406 */
19407static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
19408 struct cfg80211_sched_scan_request *request,
19409 hdd_context_t *hdd_ctx)
19410{
19411 v_U32_t i = 0;
19412
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019413 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019414 for (i = 0; i < request->n_scan_plans; i++)
19415 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019416 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
19417 request->scan_plans[i].iterations;
19418 pno_req->scanTimers.aTimerValues[i].uTimerValue =
19419 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019420 }
19421}
19422#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019423static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019424 struct cfg80211_sched_scan_request *request,
19425 hdd_context_t *hdd_ctx)
19426{
19427 v_U32_t i, temp_int;
19428 /* Driver gets only one time interval which is hardcoded in
19429 * supplicant for 10000ms. Taking power consumption into account 6
19430 * timers will be used, Timervalue is increased exponentially
19431 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
19432 * timer is configurable through INI param gPNOScanTimerRepeatValue.
19433 * If it is set to 0 only one timer will be used and PNO scan cycle
19434 * will be repeated after each interval specified by supplicant
19435 * till PNO is disabled.
19436 */
19437 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019438 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019439 HDD_PNO_SCAN_TIMERS_SET_ONE;
19440 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019441 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019442 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
19443
19444 temp_int = (request->interval)/1000;
19445 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19446 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
19447 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019448 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019449 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019450 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019451 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019452 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019453 temp_int *= 2;
19454 }
19455 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019456 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019457}
19458#endif
19459
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019460/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019461 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
19462 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019463 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019464static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019465 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19466{
19467 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019468 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019469 hdd_context_t *pHddCtx;
19470 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019471 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053019472 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
19473 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019474 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
19475 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019476 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019477 hdd_config_t *pConfig = NULL;
19478 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019479
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019480 ENTER();
19481
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019482 if (NULL == pAdapter)
19483 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019484 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019485 "%s: HDD adapter is Null", __func__);
19486 return -ENODEV;
19487 }
19488
19489 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019490 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019491
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019492 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019493 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019494 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019495 }
19496
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019497 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019498 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19499 if (NULL == hHal)
19500 {
19501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19502 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019503 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019504 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019505 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19506 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
19507 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019508 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053019509 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019510 {
19511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19512 "%s: aborting the existing scan is unsuccessfull", __func__);
19513 return -EBUSY;
19514 }
19515
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019516 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019517 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019518 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019519 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019520 return -EBUSY;
19521 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019522
c_hpothu37f21312014-04-09 21:49:54 +053019523 if (TRUE == pHddCtx->isPnoEnable)
19524 {
19525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19526 FL("already PNO is enabled"));
19527 return -EBUSY;
19528 }
c_hpothu225aa7c2014-10-22 17:45:13 +053019529
19530 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
19531 {
19532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19533 "%s: abort ROC failed ", __func__);
19534 return -EBUSY;
19535 }
19536
c_hpothu37f21312014-04-09 21:49:54 +053019537 pHddCtx->isPnoEnable = TRUE;
19538
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019539 pnoRequest.enable = 1; /*Enable PNO */
19540 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019541
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019542 if (( !pnoRequest.ucNetworksCount ) ||
19543 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019544 {
19545 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019546 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019547 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019548 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019549 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019550 goto error;
19551 }
19552
19553 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
19554 {
19555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019556 "%s: Incorrect number of channels %d",
19557 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019558 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019559 goto error;
19560 }
19561
19562 /* Framework provides one set of channels(all)
19563 * common for all saved profile */
19564 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
19565 channels_allowed, &num_channels_allowed))
19566 {
19567 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19568 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019569 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019570 goto error;
19571 }
19572 /* Checking each channel against allowed channel list */
19573 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053019574 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019575 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019576 char chList [(request->n_channels*5)+1];
19577 int len;
19578 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019579 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019580 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019581 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019582 if (request->channels[i]->hw_value == channels_allowed[indx])
19583 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019584 if ((!pConfig->enableDFSPnoChnlScan) &&
19585 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
19586 {
19587 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19588 "%s : Dropping DFS channel : %d",
19589 __func__,channels_allowed[indx]);
19590 num_ignore_dfs_ch++;
19591 break;
19592 }
19593
Nirav Shah80830bf2013-12-31 16:35:12 +053019594 valid_ch[num_ch++] = request->channels[i]->hw_value;
19595 len += snprintf(chList+len, 5, "%d ",
19596 request->channels[i]->hw_value);
19597 break ;
19598 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019599 }
19600 }
Nirav Shah80830bf2013-12-31 16:35:12 +053019601 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019602
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019603 /*If all channels are DFS and dropped, then ignore the PNO request*/
19604 if (num_ignore_dfs_ch == request->n_channels)
19605 {
19606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19607 "%s : All requested channels are DFS channels", __func__);
19608 ret = -EINVAL;
19609 goto error;
19610 }
19611 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019612
19613 pnoRequest.aNetworks =
19614 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19615 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019616 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019617 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19618 FL("failed to allocate memory aNetworks %u"),
19619 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19620 goto error;
19621 }
19622 vos_mem_zero(pnoRequest.aNetworks,
19623 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19624
19625 /* Filling per profile params */
19626 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
19627 {
19628 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019629 request->match_sets[i].ssid.ssid_len;
19630
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019631 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
19632 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019633 {
19634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019635 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019636 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019637 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019638 goto error;
19639 }
19640
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019641 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019642 request->match_sets[i].ssid.ssid,
19643 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19645 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019646 i, pnoRequest.aNetworks[i].ssId.ssId);
19647 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
19648 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
19649 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019650
19651 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019652 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
19653 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019654
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019655 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019656 }
19657
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019658 for (i = 0; i < request->n_ssids; i++)
19659 {
19660 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019661 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019662 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019663 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019664 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019665 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019666 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019667 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019668 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019669 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019670 break;
19671 }
19672 j++;
19673 }
19674 }
19675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19676 "Number of hidden networks being Configured = %d",
19677 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080019679 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019680
19681 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19682 if (pnoRequest.p24GProbeTemplate == NULL)
19683 {
19684 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19685 FL("failed to allocate memory p24GProbeTemplate %u"),
19686 SIR_PNO_MAX_PB_REQ_SIZE);
19687 goto error;
19688 }
19689
19690 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19691 if (pnoRequest.p5GProbeTemplate == NULL)
19692 {
19693 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19694 FL("failed to allocate memory p5GProbeTemplate %u"),
19695 SIR_PNO_MAX_PB_REQ_SIZE);
19696 goto error;
19697 }
19698
19699 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19700 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19701
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053019702 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
19703 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019704 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019705 pnoRequest.us24GProbeTemplateLen = request->ie_len;
19706 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
19707 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019708
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019709 pnoRequest.us5GProbeTemplateLen = request->ie_len;
19710 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
19711 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019712 }
19713
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019714 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053019715
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019716 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019717
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019718 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019719 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19720 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019721 pAdapter->pno_req_status = 0;
19722
Nirav Shah80830bf2013-12-31 16:35:12 +053019723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19724 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019725 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
19726 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053019727
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019728 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019729 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019730 hdd_cfg80211_sched_scan_done_callback, pAdapter);
19731 if (eHAL_STATUS_SUCCESS != status)
19732 {
19733 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019734 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019735 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019736 goto error;
19737 }
19738
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019739 ret = wait_for_completion_timeout(
19740 &pAdapter->pno_comp_var,
19741 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19742 if (0 >= ret)
19743 {
19744 // Did not receive the response for PNO enable in time.
19745 // Assuming the PNO enable was success.
19746 // Returning error from here, because we timeout, results
19747 // in side effect of Wifi (Wifi Setting) not to work.
19748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19749 FL("Timed out waiting for PNO to be Enabled"));
19750 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019751 }
19752
19753 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053019754 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019755
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019756error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19758 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053019759 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019760 if (pnoRequest.aNetworks)
19761 vos_mem_free(pnoRequest.aNetworks);
19762 if (pnoRequest.p24GProbeTemplate)
19763 vos_mem_free(pnoRequest.p24GProbeTemplate);
19764 if (pnoRequest.p5GProbeTemplate)
19765 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019766
19767 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019768 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019769}
19770
19771/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019772 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
19773 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019774 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019775static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
19776 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19777{
19778 int ret;
19779
19780 vos_ssr_protect(__func__);
19781 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
19782 vos_ssr_unprotect(__func__);
19783
19784 return ret;
19785}
19786
19787/*
19788 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
19789 * Function to disable PNO
19790 */
19791static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019792 struct net_device *dev)
19793{
19794 eHalStatus status = eHAL_STATUS_FAILURE;
19795 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19796 hdd_context_t *pHddCtx;
19797 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019798 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019799 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019800
19801 ENTER();
19802
19803 if (NULL == pAdapter)
19804 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019805 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019806 "%s: HDD adapter is Null", __func__);
19807 return -ENODEV;
19808 }
19809
19810 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019811
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019812 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019813 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019815 "%s: HDD context is Null", __func__);
19816 return -ENODEV;
19817 }
19818
19819 /* The return 0 is intentional when isLogpInProgress and
19820 * isLoadUnloadInProgress. We did observe a crash due to a return of
19821 * failure in sched_scan_stop , especially for a case where the unload
19822 * of the happens at the same time. The function __cfg80211_stop_sched_scan
19823 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
19824 * success. If it returns a failure , then its next invocation due to the
19825 * clean up of the second interface will have the dev pointer corresponding
19826 * to the first one leading to a crash.
19827 */
19828 if (pHddCtx->isLogpInProgress)
19829 {
19830 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19831 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019832 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019833 return ret;
19834 }
19835
Mihir Shete18156292014-03-11 15:38:30 +053019836 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019837 {
19838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19839 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19840 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019841 }
19842
19843 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19844 if (NULL == hHal)
19845 {
19846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19847 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019848 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019849 }
19850
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019851 pnoRequest.enable = 0; /* Disable PNO */
19852 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019853
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019854 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19855 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19856 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019857
19858 INIT_COMPLETION(pAdapter->pno_comp_var);
19859 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19860 pnoRequest.callbackContext = pAdapter;
19861 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019862 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019863 pAdapter->sessionId,
19864 NULL, pAdapter);
19865 if (eHAL_STATUS_SUCCESS != status)
19866 {
19867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19868 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019869 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019870 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019871 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019872 ret = wait_for_completion_timeout(
19873 &pAdapter->pno_comp_var,
19874 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19875 if (0 >= ret)
19876 {
19877 // Did not receive the response for PNO disable in time.
19878 // Assuming the PNO disable was success.
19879 // Returning error from here, because we timeout, results
19880 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019881 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019882 FL("Timed out waiting for PNO to be disabled"));
19883 ret = 0;
19884 }
19885
19886 ret = pAdapter->pno_req_status;
19887 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019888
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019889error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019890 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019891 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019892
19893 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019894 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019895}
19896
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019897/*
19898 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19899 * NL interface to disable PNO
19900 */
19901static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19902 struct net_device *dev)
19903{
19904 int ret;
19905
19906 vos_ssr_protect(__func__);
19907 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19908 vos_ssr_unprotect(__func__);
19909
19910 return ret;
19911}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019912#endif /*FEATURE_WLAN_SCAN_PNO*/
19913
19914
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019915#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019916#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019917static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19918 struct net_device *dev,
19919 u8 *peer, u8 action_code,
19920 u8 dialog_token,
19921 u16 status_code, u32 peer_capability,
19922 const u8 *buf, size_t len)
19923#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019924#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
19925 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019926static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19927 struct net_device *dev,
19928 const u8 *peer, u8 action_code,
19929 u8 dialog_token, u16 status_code,
19930 u32 peer_capability, bool initiator,
19931 const u8 *buf, size_t len)
19932#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19933static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19934 struct net_device *dev,
19935 const u8 *peer, u8 action_code,
19936 u8 dialog_token, u16 status_code,
19937 u32 peer_capability, const u8 *buf,
19938 size_t len)
19939#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19940static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19941 struct net_device *dev,
19942 u8 *peer, u8 action_code,
19943 u8 dialog_token,
19944 u16 status_code, u32 peer_capability,
19945 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019946#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019947static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19948 struct net_device *dev,
19949 u8 *peer, u8 action_code,
19950 u8 dialog_token,
19951 u16 status_code, const u8 *buf,
19952 size_t len)
19953#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019954#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019955{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019956 hdd_adapter_t *pAdapter;
19957 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019958 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070019959 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080019960 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070019961 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019962 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019963 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019964#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019965 u32 peer_capability = 0;
19966#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019967 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019968 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019969 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019970
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019971 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19972 if (NULL == pAdapter)
19973 {
19974 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19975 "%s: Adapter is NULL",__func__);
19976 return -EINVAL;
19977 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019978 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19979 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
19980 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019981
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019982 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019983 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019984 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019985 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019986 "Invalid arguments");
19987 return -EINVAL;
19988 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019989
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019990 if (pHddCtx->isLogpInProgress)
19991 {
19992 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19993 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053019994 wlan_hdd_tdls_set_link_status(pAdapter,
19995 peer,
19996 eTDLS_LINK_IDLE,
19997 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019998 return -EBUSY;
19999 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020000
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020001 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
20002 {
20003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20004 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
20005 return -EAGAIN;
20006 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020007
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020008 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
20009 if (!pHddTdlsCtx) {
20010 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20011 "%s: pHddTdlsCtx not valid.", __func__);
Hanumanth Reddy Pothula36dfa522018-03-12 16:42:08 +053020012 return -EINVAL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020013 }
20014
Hoonki Lee27511902013-03-14 18:19:06 -070020015 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020016 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020017 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020018 "%s: TDLS mode is disabled OR not enabled in FW."
20019 MAC_ADDRESS_STR " action %d declined.",
20020 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020021 return -ENOTSUPP;
20022 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020023
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020024 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20025
20026 if( NULL == pHddStaCtx )
20027 {
20028 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20029 "%s: HDD station context NULL ",__func__);
20030 return -EINVAL;
20031 }
20032
20033 /* STA should be connected and authenticated
20034 * before sending any TDLS frames
20035 */
20036 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
20037 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
20038 {
20039 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20040 "STA is not connected or unauthenticated. "
20041 "connState %u, uIsAuthenticated %u",
20042 pHddStaCtx->conn_info.connState,
20043 pHddStaCtx->conn_info.uIsAuthenticated);
20044 return -EAGAIN;
20045 }
20046
Hoonki Lee27511902013-03-14 18:19:06 -070020047 /* other than teardown frame, other mgmt frames are not sent if disabled */
20048 if (SIR_MAC_TDLS_TEARDOWN != action_code)
20049 {
20050 /* if tdls_mode is disabled to respond to peer's request */
20051 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
20052 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020053 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020054 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020055 " TDLS mode is disabled. action %d declined.",
20056 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070020057
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020058 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070020059 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053020060
20061 if (vos_max_concurrent_connections_reached())
20062 {
20063 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
20064 return -EINVAL;
20065 }
Hoonki Lee27511902013-03-14 18:19:06 -070020066 }
20067
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020068 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
20069 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053020070 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020071 {
20072 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020073 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020074 " TDLS setup is ongoing. action %d declined.",
20075 __func__, MAC_ADDR_ARRAY(peer), action_code);
20076 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020077 }
20078 }
20079
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020080 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
20081 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080020082 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020083 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20084 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020085 {
20086 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
20087 we return error code at 'add_station()'. Hence we have this
20088 check again in addtion to add_station().
20089 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020090 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020091 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020092 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20093 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020094 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
20095 __func__, MAC_ADDR_ARRAY(peer), action_code,
20096 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053020097 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080020098 }
20099 else
20100 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020101 /* maximum reached. tweak to send error code to peer and return
20102 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020103 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20105 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020106 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
20107 __func__, MAC_ADDR_ARRAY(peer), status_code,
20108 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070020109 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020110 /* fall through to send setup resp with failure status
20111 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020112 }
20113 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020114 else
20115 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020116 mutex_lock(&pHddCtx->tdls_lock);
20117 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020118 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020119 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020120 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020122 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
20123 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020124 return -EPERM;
20125 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020126 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020127 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020128 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020129
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020131 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020132 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
20133 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020134
Hoonki Leea34dd892013-02-05 22:56:02 -080020135 /*Except teardown responder will not be used so just make 0*/
20136 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020137 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080020138 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020139
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020140 mutex_lock(&pHddCtx->tdls_lock);
20141 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020142
20143 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
20144 responder = pTdlsPeer->is_responder;
20145 else
Hoonki Leea34dd892013-02-05 22:56:02 -080020146 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020148 "%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 -070020149 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
20150 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020151 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020152 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080020153 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020154 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020155 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020156
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020157 /* Discard TDLS setup if peer is removed by user app */
20158 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
20159 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20160 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
20161 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
20162
20163 mutex_lock(&pHddCtx->tdls_lock);
20164 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20165 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
20166 mutex_unlock(&pHddCtx->tdls_lock);
20167 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
20168 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
20169 MAC_ADDR_ARRAY(peer), action_code);
20170 return -EINVAL;
20171 }
20172 mutex_unlock(&pHddCtx->tdls_lock);
20173 }
20174
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020175 /* For explicit trigger of DIS_REQ come out of BMPS for
20176 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070020177 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053020178 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020179 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
20180 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070020181 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020182 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020184 "%s: Sending frame action_code %u.Disable BMPS", __func__,
20185 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020186 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
20187 if (status != VOS_STATUS_SUCCESS) {
20188 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020189 } else {
20190 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020191 }
Hoonki Lee14621352013-04-16 17:51:19 -070020192 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020193 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020194 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020195 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
20196 }
20197 }
Hoonki Lee14621352013-04-16 17:51:19 -070020198 }
20199
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020200 /* make sure doesn't call send_mgmt() while it is pending */
20201 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
20202 {
20203 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080020204 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020205 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020206 ret = -EBUSY;
20207 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020208 }
20209
20210 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020211 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
20212
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020213 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
20214 pAdapter->sessionId, peer, action_code, dialog_token,
20215 status_code, peer_capability, (tANI_U8 *)buf, len,
20216 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020217
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020218 if (VOS_STATUS_SUCCESS != status)
20219 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020220 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20221 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020222 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020223 ret = -EINVAL;
20224 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020225 }
20226
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020227 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20228 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
20229 WAIT_TIME_TDLS_MGMT);
20230
Hoonki Leed37cbb32013-04-20 00:31:14 -070020231 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
20232 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
20233
20234 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020235 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070020236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070020237 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070020238 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020239 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080020240
20241 if (pHddCtx->isLogpInProgress)
20242 {
20243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20244 "%s: LOGP in Progress. Ignore!!!", __func__);
20245 return -EAGAIN;
20246 }
Abhishek Singh837adf22015-10-01 17:37:37 +053020247 if (rc <= 0)
20248 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
20249 WLAN_LOG_INDICATOR_HOST_DRIVER,
20250 WLAN_LOG_REASON_HDD_TIME_OUT,
20251 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080020252
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020253 ret = -EINVAL;
20254 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020255 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020256 else
20257 {
20258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20259 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
20260 __func__, rc, pAdapter->mgmtTxCompletionStatus);
20261 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020262
Gopichand Nakkala05922802013-03-14 12:23:19 -070020263 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070020264 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020265 ret = max_sta_failed;
20266 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070020267 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020268
Hoonki Leea34dd892013-02-05 22:56:02 -080020269 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
20270 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020271 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020272 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20273 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020274 }
20275 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
20276 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020277 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020278 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20279 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020280 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020281
20282 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020283
20284tx_failed:
20285 /* add_station will be called before sending TDLS_SETUP_REQ and
20286 * TDLS_SETUP_RSP and as part of add_station driver will enable
20287 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
20288 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
20289 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
20290 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
20291 */
20292
20293 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20294 (SIR_MAC_TDLS_SETUP_RSP == action_code))
20295 wlan_hdd_tdls_check_bmps(pAdapter);
20296 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020297}
20298
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020299#if TDLS_MGMT_VERSION2
20300static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20301 u8 *peer, u8 action_code, u8 dialog_token,
20302 u16 status_code, u32 peer_capability,
20303 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020304#else /* TDLS_MGMT_VERSION2 */
20305#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20306static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20307 struct net_device *dev,
20308 const u8 *peer, u8 action_code,
20309 u8 dialog_token, u16 status_code,
20310 u32 peer_capability, bool initiator,
20311 const u8 *buf, size_t len)
20312#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20313static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20314 struct net_device *dev,
20315 const u8 *peer, u8 action_code,
20316 u8 dialog_token, u16 status_code,
20317 u32 peer_capability, const u8 *buf,
20318 size_t len)
20319#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20320static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20321 struct net_device *dev,
20322 u8 *peer, u8 action_code,
20323 u8 dialog_token,
20324 u16 status_code, u32 peer_capability,
20325 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020326#else
20327static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20328 u8 *peer, u8 action_code, u8 dialog_token,
20329 u16 status_code, const u8 *buf, size_t len)
20330#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020331#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020332{
20333 int ret;
20334
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020335 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020336#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020337 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20338 dialog_token, status_code,
20339 peer_capability, buf, len);
20340#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020341#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20342 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020343 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20344 dialog_token, status_code,
20345 peer_capability, initiator,
20346 buf, len);
20347#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20348 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20349 dialog_token, status_code,
20350 peer_capability, buf, len);
20351#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20352 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20353 dialog_token, status_code,
20354 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020355#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020356 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20357 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020358#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020359#endif
20360 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020361
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020362 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020363}
Atul Mittal115287b2014-07-08 13:26:33 +053020364
20365int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020366#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20367 const u8 *peer,
20368#else
Atul Mittal115287b2014-07-08 13:26:33 +053020369 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020370#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020371 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053020372 cfg80211_exttdls_callback callback)
20373{
20374
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020375 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053020376 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020377 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053020378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20379 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
20380 __func__, MAC_ADDR_ARRAY(peer));
20381
20382 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20383 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20384
20385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020386 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20387 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20388 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020389 return -ENOTSUPP;
20390 }
20391
20392 /* To cater the requirement of establishing the TDLS link
20393 * irrespective of the data traffic , get an entry of TDLS peer.
20394 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020395 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020396 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
20397 if (pTdlsPeer == NULL) {
20398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20399 "%s: peer " MAC_ADDRESS_STR " not existing",
20400 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020401 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020402 return -EINVAL;
20403 }
20404
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020405 /* check FW TDLS Off Channel capability */
20406 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020407 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020408 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020409 {
20410 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
20411 pTdlsPeer->peerParams.global_operating_class =
20412 tdls_peer_params->global_operating_class;
20413 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
20414 pTdlsPeer->peerParams.min_bandwidth_kbps =
20415 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020416 /* check configured channel is valid, non dfs and
20417 * not current operating channel */
20418 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
20419 tdls_peer_params->channel)) &&
20420 (pHddStaCtx) &&
20421 (tdls_peer_params->channel !=
20422 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020423 {
20424 pTdlsPeer->isOffChannelConfigured = TRUE;
20425 }
20426 else
20427 {
20428 pTdlsPeer->isOffChannelConfigured = FALSE;
20429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20430 "%s: Configured Tdls Off Channel is not valid", __func__);
20431
20432 }
20433 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020434 "%s: tdls_off_channel %d isOffChannelConfigured %d "
20435 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020436 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020437 pTdlsPeer->isOffChannelConfigured,
20438 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020439 }
20440 else
20441 {
20442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020443 "%s: TDLS off channel FW capability %d, "
20444 "host capab %d or Invalid TDLS Peer Params", __func__,
20445 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
20446 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020447 }
20448
Atul Mittal115287b2014-07-08 13:26:33 +053020449 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
20450
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020451 mutex_unlock(&pHddCtx->tdls_lock);
20452
Atul Mittal115287b2014-07-08 13:26:33 +053020453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20454 " %s TDLS Add Force Peer Failed",
20455 __func__);
20456 return -EINVAL;
20457 }
20458 /*EXT TDLS*/
20459
20460 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020461 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020462 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20463 " %s TDLS set callback Failed",
20464 __func__);
20465 return -EINVAL;
20466 }
20467
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020468 mutex_unlock(&pHddCtx->tdls_lock);
20469
Atul Mittal115287b2014-07-08 13:26:33 +053020470 return(0);
20471
20472}
20473
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020474int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
20475#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20476 const u8 *peer
20477#else
20478 u8 *peer
20479#endif
20480)
Atul Mittal115287b2014-07-08 13:26:33 +053020481{
20482
20483 hddTdlsPeer_t *pTdlsPeer;
20484 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020485
Atul Mittal115287b2014-07-08 13:26:33 +053020486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20487 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
20488 __func__, MAC_ADDR_ARRAY(peer));
20489
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020490 if (0 != wlan_hdd_validate_context(pHddCtx)) {
20491 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
20492 return -EINVAL;
20493 }
20494
Atul Mittal115287b2014-07-08 13:26:33 +053020495 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20496 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20497
20498 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020499 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20500 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20501 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020502 return -ENOTSUPP;
20503 }
20504
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020505 mutex_lock(&pHddCtx->tdls_lock);
20506 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053020507
20508 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020509 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020510 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020511 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053020512 __func__, MAC_ADDR_ARRAY(peer));
20513 return -EINVAL;
20514 }
20515 else {
20516 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
20517 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020518 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
20519 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020520 /* if channel switch is configured, reset
20521 the channel for this peer */
20522 if (TRUE == pTdlsPeer->isOffChannelConfigured)
20523 {
20524 pTdlsPeer->peerParams.channel = 0;
20525 pTdlsPeer->isOffChannelConfigured = FALSE;
20526 }
Atul Mittal115287b2014-07-08 13:26:33 +053020527 }
20528
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020529 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020530 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020531 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053020532 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020533 }
Atul Mittal115287b2014-07-08 13:26:33 +053020534
20535 /*EXT TDLS*/
20536
20537 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020538 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20540 " %s TDLS set callback Failed",
20541 __func__);
20542 return -EINVAL;
20543 }
Atul Mittal115287b2014-07-08 13:26:33 +053020544
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020545 mutex_unlock(&pHddCtx->tdls_lock);
20546
20547 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053020548}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020549static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020550#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20551 const u8 *peer,
20552#else
20553 u8 *peer,
20554#endif
20555 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020556{
20557 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20558 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020559 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020560 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020561
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020562 ENTER();
20563
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020564 if (!pAdapter) {
20565 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
20566 return -EINVAL;
20567 }
20568
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020569 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20570 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
20571 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020572 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020573 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070020575 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020576 return -EINVAL;
20577 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020578
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020579 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020580 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020581 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020582 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020583 }
20584
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020585
20586 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020587 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020588 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020589 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020590 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
20591 "Cannot process TDLS commands",
20592 pHddCtx->cfg_ini->fEnableTDLSSupport,
20593 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020594 return -ENOTSUPP;
20595 }
20596
20597 switch (oper) {
20598 case NL80211_TDLS_ENABLE_LINK:
20599 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020600 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020601 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053020602 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
20603 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053020604 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020605 tANI_U16 numCurrTdlsPeers = 0;
20606 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020607 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020608 tSirMacAddr peerMac;
20609 int channel;
20610 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020611
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20613 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
20614 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020615
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020616 mutex_lock(&pHddCtx->tdls_lock);
20617 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020618 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053020619 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020620 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020621 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20622 " (oper %d) not exsting. ignored",
20623 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20624 return -EINVAL;
20625 }
20626
20627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20628 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20629 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20630 "NL80211_TDLS_ENABLE_LINK");
20631
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020632 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
20633 {
20634 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
20635 MAC_ADDRESS_STR " failed",
20636 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020637 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020638 return -EINVAL;
20639 }
20640
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020641 /* before starting tdls connection, set tdls
20642 * off channel established status to default value */
20643 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020644
20645 mutex_unlock(&pHddCtx->tdls_lock);
20646
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053020647 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020648 /* TDLS Off Channel, Disable tdls channel switch,
20649 when there are more than one tdls link */
20650 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053020651 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020652 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020653 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020654 /* get connected peer and send disable tdls off chan */
20655 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020656 if ((connPeer) &&
20657 (connPeer->isOffChannelSupported == TRUE) &&
20658 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020659 {
20660 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20661 "%s: More then one peer connected, Disable "
20662 "TDLS channel switch", __func__);
20663
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020664 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020665 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
20666 channel = connPeer->peerParams.channel;
20667
20668 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020669
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020670 ret = sme_SendTdlsChanSwitchReq(
20671 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020672 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020673 peerMac,
20674 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020675 TDLS_OFF_CHANNEL_BW_OFFSET,
20676 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020677 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020678 hddLog(VOS_TRACE_LEVEL_ERROR,
20679 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020680 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020681 }
20682 else
20683 {
20684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20685 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020686 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020687 "isOffChannelConfigured %d",
20688 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020689 (connPeer ? (connPeer->isOffChannelSupported)
20690 : -1),
20691 (connPeer ? (connPeer->isOffChannelConfigured)
20692 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020693 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020694 }
20695 }
20696
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020697 mutex_lock(&pHddCtx->tdls_lock);
20698 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20699 if ( NULL == pTdlsPeer ) {
20700 mutex_unlock(&pHddCtx->tdls_lock);
20701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20702 "%s: " MAC_ADDRESS_STR
20703 " (oper %d) peer got freed in other context. ignored",
20704 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20705 return -EINVAL;
20706 }
20707 peer_status = pTdlsPeer->link_status;
20708 mutex_unlock(&pHddCtx->tdls_lock);
20709
20710 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020711 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020712 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053020713
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020714 if (0 != wlan_hdd_tdls_get_link_establish_params(
20715 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020716 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020717 return -EINVAL;
20718 }
20719 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020720
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020721 ret = sme_SendTdlsLinkEstablishParams(
20722 WLAN_HDD_GET_HAL_CTX(pAdapter),
20723 pAdapter->sessionId, peer,
20724 &tdlsLinkEstablishParams);
20725 if (ret != VOS_STATUS_SUCCESS) {
20726 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
20727 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020728 /* Send TDLS peer UAPSD capabilities to the firmware and
20729 * register with the TL on after the response for this operation
20730 * is received .
20731 */
20732 ret = wait_for_completion_interruptible_timeout(
20733 &pAdapter->tdls_link_establish_req_comp,
20734 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053020735
20736 mutex_lock(&pHddCtx->tdls_lock);
20737 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20738 if ( NULL == pTdlsPeer ) {
20739 mutex_unlock(&pHddCtx->tdls_lock);
20740 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20741 "%s %d: " MAC_ADDRESS_STR
20742 " (oper %d) peer got freed in other context. ignored",
20743 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
20744 (int)oper);
20745 return -EINVAL;
20746 }
20747 peer_status = pTdlsPeer->link_status;
20748 mutex_unlock(&pHddCtx->tdls_lock);
20749
20750 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020751 {
20752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020753 FL("Link Establish Request Failed Status %ld"),
20754 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020755 return -EINVAL;
20756 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020757 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020758
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020759 mutex_lock(&pHddCtx->tdls_lock);
20760 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20761 if ( NULL == pTdlsPeer ) {
20762 mutex_unlock(&pHddCtx->tdls_lock);
20763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20764 "%s: " MAC_ADDRESS_STR
20765 " (oper %d) peer got freed in other context. ignored",
20766 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20767 return -EINVAL;
20768 }
20769
Atul Mittal115287b2014-07-08 13:26:33 +053020770 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20771 eTDLS_LINK_CONNECTED,
20772 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020773 staDesc.ucSTAId = pTdlsPeer->staId;
20774 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053020775
20776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20777 "%s: tdlsLinkEstablishParams of peer "
20778 MAC_ADDRESS_STR "uapsdQueues: %d"
20779 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
20780 "isResponder: %d peerstaId: %d",
20781 __func__,
20782 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
20783 tdlsLinkEstablishParams.uapsdQueues,
20784 tdlsLinkEstablishParams.qos,
20785 tdlsLinkEstablishParams.maxSp,
20786 tdlsLinkEstablishParams.isBufSta,
20787 tdlsLinkEstablishParams.isOffChannelSupported,
20788 tdlsLinkEstablishParams.isResponder,
20789 pTdlsPeer->staId);
20790
20791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20792 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
20793 __func__,
20794 staDesc.ucSTAId,
20795 staDesc.ucQosEnabled);
20796
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020797 ret = WLANTL_UpdateTdlsSTAClient(
20798 pHddCtx->pvosContext,
20799 &staDesc);
20800 if (ret != VOS_STATUS_SUCCESS) {
20801 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
20802 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053020803
Gopichand Nakkala471708b2013-06-04 20:03:01 +053020804 /* Mark TDLS client Authenticated .*/
20805 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
20806 pTdlsPeer->staId,
20807 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020808 if (VOS_STATUS_SUCCESS == status)
20809 {
Hoonki Lee14621352013-04-16 17:51:19 -070020810 if (pTdlsPeer->is_responder == 0)
20811 {
20812 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020813 tdlsConnInfo_t *tdlsInfo;
20814
20815 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
20816
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020817 if (!vos_timer_is_initialized(
20818 &pTdlsPeer->initiatorWaitTimeoutTimer))
20819 {
20820 /* Initialize initiator wait callback */
20821 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020822 &pTdlsPeer->initiatorWaitTimeoutTimer,
20823 VOS_TIMER_TYPE_SW,
20824 wlan_hdd_tdls_initiator_wait_cb,
20825 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020826 }
Hoonki Lee14621352013-04-16 17:51:19 -070020827 wlan_hdd_tdls_timer_restart(pAdapter,
20828 &pTdlsPeer->initiatorWaitTimeoutTimer,
20829 WAIT_TIME_TDLS_INITIATOR);
20830 /* suspend initiator TX until it receives direct packet from the
20831 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020832 ret = WLANTL_SuspendDataTx(
20833 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20834 &staId, NULL);
20835 if (ret != VOS_STATUS_SUCCESS) {
20836 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20837 }
Hoonki Lee14621352013-04-16 17:51:19 -070020838 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020839
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020840 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020841 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020842 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020843 suppChannelLen =
20844 tdlsLinkEstablishParams.supportedChannelsLen;
20845
20846 if ((suppChannelLen > 0) &&
20847 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20848 {
20849 tANI_U8 suppPeerChannel = 0;
20850 int i = 0;
20851 for (i = 0U; i < suppChannelLen; i++)
20852 {
20853 suppPeerChannel =
20854 tdlsLinkEstablishParams.supportedChannels[i];
20855
20856 pTdlsPeer->isOffChannelSupported = FALSE;
20857 if (suppPeerChannel ==
20858 pTdlsPeer->peerParams.channel)
20859 {
20860 pTdlsPeer->isOffChannelSupported = TRUE;
20861 break;
20862 }
20863 }
20864 }
20865 else
20866 {
20867 pTdlsPeer->isOffChannelSupported = FALSE;
20868 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020869 }
20870 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20871 "%s: TDLS channel switch request for channel "
20872 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020873 "%d isOffChannelSupported %d", __func__,
20874 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020875 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020876 suppChannelLen,
20877 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020878
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020879 /* TDLS Off Channel, Enable tdls channel switch,
20880 when their is only one tdls link and it supports */
20881 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20882 if ((numCurrTdlsPeers == 1) &&
20883 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20884 (TRUE == pTdlsPeer->isOffChannelConfigured))
20885 {
20886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20887 "%s: Send TDLS channel switch request for channel %d",
20888 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020889
20890 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020891 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20892 channel = pTdlsPeer->peerParams.channel;
20893
20894 mutex_unlock(&pHddCtx->tdls_lock);
20895
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020896 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20897 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020898 peerMac,
20899 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020900 TDLS_OFF_CHANNEL_BW_OFFSET,
20901 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020902 if (ret != VOS_STATUS_SUCCESS) {
20903 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20904 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020905 }
20906 else
20907 {
20908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20909 "%s: TDLS channel switch request not sent"
20910 " numCurrTdlsPeers %d "
20911 "isOffChannelSupported %d "
20912 "isOffChannelConfigured %d",
20913 __func__, numCurrTdlsPeers,
20914 pTdlsPeer->isOffChannelSupported,
20915 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020916 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020917 }
20918
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020919 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020920 else
20921 mutex_unlock(&pHddCtx->tdls_lock);
20922
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020923 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020924
20925 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020926 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
20927 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020928 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020929 int ac;
20930 uint8 ucAc[4] = { WLANTL_AC_VO,
20931 WLANTL_AC_VI,
20932 WLANTL_AC_BK,
20933 WLANTL_AC_BE };
20934 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
20935 for(ac=0; ac < 4; ac++)
20936 {
20937 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20938 pTdlsPeer->staId, ucAc[ac],
20939 tlTid[ac], tlTid[ac], 0, 0,
20940 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020941 if (status != VOS_STATUS_SUCCESS) {
20942 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
20943 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020944 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020945 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020946 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020947
Bhargav Shah66896792015-10-01 18:17:37 +053020948 /* stop TCP delack timer if TDLS is enable */
20949 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20950 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053020951 hdd_wlan_tdls_enable_link_event(peer,
20952 pTdlsPeer->isOffChannelSupported,
20953 pTdlsPeer->isOffChannelConfigured,
20954 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020955 }
20956 break;
20957 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080020958 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020959 tANI_U16 numCurrTdlsPeers = 0;
20960 hddTdlsPeer_t *connPeer = NULL;
20961
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020962 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20963 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
20964 __func__, MAC_ADDR_ARRAY(peer));
20965
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020966 mutex_lock(&pHddCtx->tdls_lock);
20967 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020968
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020969
Sunil Dutt41de4e22013-11-14 18:09:02 +053020970 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020971 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020972 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20973 " (oper %d) not exsting. ignored",
20974 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20975 return -EINVAL;
20976 }
20977
20978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20979 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20980 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20981 "NL80211_TDLS_DISABLE_LINK");
20982
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020983 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080020984 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020985 long status;
20986
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020987 /* set tdls off channel status to false for this peer */
20988 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053020989 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20990 eTDLS_LINK_TEARING,
20991 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
20992 eTDLS_LINK_UNSPECIFIED:
20993 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020994 mutex_unlock(&pHddCtx->tdls_lock);
20995
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020996 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
20997
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020998 status = sme_DeleteTdlsPeerSta(
20999 WLAN_HDD_GET_HAL_CTX(pAdapter),
21000 pAdapter->sessionId, peer );
21001 if (status != VOS_STATUS_SUCCESS) {
21002 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
21003 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021004
21005 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
21006 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021007
21008 mutex_lock(&pHddCtx->tdls_lock);
21009 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21010 if ( NULL == pTdlsPeer ) {
21011 mutex_unlock(&pHddCtx->tdls_lock);
21012 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21013 " peer was freed in other context",
21014 __func__, MAC_ADDR_ARRAY(peer));
21015 return -EINVAL;
21016 }
21017
Atul Mittal271a7652014-09-12 13:18:22 +053021018 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053021019 eTDLS_LINK_IDLE,
21020 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021021 mutex_unlock(&pHddCtx->tdls_lock);
21022
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021023 if (status <= 0)
21024 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021025 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21026 "%s: Del station failed status %ld",
21027 __func__, status);
21028 return -EPERM;
21029 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021030
21031 /* TDLS Off Channel, Enable tdls channel switch,
21032 when their is only one tdls link and it supports */
21033 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
21034 if (numCurrTdlsPeers == 1)
21035 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021036 tSirMacAddr peerMac;
21037 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021038
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021039 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021040 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021041
21042 if (connPeer == NULL) {
21043 mutex_unlock(&pHddCtx->tdls_lock);
21044 hddLog(VOS_TRACE_LEVEL_ERROR,
21045 "%s connPeer is NULL", __func__);
21046 return -EINVAL;
21047 }
21048
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021049 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
21050 channel = connPeer->peerParams.channel;
21051
21052 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21053 "%s: TDLS channel switch "
21054 "isOffChannelSupported %d "
21055 "isOffChannelConfigured %d "
21056 "isOffChannelEstablished %d",
21057 __func__,
21058 (connPeer ? connPeer->isOffChannelSupported : -1),
21059 (connPeer ? connPeer->isOffChannelConfigured : -1),
21060 (connPeer ? connPeer->isOffChannelEstablished : -1));
21061
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021062 if ((connPeer) &&
21063 (connPeer->isOffChannelSupported == TRUE) &&
21064 (connPeer->isOffChannelConfigured == TRUE))
21065 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053021066 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021067 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021068 status = sme_SendTdlsChanSwitchReq(
21069 WLAN_HDD_GET_HAL_CTX(pAdapter),
21070 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021071 peerMac,
21072 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021073 TDLS_OFF_CHANNEL_BW_OFFSET,
21074 TDLS_CHANNEL_SWITCH_ENABLE);
21075 if (status != VOS_STATUS_SUCCESS) {
21076 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
21077 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021078 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021079 else
21080 mutex_unlock(&pHddCtx->tdls_lock);
21081 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021082 else
21083 {
21084 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21085 "%s: TDLS channel switch request not sent "
21086 "numCurrTdlsPeers %d ",
21087 __func__, numCurrTdlsPeers);
21088 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021089 }
21090 else
21091 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021092 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021093 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21094 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080021095 }
Bhargav Shah66896792015-10-01 18:17:37 +053021096 if (numCurrTdlsPeers == 0) {
21097 /* start TCP delack timer if TDLS is disable */
21098 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21099 hdd_manage_delack_timer(pHddCtx);
21100 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021101 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021102 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021103 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021104 {
Atul Mittal115287b2014-07-08 13:26:33 +053021105 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021106
Atul Mittal115287b2014-07-08 13:26:33 +053021107 if (0 != status)
21108 {
21109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021110 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053021111 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021112 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053021113 break;
21114 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021115 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021116 {
Atul Mittal115287b2014-07-08 13:26:33 +053021117 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
21118 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021119 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053021120 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021121
Atul Mittal115287b2014-07-08 13:26:33 +053021122 if (0 != status)
21123 {
21124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021125 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053021126 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053021127 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053021128 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021129 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021130 case NL80211_TDLS_DISCOVERY_REQ:
21131 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021132 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021133 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021134 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021135 return -ENOTSUPP;
21136 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21138 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021139 return -ENOTSUPP;
21140 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021141
21142 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021143 return 0;
21144}
Chilam NG571c65a2013-01-19 12:27:36 +053021145
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021146static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021147#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
21148 const u8 *peer,
21149#else
21150 u8 *peer,
21151#endif
21152 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021153{
21154 int ret;
21155
21156 vos_ssr_protect(__func__);
21157 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
21158 vos_ssr_unprotect(__func__);
21159
21160 return ret;
21161}
21162
Chilam NG571c65a2013-01-19 12:27:36 +053021163int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
21164 struct net_device *dev, u8 *peer)
21165{
Arif Hussaina7c8e412013-11-20 11:06:42 -080021166 hddLog(VOS_TRACE_LEVEL_INFO,
21167 "tdls send discover req: "MAC_ADDRESS_STR,
21168 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021169#if TDLS_MGMT_VERSION2
21170 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21171 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21172#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021173#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
21174 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21175 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
21176#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
21177 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21178 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21179#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
21180 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21181 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21182#else
Chilam NG571c65a2013-01-19 12:27:36 +053021183 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21184 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021185#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021186#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053021187}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021188#endif
21189
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021190#ifdef WLAN_FEATURE_GTK_OFFLOAD
21191/*
21192 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
21193 * Callback rountine called upon receiving response for
21194 * get offload info
21195 */
21196void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
21197 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
21198{
21199
21200 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021201 tANI_U8 tempReplayCounter[8];
21202 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021203
21204 ENTER();
21205
21206 if (NULL == pAdapter)
21207 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053021208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021209 "%s: HDD adapter is Null", __func__);
21210 return ;
21211 }
21212
21213 if (NULL == pGtkOffloadGetInfoRsp)
21214 {
21215 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21216 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
21217 return ;
21218 }
21219
21220 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
21221 {
21222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21223 "%s: wlan Failed to get replay counter value",
21224 __func__);
21225 return ;
21226 }
21227
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021228 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21229 /* Update replay counter */
21230 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
21231 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21232
21233 {
21234 /* changing from little to big endian since supplicant
21235 * works on big endian format
21236 */
21237 int i;
21238 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21239
21240 for (i = 0; i < 8; i++)
21241 {
21242 tempReplayCounter[7-i] = (tANI_U8)p[i];
21243 }
21244 }
21245
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021246 /* Update replay counter to NL */
21247 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021248 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021249}
21250
21251/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021252 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021253 * This function is used to offload GTK rekeying job to the firmware.
21254 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021255int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021256 struct cfg80211_gtk_rekey_data *data)
21257{
21258 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21259 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21260 hdd_station_ctx_t *pHddStaCtx;
21261 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021262 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021263 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021264 eHalStatus status = eHAL_STATUS_FAILURE;
21265
21266 ENTER();
21267
21268 if (NULL == pAdapter)
21269 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053021270 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021271 "%s: HDD adapter is Null", __func__);
21272 return -ENODEV;
21273 }
21274
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053021275 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21276 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
21277 pAdapter->sessionId, pAdapter->device_mode));
21278
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021279 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021280 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021281 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021282 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021283 }
21284
21285 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21286 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
21287 if (NULL == hHal)
21288 {
21289 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21290 "%s: HAL context is Null!!!", __func__);
21291 return -EAGAIN;
21292 }
21293
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021294 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
21295 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
21296 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
21297 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021298 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021299 {
21300 /* changing from big to little endian since driver
21301 * works on little endian format
21302 */
21303 tANI_U8 *p =
21304 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
21305 int i;
21306
21307 for (i = 0; i < 8; i++)
21308 {
21309 p[7-i] = data->replay_ctr[i];
21310 }
21311 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021312
21313 if (TRUE == pHddCtx->hdd_wlan_suspended)
21314 {
21315 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021316 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
21317 sizeof (tSirGtkOffloadParams));
21318 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021319 pAdapter->sessionId);
21320
21321 if (eHAL_STATUS_SUCCESS != status)
21322 {
21323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21324 "%s: sme_SetGTKOffload failed, returned %d",
21325 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021326
21327 /* Need to clear any trace of key value in the memory.
21328 * Thus zero out the memory even though it is local
21329 * variable.
21330 */
21331 vos_mem_zero(&hddGtkOffloadReqParams,
21332 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021333 return status;
21334 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21336 "%s: sme_SetGTKOffload successfull", __func__);
21337 }
21338 else
21339 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21341 "%s: wlan not suspended GTKOffload request is stored",
21342 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021343 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021344
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021345 /* Need to clear any trace of key value in the memory.
21346 * Thus zero out the memory even though it is local
21347 * variable.
21348 */
21349 vos_mem_zero(&hddGtkOffloadReqParams,
21350 sizeof(hddGtkOffloadReqParams));
21351
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021352 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021353 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021354}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021355
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021356int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
21357 struct cfg80211_gtk_rekey_data *data)
21358{
21359 int ret;
21360
21361 vos_ssr_protect(__func__);
21362 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
21363 vos_ssr_unprotect(__func__);
21364
21365 return ret;
21366}
21367#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021368/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021369 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021370 * This function is used to set access control policy
21371 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021372static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21373 struct net_device *dev,
21374 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021375{
21376 int i;
21377 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21378 hdd_hostapd_state_t *pHostapdState;
21379 tsap_Config_t *pConfig;
21380 v_CONTEXT_t pVosContext = NULL;
21381 hdd_context_t *pHddCtx;
21382 int status;
21383
21384 ENTER();
21385
21386 if (NULL == pAdapter)
21387 {
21388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21389 "%s: HDD adapter is Null", __func__);
21390 return -ENODEV;
21391 }
21392
21393 if (NULL == params)
21394 {
21395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21396 "%s: params is Null", __func__);
21397 return -EINVAL;
21398 }
21399
21400 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21401 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021402 if (0 != status)
21403 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021404 return status;
21405 }
21406
21407 pVosContext = pHddCtx->pvosContext;
21408 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
21409
21410 if (NULL == pHostapdState)
21411 {
21412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21413 "%s: pHostapdState is Null", __func__);
21414 return -EINVAL;
21415 }
21416
21417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
21418 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021419 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21420 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
21421 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021422
21423 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
21424 {
21425 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
21426
21427 /* default value */
21428 pConfig->num_accept_mac = 0;
21429 pConfig->num_deny_mac = 0;
21430
21431 /**
21432 * access control policy
21433 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
21434 * listed in hostapd.deny file.
21435 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
21436 * listed in hostapd.accept file.
21437 */
21438 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
21439 {
21440 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
21441 }
21442 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
21443 {
21444 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
21445 }
21446 else
21447 {
21448 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21449 "%s:Acl Policy : %d is not supported",
21450 __func__, params->acl_policy);
21451 return -ENOTSUPP;
21452 }
21453
21454 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
21455 {
21456 pConfig->num_accept_mac = params->n_acl_entries;
21457 for (i = 0; i < params->n_acl_entries; i++)
21458 {
21459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21460 "** Add ACL MAC entry %i in WhiletList :"
21461 MAC_ADDRESS_STR, i,
21462 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21463
21464 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
21465 sizeof(qcmacaddr));
21466 }
21467 }
21468 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
21469 {
21470 pConfig->num_deny_mac = params->n_acl_entries;
21471 for (i = 0; i < params->n_acl_entries; i++)
21472 {
21473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21474 "** Add ACL MAC entry %i in BlackList :"
21475 MAC_ADDRESS_STR, i,
21476 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21477
21478 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
21479 sizeof(qcmacaddr));
21480 }
21481 }
21482
21483 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
21484 {
21485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21486 "%s: SAP Set Mac Acl fail", __func__);
21487 return -EINVAL;
21488 }
21489 }
21490 else
21491 {
21492 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053021493 "%s: Invalid device_mode = %s (%d)",
21494 __func__, hdd_device_modetoString(pAdapter->device_mode),
21495 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021496 return -EINVAL;
21497 }
21498
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021499 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021500 return 0;
21501}
21502
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021503static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21504 struct net_device *dev,
21505 const struct cfg80211_acl_data *params)
21506{
21507 int ret;
21508 vos_ssr_protect(__func__);
21509 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
21510 vos_ssr_unprotect(__func__);
21511
21512 return ret;
21513}
21514
Leo Chang9056f462013-08-01 19:21:11 -070021515#ifdef WLAN_NL80211_TESTMODE
21516#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070021517void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070021518(
21519 void *pAdapter,
21520 void *indCont
21521)
21522{
Leo Changd9df8aa2013-09-26 13:32:26 -070021523 tSirLPHBInd *lphbInd;
21524 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053021525 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070021526
21527 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021528 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070021529
c_hpothu73f35e62014-04-18 13:40:08 +053021530 if (pAdapter == NULL)
21531 {
21532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21533 "%s: pAdapter is NULL\n",__func__);
21534 return;
21535 }
21536
Leo Chang9056f462013-08-01 19:21:11 -070021537 if (NULL == indCont)
21538 {
21539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021540 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070021541 return;
21542 }
21543
c_hpothu73f35e62014-04-18 13:40:08 +053021544 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070021545 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070021546 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053021547 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070021548 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070021549 GFP_ATOMIC);
21550 if (!skb)
21551 {
21552 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21553 "LPHB timeout, NL buffer alloc fail");
21554 return;
21555 }
21556
Leo Changac3ba772013-10-07 09:47:04 -070021557 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070021558 {
21559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21560 "WLAN_HDD_TM_ATTR_CMD put fail");
21561 goto nla_put_failure;
21562 }
Leo Changac3ba772013-10-07 09:47:04 -070021563 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070021564 {
21565 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21566 "WLAN_HDD_TM_ATTR_TYPE put fail");
21567 goto nla_put_failure;
21568 }
Leo Changac3ba772013-10-07 09:47:04 -070021569 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070021570 sizeof(tSirLPHBInd), lphbInd))
21571 {
21572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21573 "WLAN_HDD_TM_ATTR_DATA put fail");
21574 goto nla_put_failure;
21575 }
Leo Chang9056f462013-08-01 19:21:11 -070021576 cfg80211_testmode_event(skb, GFP_ATOMIC);
21577 return;
21578
21579nla_put_failure:
21580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21581 "NLA Put fail");
21582 kfree_skb(skb);
21583
21584 return;
21585}
21586#endif /* FEATURE_WLAN_LPHB */
21587
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021588static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070021589{
21590 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
21591 int err = 0;
21592#ifdef FEATURE_WLAN_LPHB
21593 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070021594 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021595
21596 ENTER();
21597
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021598 err = wlan_hdd_validate_context(pHddCtx);
21599 if (0 != err)
21600 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021601 return err;
21602 }
Leo Chang9056f462013-08-01 19:21:11 -070021603#endif /* FEATURE_WLAN_LPHB */
21604
21605 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
21606 if (err)
21607 {
21608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21609 "%s Testmode INV ATTR", __func__);
21610 return err;
21611 }
21612
21613 if (!tb[WLAN_HDD_TM_ATTR_CMD])
21614 {
21615 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21616 "%s Testmode INV CMD", __func__);
21617 return -EINVAL;
21618 }
21619
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021620 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21621 TRACE_CODE_HDD_CFG80211_TESTMODE,
21622 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070021623 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
21624 {
21625#ifdef FEATURE_WLAN_LPHB
21626 /* Low Power Heartbeat configuration request */
21627 case WLAN_HDD_TM_CMD_WLAN_HB:
21628 {
21629 int buf_len;
21630 void *buf;
21631 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080021632 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070021633
21634 if (!tb[WLAN_HDD_TM_ATTR_DATA])
21635 {
21636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21637 "%s Testmode INV DATA", __func__);
21638 return -EINVAL;
21639 }
21640
21641 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
21642 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080021643
Manjeet Singh3c577442017-02-10 19:03:38 +053021644 if (buf_len > sizeof(*hb_params)) {
21645 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
21646 buf_len);
21647 return -ERANGE;
21648 }
21649
Amar Singhal05852702014-02-04 14:40:00 -080021650 hb_params_temp =(tSirLPHBReq *)buf;
21651 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
21652 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
21653 return -EINVAL;
21654
Leo Chang9056f462013-08-01 19:21:11 -070021655 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
21656 if (NULL == hb_params)
21657 {
21658 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21659 "%s Request Buffer Alloc Fail", __func__);
21660 return -EINVAL;
21661 }
21662
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053021663 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070021664 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070021665 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
21666 hb_params,
21667 wlan_hdd_cfg80211_lphb_ind_handler);
21668 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070021669 {
Leo Changd9df8aa2013-09-26 13:32:26 -070021670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21671 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070021672 vos_mem_free(hb_params);
21673 }
Leo Chang9056f462013-08-01 19:21:11 -070021674 return 0;
21675 }
21676#endif /* FEATURE_WLAN_LPHB */
21677 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21679 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070021680 return -EOPNOTSUPP;
21681 }
21682
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021683 EXIT();
21684 return err;
Leo Chang9056f462013-08-01 19:21:11 -070021685}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021686
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053021687static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
21688#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
21689 struct wireless_dev *wdev,
21690#endif
21691 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021692{
21693 int ret;
21694
21695 vos_ssr_protect(__func__);
21696 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
21697 vos_ssr_unprotect(__func__);
21698
21699 return ret;
21700}
Leo Chang9056f462013-08-01 19:21:11 -070021701#endif /* CONFIG_NL80211_TESTMODE */
21702
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021703extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021704static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021705 struct net_device *dev,
21706 int idx, struct survey_info *survey)
21707{
21708 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21709 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053021710 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021711 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053021712 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021713 v_S7_t snr,rssi;
21714 int status, i, j, filled = 0;
21715
21716 ENTER();
21717
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021718 if (NULL == pAdapter)
21719 {
21720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21721 "%s: HDD adapter is Null", __func__);
21722 return -ENODEV;
21723 }
21724
21725 if (NULL == wiphy)
21726 {
21727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21728 "%s: wiphy is Null", __func__);
21729 return -ENODEV;
21730 }
21731
21732 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21733 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021734 if (0 != status)
21735 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021736 return status;
21737 }
21738
Mihir Sheted9072e02013-08-21 17:02:29 +053021739 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21740
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021741 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053021742 0 != pAdapter->survey_idx ||
21743 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021744 {
21745 /* The survey dump ops when implemented completely is expected to
21746 * return a survey of all channels and the ops is called by the
21747 * kernel with incremental values of the argument 'idx' till it
21748 * returns -ENONET. But we can only support the survey for the
21749 * operating channel for now. survey_idx is used to track
21750 * that the ops is called only once and then return -ENONET for
21751 * the next iteration
21752 */
21753 pAdapter->survey_idx = 0;
21754 return -ENONET;
21755 }
21756
Mukul Sharma9d5233b2015-06-11 20:28:20 +053021757 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
21758 {
21759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21760 "%s: Roaming in progress, hence return ", __func__);
21761 return -ENONET;
21762 }
21763
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021764 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
21765
21766 wlan_hdd_get_snr(pAdapter, &snr);
21767 wlan_hdd_get_rssi(pAdapter, &rssi);
21768
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021769 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21770 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
21771 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021772 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
21773 hdd_wlan_get_freq(channel, &freq);
21774
21775
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053021776 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021777 {
21778 if (NULL == wiphy->bands[i])
21779 {
21780 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
21781 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
21782 continue;
21783 }
21784
21785 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
21786 {
21787 struct ieee80211_supported_band *band = wiphy->bands[i];
21788
21789 if (band->channels[j].center_freq == (v_U16_t)freq)
21790 {
21791 survey->channel = &band->channels[j];
21792 /* The Rx BDs contain SNR values in dB for the received frames
21793 * while the supplicant expects noise. So we calculate and
21794 * return the value of noise (dBm)
21795 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
21796 */
21797 survey->noise = rssi - snr;
21798 survey->filled = SURVEY_INFO_NOISE_DBM;
21799 filled = 1;
21800 }
21801 }
21802 }
21803
21804 if (filled)
21805 pAdapter->survey_idx = 1;
21806 else
21807 {
21808 pAdapter->survey_idx = 0;
21809 return -ENONET;
21810 }
21811
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021812 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021813 return 0;
21814}
21815
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021816static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
21817 struct net_device *dev,
21818 int idx, struct survey_info *survey)
21819{
21820 int ret;
21821
21822 vos_ssr_protect(__func__);
21823 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
21824 vos_ssr_unprotect(__func__);
21825
21826 return ret;
21827}
21828
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021829/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021830 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021831 * this is called when cfg80211 driver resume
21832 * driver updates latest sched_scan scan result(if any) to cfg80211 database
21833 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021834int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021835{
21836 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21837 hdd_adapter_t *pAdapter;
21838 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21839 VOS_STATUS status = VOS_STATUS_SUCCESS;
21840
21841 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021842
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021843 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021844 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021845 return 0;
21846 }
21847
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021848 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21849 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021850
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021851 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021852 {
21853 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21854 "%s: Resume SoftAP", __func__);
21855 hdd_set_wlan_suspend_mode(false);
21856 }
21857
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021858 spin_lock(&pHddCtx->schedScan_lock);
21859 pHddCtx->isWiphySuspended = FALSE;
21860 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21861 {
21862 spin_unlock(&pHddCtx->schedScan_lock);
21863 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21864 "%s: Return resume is not due to PNO indication", __func__);
21865 return 0;
21866 }
21867 // Reset flag to avoid updatating cfg80211 data old results again
21868 pHddCtx->isSchedScanUpdatePending = FALSE;
21869 spin_unlock(&pHddCtx->schedScan_lock);
21870
21871 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21872
21873 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21874 {
21875 pAdapter = pAdapterNode->pAdapter;
21876 if ( (NULL != pAdapter) &&
21877 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21878 {
21879 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021880 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021881 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21882 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021883 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021884 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021885 {
21886 /* Acquire wakelock to handle the case where APP's tries to
21887 * suspend immediately after updating the scan results. Whis
21888 * results in app's is in suspended state and not able to
21889 * process the connect request to AP
21890 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021891 hdd_prevent_suspend_timeout(2000,
21892 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021893 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021894 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021895
21896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21897 "%s : cfg80211 scan result database updated", __func__);
21898
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021899 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021900 return 0;
21901
21902 }
21903 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21904 pAdapterNode = pNext;
21905 }
21906
21907 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21908 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021909 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021910 return 0;
21911}
21912
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021913int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21914{
21915 int ret;
21916
21917 vos_ssr_protect(__func__);
21918 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
21919 vos_ssr_unprotect(__func__);
21920
21921 return ret;
21922}
21923
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021924/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021925 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021926 * this is called when cfg80211 driver suspends
21927 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021928int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021929 struct cfg80211_wowlan *wow)
21930{
21931 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021932 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021933
21934 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021935
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021936 ret = wlan_hdd_validate_context(pHddCtx);
21937 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021938 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021939 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021940 }
21941
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021942 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021943 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21944 "%s: Suspend SoftAP", __func__);
21945 hdd_set_wlan_suspend_mode(true);
21946 }
21947
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021948
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021949 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21950 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
21951 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021952 pHddCtx->isWiphySuspended = TRUE;
21953
21954 EXIT();
21955
21956 return 0;
21957}
21958
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021959int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
21960 struct cfg80211_wowlan *wow)
21961{
21962 int ret;
21963
21964 vos_ssr_protect(__func__);
21965 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
21966 vos_ssr_unprotect(__func__);
21967
21968 return ret;
21969}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021970
21971#ifdef FEATURE_OEM_DATA_SUPPORT
21972static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021973 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021974{
21975 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21976
21977 ENTER();
21978
21979 if (wlan_hdd_validate_context(pHddCtx)) {
21980 return;
21981 }
21982 if (!pMsg)
21983 {
21984 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
21985 return;
21986 }
21987
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021988 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021989
21990 EXIT();
21991 return;
21992
21993}
21994
21995void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021996 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021997{
21998 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21999
22000 ENTER();
22001
22002 if (wlan_hdd_validate_context(pHddCtx)) {
22003 return;
22004 }
22005
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022006 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022007
22008 switch(evType) {
22009 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022010 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022011 break;
22012 default:
22013 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
22014 break;
22015 }
22016 EXIT();
22017}
22018#endif
22019
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022020#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22021 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022022/**
22023 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
22024 * @wiphy: Pointer to wiphy
22025 * @wdev: Pointer to wireless device structure
22026 *
22027 * This function is used to abort an ongoing scan
22028 *
22029 * Return: None
22030 */
22031static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22032 struct wireless_dev *wdev)
22033{
22034 struct net_device *dev = wdev->netdev;
22035 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22036 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
22037 int ret;
22038
22039 ENTER();
22040
22041 if (NULL == adapter) {
22042 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
22043 return;
22044 }
22045
22046 ret = wlan_hdd_validate_context(hdd_ctx);
22047 if (0 != ret)
22048 return;
22049
22050 wlan_hdd_scan_abort(adapter);
22051
22052 return;
22053}
22054
22055/**
22056 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
22057 * @wiphy: Pointer to wiphy
22058 * @wdev: Pointer to wireless device structure
22059 *
22060 * Return: None
22061 */
22062void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22063 struct wireless_dev *wdev)
22064{
22065 vos_ssr_protect(__func__);
22066 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
22067 vos_ssr_unprotect(__func__);
22068
22069 return;
22070}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022071#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022072
Abhishek Singh936c6932017-11-07 17:28:23 +053022073#ifdef CHANNEL_SWITCH_SUPPORTED
22074/**
22075 * __wlan_hdd_cfg80211_channel_switch()- function to switch
22076 * channel in SAP/GO
22077 * @wiphy: wiphy pointer
22078 * @dev: dev pointer.
22079 * @csa_params: Change channel params
22080 *
22081 * This function is called to switch channel in SAP/GO
22082 *
22083 * Return: 0 if success else return non zero
22084 */
22085static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22086 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22087{
22088 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22089 hdd_context_t *hdd_ctx;
22090 uint8_t channel;
22091 int ret;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022092 ptSapContext sap_ctx;
Abhishek Singh936c6932017-11-07 17:28:23 +053022093 v_CONTEXT_t vos_ctx;
22094
22095 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
22096
22097 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
22098 ret = wlan_hdd_validate_context(hdd_ctx);
22099 if (ret)
22100 return ret;
22101
22102 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
22103 if (!vos_ctx) {
22104 hddLog(LOGE, FL("Vos ctx is null"));
22105 return -EINVAL;
22106 }
22107
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022108 if (WLAN_HDD_SOFTAP != adapter->device_mode)
Abhishek Singh936c6932017-11-07 17:28:23 +053022109 return -ENOTSUPP;
22110
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022111 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
22112 if (!sap_ctx) {
22113 hddLog(LOGE, FL("sap_ctx is NULL"));
22114 return -EINVAL;
22115 }
22116
22117 ret = wlansap_chk_n_set_chan_change_in_progress(sap_ctx);
22118 if (ret)
22119 return ret;
22120
22121 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
22122
Abhishek Singh936c6932017-11-07 17:28:23 +053022123 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053022124 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053022125
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022126 if (ret) {
22127 wlansap_reset_chan_change_in_progress(sap_ctx);
22128 complete(&sap_ctx->ecsa_info.chan_switch_comp);
22129 }
22130
Abhishek Singh936c6932017-11-07 17:28:23 +053022131 return ret;
22132}
22133
22134/**
22135 * wlan_hdd_cfg80211_channel_switch()- function to switch
22136 * channel in SAP/GO
22137 * @wiphy: wiphy pointer
22138 * @dev: dev pointer.
22139 * @csa_params: Change channel params
22140 *
22141 * This function is called to switch channel in SAP/GO
22142 *
22143 * Return: 0 if success else return non zero
22144 */
22145static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22146 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22147{
22148 int ret;
22149
22150 vos_ssr_protect(__func__);
22151 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
22152 vos_ssr_unprotect(__func__);
22153
22154 return ret;
22155}
22156#endif
22157
Jeff Johnson295189b2012-06-20 16:38:30 -070022158/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053022159static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070022160{
22161 .add_virtual_intf = wlan_hdd_add_virtual_intf,
22162 .del_virtual_intf = wlan_hdd_del_virtual_intf,
22163 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
22164 .change_station = wlan_hdd_change_station,
22165#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
22166 .add_beacon = wlan_hdd_cfg80211_add_beacon,
22167 .del_beacon = wlan_hdd_cfg80211_del_beacon,
22168 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022169#else
22170 .start_ap = wlan_hdd_cfg80211_start_ap,
22171 .change_beacon = wlan_hdd_cfg80211_change_beacon,
22172 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070022173#endif
22174 .change_bss = wlan_hdd_cfg80211_change_bss,
22175 .add_key = wlan_hdd_cfg80211_add_key,
22176 .get_key = wlan_hdd_cfg80211_get_key,
22177 .del_key = wlan_hdd_cfg80211_del_key,
22178 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022179#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070022180 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022181#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022182 .scan = wlan_hdd_cfg80211_scan,
22183 .connect = wlan_hdd_cfg80211_connect,
22184 .disconnect = wlan_hdd_cfg80211_disconnect,
22185 .join_ibss = wlan_hdd_cfg80211_join_ibss,
22186 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
22187 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
22188 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
22189 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070022190 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
22191 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053022192 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070022193#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
22194 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
22195 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
22196 .set_txq_params = wlan_hdd_set_txq_params,
22197#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022198 .get_station = wlan_hdd_cfg80211_get_station,
22199 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
22200 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022201 .add_station = wlan_hdd_cfg80211_add_station,
22202#ifdef FEATURE_WLAN_LFR
22203 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
22204 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
22205 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
22206#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070022207#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
22208 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
22209#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080022210#ifdef FEATURE_WLAN_TDLS
22211 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
22212 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
22213#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053022214#ifdef WLAN_FEATURE_GTK_OFFLOAD
22215 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
22216#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053022217#ifdef FEATURE_WLAN_SCAN_PNO
22218 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
22219 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
22220#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022221 .resume = wlan_hdd_cfg80211_resume_wlan,
22222 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053022223 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070022224#ifdef WLAN_NL80211_TESTMODE
22225 .testmode_cmd = wlan_hdd_cfg80211_testmode,
22226#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022227 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022228#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22229 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022230 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022231#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053022232#ifdef CHANNEL_SWITCH_SUPPORTED
22233 .channel_switch = wlan_hdd_cfg80211_channel_switch,
22234#endif
22235
Jeff Johnson295189b2012-06-20 16:38:30 -070022236};
22237