blob: 55df656770c686712820fd1e472fd913fa1b7609 [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
Jeff Johnson295189b2012-06-20 16:38:30 -0700462static struct cfg80211_ops wlan_hdd_cfg80211_ops;
463
464/* Data rate 100KBPS based on IE Index */
465struct index_data_rate_type
466{
467 v_U8_t beacon_rate_index;
468 v_U16_t supported_rate[4];
469};
470
471/* 11B, 11G Rate table include Basic rate and Extended rate
472 The IDX field is the rate index
473 The HI field is the rate when RSSI is strong or being ignored
474 (in this case we report actual rate)
475 The MID field is the rate when RSSI is moderate
476 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
477 The LO field is the rate when RSSI is low
478 (in this case we don't report rates, actual current rate used)
479 */
480static const struct
481{
482 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700483 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700484} supported_data_rate[] =
485{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700486/* IDX HI HM LM LO (RSSI-based index */
487 {2, { 10, 10, 10, 0}},
488 {4, { 20, 20, 10, 0}},
489 {11, { 55, 20, 10, 0}},
490 {12, { 60, 55, 20, 0}},
491 {18, { 90, 55, 20, 0}},
492 {22, {110, 55, 20, 0}},
493 {24, {120, 90, 60, 0}},
494 {36, {180, 120, 60, 0}},
495 {44, {220, 180, 60, 0}},
496 {48, {240, 180, 90, 0}},
497 {66, {330, 180, 90, 0}},
498 {72, {360, 240, 90, 0}},
499 {96, {480, 240, 120, 0}},
500 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700501};
502
503/* MCS Based rate table */
504static struct index_data_rate_type supported_mcs_rate[] =
505{
506/* MCS L20 L40 S20 S40 */
507 {0, {65, 135, 72, 150}},
508 {1, {130, 270, 144, 300}},
509 {2, {195, 405, 217, 450}},
510 {3, {260, 540, 289, 600}},
511 {4, {390, 810, 433, 900}},
512 {5, {520, 1080, 578, 1200}},
513 {6, {585, 1215, 650, 1350}},
514 {7, {650, 1350, 722, 1500}}
515};
516
Leo Chang6f8870f2013-03-26 18:11:36 -0700517#ifdef WLAN_FEATURE_11AC
518
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530519#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700520
521struct index_vht_data_rate_type
522{
523 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530524 v_U16_t supported_VHT80_rate[2];
525 v_U16_t supported_VHT40_rate[2];
526 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700527};
528
529typedef enum
530{
531 DATA_RATE_11AC_MAX_MCS_7,
532 DATA_RATE_11AC_MAX_MCS_8,
533 DATA_RATE_11AC_MAX_MCS_9,
534 DATA_RATE_11AC_MAX_MCS_NA
535} eDataRate11ACMaxMcs;
536
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530537/* SSID broadcast type */
538typedef enum eSSIDBcastType
539{
540 eBCAST_UNKNOWN = 0,
541 eBCAST_NORMAL = 1,
542 eBCAST_HIDDEN = 2,
543} tSSIDBcastType;
544
Leo Chang6f8870f2013-03-26 18:11:36 -0700545/* MCS Based VHT rate table */
546static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
547{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530548/* MCS L80 S80 L40 S40 L20 S40*/
549 {0, {293, 325}, {135, 150}, {65, 72}},
550 {1, {585, 650}, {270, 300}, {130, 144}},
551 {2, {878, 975}, {405, 450}, {195, 217}},
552 {3, {1170, 1300}, {540, 600}, {260, 289}},
553 {4, {1755, 1950}, {810, 900}, {390, 433}},
554 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
555 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
556 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
557 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
558 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700559};
560#endif /* WLAN_FEATURE_11AC */
561
c_hpothu79aab322014-07-14 21:11:01 +0530562/*array index points to MCS and array value points respective rssi*/
563static int rssiMcsTbl[][10] =
564{
565/*MCS 0 1 2 3 4 5 6 7 8 9*/
566 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
567 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
568 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
569};
570
Jeff Johnson295189b2012-06-20 16:38:30 -0700571extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530572#ifdef FEATURE_WLAN_SCAN_PNO
573static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
574#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700575
Leo Chang9056f462013-08-01 19:21:11 -0700576#ifdef WLAN_NL80211_TESTMODE
577enum wlan_hdd_tm_attr
578{
579 WLAN_HDD_TM_ATTR_INVALID = 0,
580 WLAN_HDD_TM_ATTR_CMD = 1,
581 WLAN_HDD_TM_ATTR_DATA = 2,
582 WLAN_HDD_TM_ATTR_TYPE = 3,
583 /* keep last */
584 WLAN_HDD_TM_ATTR_AFTER_LAST,
585 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
586};
587
588enum wlan_hdd_tm_cmd
589{
590 WLAN_HDD_TM_CMD_WLAN_HB = 1,
591};
592
593#define WLAN_HDD_TM_DATA_MAX_LEN 5000
594
595static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
596{
597 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
598 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
599 .len = WLAN_HDD_TM_DATA_MAX_LEN },
600};
601#endif /* WLAN_NL80211_TESTMODE */
602
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800603#ifdef FEATURE_WLAN_CH_AVOID
604/*
605 * FUNCTION: wlan_hdd_send_avoid_freq_event
606 * This is called when wlan driver needs to send vendor specific
607 * avoid frequency range event to userspace
608 */
609int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
610 tHddAvoidFreqList *pAvoidFreqList)
611{
612 struct sk_buff *vendor_event;
613
614 ENTER();
615
616 if (!pHddCtx)
617 {
618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
619 "%s: HDD context is null", __func__);
620 return -1;
621 }
622
623 if (!pAvoidFreqList)
624 {
625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
626 "%s: pAvoidFreqList is null", __func__);
627 return -1;
628 }
629
630 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530631#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
632 NULL,
633#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800634 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530635 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800636 GFP_KERNEL);
637 if (!vendor_event)
638 {
639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
640 "%s: cfg80211_vendor_event_alloc failed", __func__);
641 return -1;
642 }
643
644 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
645 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
646
647 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
648
649 EXIT();
650 return 0;
651}
652#endif /* FEATURE_WLAN_CH_AVOID */
653
Srinivas Dasari030bad32015-02-18 23:23:54 +0530654/*
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +0530655 * define short names for the global vendor params
656 * used by QCA_NL80211_VENDOR_SUBCMD_HANG
657 */
658#define HANG_REASON_INDEX QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX
659
660/**
661 * hdd_convert_hang_reason() - Convert cds recovery reason to vendor specific
662 * hang reason
663 * @reason: cds recovery reason
664 *
665 * Return: Vendor specific reason code
666 */
667static enum qca_wlan_vendor_hang_reason
668hdd_convert_hang_reason(enum vos_hang_reason reason)
669{
670 unsigned int ret_val;
671
672 switch (reason) {
673 case VOS_GET_MSG_BUFF_FAILURE:
674 ret_val = QCA_WLAN_HANG_GET_MSG_BUFF_FAILURE;
675 break;
676 case VOS_ACTIVE_LIST_TIMEOUT:
677 ret_val = QCA_WLAN_HANG_ACTIVE_LIST_TIMEOUT;
678 break;
679 case VOS_SCAN_REQ_EXPIRED:
680 ret_val = QCA_WLAN_HANG_SCAN_REQ_EXPIRED;
681 break;
682 case VOS_TRANSMISSIONS_TIMEOUT:
683 ret_val = QCA_WLAN_HANG_TRANSMISSIONS_TIMEOUT;
684 break;
685 case VOS_DXE_FAILURE:
686 ret_val = QCA_WLAN_HANG_DXE_FAILURE;
687 break;
688 case VOS_WDI_FAILURE:
689 ret_val = QCA_WLAN_HANG_WDI_FAILURE;
690 break;
691 case VOS_REASON_UNSPECIFIED:
692 default:
693 ret_val = QCA_WLAN_HANG_REASON_UNSPECIFIED;
694 }
695 return ret_val;
696}
697
698/**
699 * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace
700 * @hdd_ctx: Pointer to hdd context
701 * @reason: cds recovery reason
702 *
703 * Return: 0 on success or failure reason
704 */
705int wlan_hdd_send_hang_reason_event(hdd_context_t *hdd_ctx,
706 enum vos_hang_reason reason)
707{
708 struct sk_buff *vendor_event;
709 enum qca_wlan_vendor_hang_reason hang_reason;
710
711 ENTER();
712
713 if (!hdd_ctx) {
714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
715 "HDD context is null");
716 return -EINVAL;
717 }
718
719 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
720#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
721 NULL,
722#endif
723 sizeof(unsigned int),
724 HANG_REASON_INDEX,
725 GFP_KERNEL);
726 if (!vendor_event) {
727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
728 "cfg80211_vendor_event_alloc failed");
729 return -ENOMEM;
730 }
731
732 hang_reason = hdd_convert_hang_reason(reason);
733
734 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_HANG_REASON,
735 (unsigned int) hang_reason)) {
736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
737 "QCA_WLAN_VENDOR_ATTR_HANG_REASON put fail");
738 kfree_skb(vendor_event);
739 return -EINVAL;
740 }
741
742 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
743
744 EXIT();
745 return 0;
746}
747#undef HANG_REASON_INDEX
748
749/*
Srinivas Dasari030bad32015-02-18 23:23:54 +0530750 * FUNCTION: __wlan_hdd_cfg80211_nan_request
751 * This is called when wlan driver needs to send vendor specific
752 * nan request event.
753 */
754static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
755 struct wireless_dev *wdev,
756 const void *data, int data_len)
757{
758 tNanRequestReq nan_req;
759 VOS_STATUS status;
760 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530761 struct net_device *dev = wdev->netdev;
762 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
763 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530764 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
765
766 if (0 == data_len)
767 {
768 hddLog(VOS_TRACE_LEVEL_ERROR,
769 FL("NAN - Invalid Request, length = 0"));
770 return ret_val;
771 }
772
773 if (NULL == data)
774 {
775 hddLog(VOS_TRACE_LEVEL_ERROR,
776 FL("NAN - Invalid Request, data is NULL"));
777 return ret_val;
778 }
779
780 status = wlan_hdd_validate_context(pHddCtx);
781 if (0 != status)
782 {
783 hddLog(VOS_TRACE_LEVEL_ERROR,
784 FL("HDD context is not valid"));
785 return -EINVAL;
786 }
787
788 hddLog(LOG1, FL("Received NAN command"));
789 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
790 (tANI_U8 *)data, data_len);
791
792 /* check the NAN Capability */
793 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
794 {
795 hddLog(VOS_TRACE_LEVEL_ERROR,
796 FL("NAN is not supported by Firmware"));
797 return -EINVAL;
798 }
799
800 nan_req.request_data_len = data_len;
801 nan_req.request_data = data;
802
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530803 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530804 if (VOS_STATUS_SUCCESS == status)
805 {
806 ret_val = 0;
807 }
808 return ret_val;
809}
810
811/*
812 * FUNCTION: wlan_hdd_cfg80211_nan_request
813 * Wrapper to protect the nan vendor command from ssr
814 */
815static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
816 struct wireless_dev *wdev,
817 const void *data, int data_len)
818{
819 int ret;
820
821 vos_ssr_protect(__func__);
822 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
823 vos_ssr_unprotect(__func__);
824
825 return ret;
826}
827
828/*
829 * FUNCTION: wlan_hdd_cfg80211_nan_callback
830 * This is a callback function and it gets called
831 * when we need to report nan response event to
832 * upper layers.
833 */
834static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
835{
836 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
837 struct sk_buff *vendor_event;
838 int status;
839 tSirNanEvent *data;
840
841 ENTER();
842 if (NULL == msg)
843 {
844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
845 FL(" msg received here is null"));
846 return;
847 }
848 data = msg;
849
850 status = wlan_hdd_validate_context(pHddCtx);
851
852 if (0 != status)
853 {
854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
855 FL("HDD context is not valid"));
856 return;
857 }
858
859 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530860#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
861 NULL,
862#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530863 data->event_data_len +
864 NLMSG_HDRLEN,
865 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
866 GFP_KERNEL);
867
868 if (!vendor_event)
869 {
870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
871 FL("cfg80211_vendor_event_alloc failed"));
872 return;
873 }
874 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
875 data->event_data_len, data->event_data))
876 {
877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
878 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
879 kfree_skb(vendor_event);
880 return;
881 }
882 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
883 EXIT();
884}
885
886/*
887 * FUNCTION: wlan_hdd_cfg80211_nan_init
888 * This function is called to register the callback to sme layer
889 */
890inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
891{
892 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
893}
894
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530895/*
896 * define short names for the global vendor params
897 * used by __wlan_hdd_cfg80211_get_station_cmd()
898 */
899#define STATION_INVALID \
900 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
901#define STATION_INFO \
902 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
903#define STATION_ASSOC_FAIL_REASON \
904 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +0530905#define STATION_REMOTE \
906 QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530907#define STATION_MAX \
908 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
909
910static const struct nla_policy
911hdd_get_station_policy[STATION_MAX + 1] = {
912 [STATION_INFO] = {.type = NLA_FLAG},
913 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
914};
915
916/**
917 * hdd_get_station_assoc_fail() - Handle get station assoc fail
918 * @hdd_ctx: HDD context within host driver
919 * @wdev: wireless device
920 *
921 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
922 * Validate cmd attributes and send the station info to upper layers.
923 *
924 * Return: Success(0) or reason code for failure
925 */
926static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
927 hdd_adapter_t *adapter)
928{
929 struct sk_buff *skb = NULL;
930 uint32_t nl_buf_len;
931 hdd_station_ctx_t *hdd_sta_ctx;
932
933 nl_buf_len = NLMSG_HDRLEN;
934 nl_buf_len += sizeof(uint32_t);
935 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
936
937 if (!skb) {
938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
939 return -ENOMEM;
940 }
941
942 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
943
944 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
945 hdd_sta_ctx->conn_info.assoc_status_code)) {
946 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
947 goto fail;
948 }
949 return cfg80211_vendor_cmd_reply(skb);
950fail:
951 if (skb)
952 kfree_skb(skb);
953 return -EINVAL;
954}
955
956/**
957 * hdd_map_auth_type() - transform auth type specific to
958 * vendor command
959 * @auth_type: csr auth type
960 *
961 * Return: Success(0) or reason code for failure
962 */
963static int hdd_convert_auth_type(uint32_t auth_type)
964{
965 uint32_t ret_val;
966
967 switch (auth_type) {
968 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
969 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
970 break;
971 case eCSR_AUTH_TYPE_SHARED_KEY:
972 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
973 break;
974 case eCSR_AUTH_TYPE_WPA:
975 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
976 break;
977 case eCSR_AUTH_TYPE_WPA_PSK:
978 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
979 break;
980 case eCSR_AUTH_TYPE_AUTOSWITCH:
981 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
982 break;
983 case eCSR_AUTH_TYPE_WPA_NONE:
984 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
985 break;
986 case eCSR_AUTH_TYPE_RSN:
987 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
988 break;
989 case eCSR_AUTH_TYPE_RSN_PSK:
990 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
991 break;
992 case eCSR_AUTH_TYPE_FT_RSN:
993 ret_val = QCA_WLAN_AUTH_TYPE_FT;
994 break;
995 case eCSR_AUTH_TYPE_FT_RSN_PSK:
996 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
997 break;
998 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
999 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
1000 break;
1001 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
1002 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
1003 break;
1004#ifdef FEATURE_WLAN_ESE
1005 case eCSR_AUTH_TYPE_CCKM_WPA:
1006 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
1007 break;
1008 case eCSR_AUTH_TYPE_CCKM_RSN:
1009 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
1010 break;
1011#endif
1012 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
1013 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
1014 break;
1015 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
1016 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
1017 break;
1018 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
1019 case eCSR_AUTH_TYPE_FAILED:
1020 case eCSR_AUTH_TYPE_NONE:
1021 default:
1022 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
1023 break;
1024 }
1025 return ret_val;
1026}
1027
1028/**
1029 * hdd_map_dot_11_mode() - transform dot11mode type specific to
1030 * vendor command
1031 * @dot11mode: dot11mode
1032 *
1033 * Return: Success(0) or reason code for failure
1034 */
1035static int hdd_convert_dot11mode(uint32_t dot11mode)
1036{
1037 uint32_t ret_val;
1038
1039 switch (dot11mode) {
1040 case eCSR_CFG_DOT11_MODE_11A:
1041 ret_val = QCA_WLAN_802_11_MODE_11A;
1042 break;
1043 case eCSR_CFG_DOT11_MODE_11B:
1044 ret_val = QCA_WLAN_802_11_MODE_11B;
1045 break;
1046 case eCSR_CFG_DOT11_MODE_11G:
1047 ret_val = QCA_WLAN_802_11_MODE_11G;
1048 break;
1049 case eCSR_CFG_DOT11_MODE_11N:
1050 ret_val = QCA_WLAN_802_11_MODE_11N;
1051 break;
1052 case eCSR_CFG_DOT11_MODE_11AC:
1053 ret_val = QCA_WLAN_802_11_MODE_11AC;
1054 break;
1055 case eCSR_CFG_DOT11_MODE_AUTO:
1056 case eCSR_CFG_DOT11_MODE_ABG:
1057 default:
1058 ret_val = QCA_WLAN_802_11_MODE_INVALID;
1059 }
1060 return ret_val;
1061}
1062
1063/**
1064 * hdd_add_tx_bitrate() - add tx bitrate attribute
1065 * @skb: pointer to sk buff
1066 * @hdd_sta_ctx: pointer to hdd station context
1067 * @idx: attribute index
1068 *
1069 * Return: Success(0) or reason code for failure
1070 */
1071static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
1072 hdd_station_ctx_t *hdd_sta_ctx,
1073 int idx)
1074{
1075 struct nlattr *nla_attr;
1076 uint32_t bitrate, bitrate_compat;
1077
1078 nla_attr = nla_nest_start(skb, idx);
1079 if (!nla_attr)
1080 goto fail;
1081 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301082 bitrate = cfg80211_calculate_bitrate(
1083 &hdd_sta_ctx->cache_conn_info.txrate);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301084
1085 /* report 16-bit bitrate only if we can */
1086 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
1087 if (bitrate > 0 &&
1088 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
1089 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1090 goto fail;
1091 }
1092 if (bitrate_compat > 0 &&
1093 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
1094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1095 goto fail;
1096 }
1097 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301098 hdd_sta_ctx->cache_conn_info.txrate.nss)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1100 goto fail;
1101 }
1102 nla_nest_end(skb, nla_attr);
1103 return 0;
1104fail:
1105 return -EINVAL;
1106}
1107
1108/**
1109 * hdd_add_sta_info() - add station info attribute
1110 * @skb: pointer to sk buff
1111 * @hdd_sta_ctx: pointer to hdd station context
1112 * @idx: attribute index
1113 *
1114 * Return: Success(0) or reason code for failure
1115 */
1116static int32_t hdd_add_sta_info(struct sk_buff *skb,
1117 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1118{
1119 struct nlattr *nla_attr;
1120
1121 nla_attr = nla_nest_start(skb, idx);
1122 if (!nla_attr)
1123 goto fail;
1124 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301125 (hdd_sta_ctx->cache_conn_info.signal + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1127 goto fail;
1128 }
1129 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1130 goto fail;
1131 nla_nest_end(skb, nla_attr);
1132 return 0;
1133fail:
1134 return -EINVAL;
1135}
1136
1137/**
1138 * hdd_add_survey_info() - add survey info attribute
1139 * @skb: pointer to sk buff
1140 * @hdd_sta_ctx: pointer to hdd station context
1141 * @idx: attribute index
1142 *
1143 * Return: Success(0) or reason code for failure
1144 */
1145static int32_t hdd_add_survey_info(struct sk_buff *skb,
1146 hdd_station_ctx_t *hdd_sta_ctx,
1147 int idx)
1148{
1149 struct nlattr *nla_attr;
1150
1151 nla_attr = nla_nest_start(skb, idx);
1152 if (!nla_attr)
1153 goto fail;
1154 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301155 hdd_sta_ctx->cache_conn_info.freq) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301156 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301157 (hdd_sta_ctx->cache_conn_info.noise + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1159 goto fail;
1160 }
1161 nla_nest_end(skb, nla_attr);
1162 return 0;
1163fail:
1164 return -EINVAL;
1165}
1166
1167/**
1168 * hdd_add_link_standard_info() - add link info attribute
1169 * @skb: pointer to sk buff
1170 * @hdd_sta_ctx: pointer to hdd station context
1171 * @idx: attribute index
1172 *
1173 * Return: Success(0) or reason code for failure
1174 */
1175static int32_t
1176hdd_add_link_standard_info(struct sk_buff *skb,
1177 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1178{
1179 struct nlattr *nla_attr;
1180
1181 nla_attr = nla_nest_start(skb, idx);
1182 if (!nla_attr)
1183 goto fail;
1184 if (nla_put(skb,
1185 NL80211_ATTR_SSID,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301186 hdd_sta_ctx->cache_conn_info.SSID.SSID.length,
1187 hdd_sta_ctx->cache_conn_info.SSID.SSID.ssId)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1189 goto fail;
1190 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301191 if (nla_put(skb, NL80211_ATTR_MAC, VOS_MAC_ADDR_SIZE,
1192 hdd_sta_ctx->cache_conn_info.bssId))
1193 goto fail;
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301194 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1195 goto fail;
1196 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1197 goto fail;
1198 nla_nest_end(skb, nla_attr);
1199 return 0;
1200fail:
1201 return -EINVAL;
1202}
1203
1204/**
1205 * hdd_add_ap_standard_info() - add ap info attribute
1206 * @skb: pointer to sk buff
1207 * @hdd_sta_ctx: pointer to hdd station context
1208 * @idx: attribute index
1209 *
1210 * Return: Success(0) or reason code for failure
1211 */
1212static int32_t
1213hdd_add_ap_standard_info(struct sk_buff *skb,
1214 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1215{
1216 struct nlattr *nla_attr;
1217
1218 nla_attr = nla_nest_start(skb, idx);
1219 if (!nla_attr)
1220 goto fail;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301221 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301222 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301223 sizeof(hdd_sta_ctx->cache_conn_info.vht_caps),
1224 &hdd_sta_ctx->cache_conn_info.vht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1226 goto fail;
1227 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301228 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301229 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301230 sizeof(hdd_sta_ctx->cache_conn_info.ht_caps),
1231 &hdd_sta_ctx->cache_conn_info.ht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1233 goto fail;
1234 }
1235 nla_nest_end(skb, nla_attr);
1236 return 0;
1237fail:
1238 return -EINVAL;
1239}
1240
1241/**
1242 * hdd_get_station_info() - send BSS information to supplicant
1243 * @hdd_ctx: pointer to hdd context
1244 * @adapter: pointer to adapter
1245 *
1246 * Return: 0 if success else error status
1247 */
1248static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1249 hdd_adapter_t *adapter)
1250{
1251 struct sk_buff *skb = NULL;
1252 uint8_t *tmp_hs20 = NULL;
1253 uint32_t nl_buf_len;
1254 hdd_station_ctx_t *hdd_sta_ctx;
1255
1256 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1257
1258 nl_buf_len = NLMSG_HDRLEN;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301259
1260 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.SSID.SSID.length) +
1261 VOS_MAC_ADDR_SIZE +
1262 sizeof(hdd_sta_ctx->cache_conn_info.freq) +
1263 sizeof(hdd_sta_ctx->cache_conn_info.noise) +
1264 sizeof(hdd_sta_ctx->cache_conn_info.signal) +
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301265 (sizeof(uint32_t) * 2) +
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301266 sizeof(hdd_sta_ctx->cache_conn_info.txrate.nss) +
1267 sizeof(hdd_sta_ctx->cache_conn_info.roam_count) +
1268 sizeof(hdd_sta_ctx->cache_conn_info.authType) +
1269 sizeof(hdd_sta_ctx->cache_conn_info.dot11Mode);
1270 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
1271 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.vht_caps);
1272 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
1273 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_caps);
1274 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) {
1275 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->
1276 cache_conn_info.hs20vendor_ie);
1277 nl_buf_len +=
1278 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie) -
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301279 1);
1280 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301281 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
1282 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_operation);
1283 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
1284 nl_buf_len +=
1285 sizeof(hdd_sta_ctx->cache_conn_info.vht_operation);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301286
1287
1288 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1289 if (!skb) {
1290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1291 __func__, __LINE__);
1292 return -ENOMEM;
1293 }
1294
1295 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1296 LINK_INFO_STANDARD_NL80211_ATTR)) {
1297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1298 goto fail;
1299 }
1300 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1301 AP_INFO_STANDARD_NL80211_ATTR)) {
1302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1303 goto fail;
1304 }
1305 if (nla_put_u32(skb, INFO_ROAM_COUNT,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301306 hdd_sta_ctx->cache_conn_info.roam_count) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301307 nla_put_u32(skb, INFO_AKM,
1308 hdd_convert_auth_type(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301309 hdd_sta_ctx->cache_conn_info.authType)) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301310 nla_put_u32(skb, WLAN802_11_MODE,
1311 hdd_convert_dot11mode(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301312 hdd_sta_ctx->cache_conn_info.dot11Mode))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1314 goto fail;
1315 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301316 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301317 if (nla_put(skb, HT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301318 (sizeof(hdd_sta_ctx->cache_conn_info.ht_operation)),
1319 &hdd_sta_ctx->cache_conn_info.ht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1321 goto fail;
1322 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301323 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301324 if (nla_put(skb, VHT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301325 (sizeof(hdd_sta_ctx->
1326 cache_conn_info.vht_operation)),
1327 &hdd_sta_ctx->cache_conn_info.vht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1329 goto fail;
1330 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301331 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301332 if (nla_put(skb, AP_INFO_HS20_INDICATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301333 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie)
1334 - 1), tmp_hs20 + 1)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1336 goto fail;
1337 }
1338
1339 return cfg80211_vendor_cmd_reply(skb);
1340fail:
1341 if (skb)
1342 kfree_skb(skb);
1343 return -EINVAL;
1344}
1345
1346/**
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301347 * hdd_add_survey_info_sap_get_len - get data length used in
1348 * hdd_add_survey_info_sap()
1349 *
1350 * This function calculates the data length used in hdd_add_survey_info_sap()
1351 *
1352 * Return: total data length used in hdd_add_survey_info_sap()
1353 */
1354static uint32_t hdd_add_survey_info_sap_get_len(void)
1355{
1356 return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
1357}
1358
1359/**
1360 * hdd_add_survey_info - add survey info attribute
1361 * @skb: pointer to response skb buffer
1362 * @stainfo: station information
1363 * @idx: attribute type index for nla_next_start()
1364 *
1365 * This function adds survey info attribute to response skb buffer
1366 *
1367 * Return : 0 on success and errno on failure
1368 */
1369static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
1370 struct hdd_cache_sta_info *stainfo,
1371 int idx)
1372{
1373 struct nlattr *nla_attr;
1374
1375 nla_attr = nla_nest_start(skb, idx);
1376 if (!nla_attr)
1377 goto fail;
1378 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1379 stainfo->freq)) {
1380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1381 FL("put fail"));
1382 goto fail;
1383 }
1384 nla_nest_end(skb, nla_attr);
1385 return 0;
1386fail:
1387 return -EINVAL;
1388}
1389
1390/**
1391 * hdd_add_tx_bitrate_sap_get_len - get data length used in
1392 * hdd_add_tx_bitrate_sap()
1393 *
1394 * This function calculates the data length used in hdd_add_tx_bitrate_sap()
1395 *
1396 * Return: total data length used in hdd_add_tx_bitrate_sap()
1397 */
1398static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
1399{
1400 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
1401}
1402
1403/**
1404 * hdd_add_tx_bitrate_sap - add vht nss info attribute
1405 * @skb: pointer to response skb buffer
1406 * @stainfo: station information
1407 * @idx: attribute type index for nla_next_start()
1408 *
1409 * This function adds vht nss attribute to response skb buffer
1410 *
1411 * Return : 0 on success and errno on failure
1412 */
1413static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
1414 struct hdd_cache_sta_info *stainfo,
1415 int idx)
1416{
1417 struct nlattr *nla_attr;
1418
1419 nla_attr = nla_nest_start(skb, idx);
1420 if (!nla_attr)
1421 goto fail;
1422
1423 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1424 stainfo->nss)) {
1425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1426 FL("put fail"));
1427 goto fail;
1428 }
1429 nla_nest_end(skb, nla_attr);
1430 return 0;
1431fail:
1432 return -EINVAL;
1433}
1434
1435/**
1436 * hdd_add_sta_info_sap_get_len - get data length used in
1437 * hdd_add_sta_info_sap()
1438 *
1439 * This function calculates the data length used in hdd_add_sta_info_sap()
1440 *
1441 * Return: total data length used in hdd_add_sta_info_sap()
1442 */
1443static uint32_t hdd_add_sta_info_sap_get_len(void)
1444{
1445 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
1446 hdd_add_tx_bitrate_sap_get_len());
1447}
1448
1449/**
1450 * hdd_add_sta_info_sap - add sta signal info attribute
1451 * @skb: pointer to response skb buffer
1452 * @rssi: peer rssi value
1453 * @stainfo: station information
1454 * @idx: attribute type index for nla_next_start()
1455 *
1456 * This function adds sta signal attribute to response skb buffer
1457 *
1458 * Return : 0 on success and errno on failure
1459 */
1460static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
1461 struct hdd_cache_sta_info *stainfo, int idx)
1462{
1463 struct nlattr *nla_attr;
1464
1465 nla_attr = nla_nest_start(skb, idx);
1466 if (!nla_attr)
1467 goto fail;
1468
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05301469 /* upperlayer expects positive rssi value */
1470 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, (rssi + 96))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1472 FL("put fail"));
1473 goto fail;
1474 }
1475 if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE)) {
1476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1477 FL("put fail"));
1478 goto fail;
1479 }
1480
1481 nla_nest_end(skb, nla_attr);
1482 return 0;
1483fail:
1484 return -EINVAL;
1485}
1486
1487/**
1488 * hdd_add_link_standard_info_sap_get_len - get data length used in
1489 * hdd_add_link_standard_info_sap()
1490 *
1491 * This function calculates the data length used in
1492 * hdd_add_link_standard_info_sap()
1493 *
1494 * Return: total data length used in hdd_add_link_standard_info_sap()
1495 */
1496static uint32_t hdd_add_link_standard_info_sap_get_len(void)
1497{
1498 return ((NLA_HDRLEN) +
1499 hdd_add_survey_info_sap_get_len() +
1500 hdd_add_sta_info_sap_get_len() +
1501 (sizeof(uint32_t) + NLA_HDRLEN));
1502}
1503
1504/**
1505 * hdd_add_link_standard_info_sap - add add link info attribut
1506 * @skb: pointer to response skb buffer
1507 * @stainfo: station information
1508 * @idx: attribute type index for nla_next_start()
1509 *
1510 * This function adds link info attribut to response skb buffer
1511 *
1512 * Return : 0 on success and errno on failure
1513 */
1514static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
1515 struct hdd_cache_sta_info *stainfo,
1516 int idx)
1517{
1518 struct nlattr *nla_attr;
1519
1520 nla_attr = nla_nest_start(skb, idx);
1521 if (!nla_attr)
1522 goto fail;
1523 if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
1524 goto fail;
1525 if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
1526 goto fail;
1527
1528 if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
1529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1530 FL("put fail"));
1531 goto fail;
1532 }
1533
1534 nla_nest_end(skb, nla_attr);
1535 return 0;
1536fail:
1537 return -EINVAL;
1538}
1539
1540/**
1541 * hdd_add_ap_standard_info_sap_get_len - get data length used in
1542 * hdd_add_ap_standard_info_sap()
1543 * @stainfo: station information
1544 *
1545 * This function calculates the data length used in
1546 * hdd_add_ap_standard_info_sap()
1547 *
1548 * Return: total data length used in hdd_add_ap_standard_info_sap()
1549 */
1550static uint32_t hdd_add_ap_standard_info_sap_get_len(
1551 struct hdd_cache_sta_info *stainfo)
1552{
1553 uint32_t len;
1554
1555 len = NLA_HDRLEN;
1556 if (stainfo->vht_present)
1557 len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
1558 if (stainfo->ht_present)
1559 len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
1560
1561 return len;
1562}
1563
1564/**
1565 * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
1566 * @skb: pointer to response skb buffer
1567 * @stainfo: station information
1568 * @idx: attribute type index for nla_next_start()
1569 *
1570 * This function adds HT and VHT info attributes to response skb buffer
1571 *
1572 * Return : 0 on success and errno on failure
1573 */
1574static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
1575 struct hdd_cache_sta_info *stainfo,
1576 int idx)
1577{
1578 struct nlattr *nla_attr;
1579
1580 nla_attr = nla_nest_start(skb, idx);
1581 if (!nla_attr)
1582 goto fail;
1583
1584 if (stainfo->vht_present) {
1585 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1586 sizeof(stainfo->vht_caps),
1587 &stainfo->vht_caps)) {
1588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1589 FL("put fail"));
1590 goto fail;
1591 }
1592 }
1593 if (stainfo->ht_present) {
1594 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1595 sizeof(stainfo->ht_caps),
1596 &stainfo->ht_caps)) {
1597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1598 FL("put fail"));
1599 goto fail;
1600 }
1601 }
1602 nla_nest_end(skb, nla_attr);
1603 return 0;
1604fail:
1605 return -EINVAL;
1606}
1607
1608/**
1609 * hdd_decode_ch_width - decode channel band width based
1610 * @ch_width: encoded enum value holding channel band width
1611 *
1612 * This function decodes channel band width from the given encoded enum value.
1613 *
1614 * Returns: decoded channel band width.
1615 */
1616static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
1617{
1618 switch (ch_width) {
1619 case 0:
1620 return 20;
1621 case 1:
1622 return 40;
1623 case 2:
1624 return 80;
1625 default:
1626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1627 "invalid enum: %d", ch_width);
1628 return 20;
1629 }
1630}
1631
1632/**
1633 * hdd_get_cached_station_remote() - get cached(deleted) peer's info
1634 * @hdd_ctx: hdd context
1635 * @adapter: hostapd interface
1636 * @mac_addr: mac address of requested peer
1637 *
1638 * This function collect and indicate the cached(deleted) peer's info
1639 *
1640 * Return: 0 on success, otherwise error value
1641 */
1642static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx,
1643 hdd_adapter_t *adapter,
1644 v_MACADDR_t mac_addr)
1645{
1646 struct hdd_cache_sta_info *stainfo;
1647 struct sk_buff *skb = NULL;
1648 uint32_t nl_buf_len;
1649 uint8_t cw;
1650 ptSapContext sap_ctx;
1651 v_CONTEXT_t vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
1652
1653 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
1654 if(sap_ctx == NULL){
1655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1656 FL("psapCtx is NULL"));
1657 return -ENOENT;
1658 }
1659
1660 stainfo = hdd_get_cache_stainfo(sap_ctx->cache_sta_info,
1661 mac_addr.bytes);
1662 if (!stainfo) {
1663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1664 "peer " MAC_ADDRESS_STR " not found",
1665 MAC_ADDR_ARRAY(mac_addr.bytes));
1666 return -EINVAL;
1667 }
1668 if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE) {
1669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1670 "peer " MAC_ADDRESS_STR " is in connected state",
1671 MAC_ADDR_ARRAY(mac_addr.bytes));
1672 return -EINVAL;
1673 }
1674
1675
1676 nl_buf_len = NLMSG_HDRLEN + hdd_add_link_standard_info_sap_get_len() +
1677 hdd_add_ap_standard_info_sap_get_len(stainfo) +
1678 (sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
1679 (sizeof(cw) + NLA_HDRLEN) +
1680 (sizeof(stainfo->rx_rate) + NLA_HDRLEN);
1681
1682 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1683 if (!skb) {
1684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "cfg80211_vendor_cmd_alloc_reply_skb failed");
1685 return -ENOMEM;
1686 }
1687
1688 if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
1689 LINK_INFO_STANDARD_NL80211_ATTR)) {
1690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "link standard put fail");
1691 goto fail;
1692 }
1693
1694 if (hdd_add_ap_standard_info_sap(skb, stainfo,
1695 AP_INFO_STANDARD_NL80211_ATTR)) {
1696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ap standard put fail");
1697 goto fail;
1698 }
1699
1700 /* upper layer expects decoded channel BW */
1701 cw = hdd_decode_ch_width(stainfo->ch_width);
1702 if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE, stainfo->dot11_mode) ||
1703 nla_put_u8(skb, REMOTE_CH_WIDTH, cw)) {
1704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "remote ch put fail");
1705 goto fail;
1706 }
Hanumanth Reddy Pothula504fe152018-01-02 20:41:03 +05301707 if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, (stainfo->rx_rate * 100))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "rx rate put fail");
1709 goto fail;
1710 }
1711
1712 vos_mem_zero(stainfo, sizeof(*stainfo));
1713
1714 return cfg80211_vendor_cmd_reply(skb);
1715fail:
1716 if (skb)
1717 kfree_skb(skb);
1718
1719 return -EINVAL;
1720}
1721
1722/**
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301723 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1724 * @wiphy: corestack handler
1725 * @wdev: wireless device
1726 * @data: data
1727 * @data_len: data length
1728 *
1729 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1730 * Validate cmd attributes and send the station info to upper layers.
1731 *
1732 * Return: Success(0) or reason code for failure
1733 */
1734static int32_t
1735__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1736 struct wireless_dev *wdev,
1737 const void *data,
1738 int data_len)
1739{
1740 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1741 struct net_device *dev = wdev->netdev;
1742 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1743 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1744 int32_t status;
1745
1746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1747 if (VOS_FTM_MODE == hdd_get_conparam()) {
1748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1749 status = -EPERM;
1750 goto out;
1751 }
1752
1753 status = wlan_hdd_validate_context(hdd_ctx);
1754 if (0 != status)
1755 goto out;
1756
1757
1758 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1759 data, data_len, NULL);
1760 if (status) {
1761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1762 goto out;
1763 }
1764
1765 /* Parse and fetch Command Type*/
1766 if (tb[STATION_INFO]) {
1767 status = hdd_get_station_info(hdd_ctx, adapter);
1768 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1769 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301770 } else if (tb[STATION_REMOTE]) {
1771 v_MACADDR_t mac_addr;
1772
1773 if (adapter->device_mode != WLAN_HDD_SOFTAP &&
1774 adapter->device_mode != WLAN_HDD_P2P_GO) {
1775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"invalid device_mode:%d",
1776 adapter->device_mode);
1777 status = -EINVAL;
1778 goto out;
1779 }
1780
1781 nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
1782 VOS_MAC_ADDRESS_LEN);
1783
1784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "STATION_REMOTE "MAC_ADDRESS_STR"",
1785 MAC_ADDR_ARRAY(mac_addr.bytes));
1786
1787 status = hdd_get_cached_station_remote(hdd_ctx, adapter,
1788 mac_addr);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301789 } else {
1790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1791 status = -EINVAL;
1792 goto out;
1793 }
1794 EXIT();
1795out:
1796 return status;
1797}
1798
1799/**
1800 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1801 * @wiphy: corestack handler
1802 * @wdev: wireless device
1803 * @data: data
1804 * @data_len: data length
1805 *
1806 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1807 * Validate cmd attributes and send the station info to upper layers.
1808 *
1809 * Return: Success(0) or reason code for failure
1810 */
1811static int32_t
1812hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1813 struct wireless_dev *wdev,
1814 const void *data,
1815 int data_len)
1816{
1817 int ret;
1818
1819 vos_ssr_protect(__func__);
1820 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1821 vos_ssr_unprotect(__func__);
1822
1823 return ret;
1824}
1825
1826/*
1827 * undef short names defined for get station command
1828 * used by __wlan_hdd_cfg80211_get_station_cmd()
1829 */
1830#undef STATION_INVALID
1831#undef STATION_INFO
1832#undef STATION_ASSOC_FAIL_REASON
1833#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301834
Sunil Duttc69bccb2014-05-26 21:30:20 +05301835#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1836
1837static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1838 struct sk_buff *vendor_event)
1839{
1840 if (nla_put_u8(vendor_event,
1841 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1842 stats->rate.preamble) ||
1843 nla_put_u8(vendor_event,
1844 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1845 stats->rate.nss) ||
1846 nla_put_u8(vendor_event,
1847 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1848 stats->rate.bw) ||
1849 nla_put_u8(vendor_event,
1850 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1851 stats->rate.rateMcsIdx) ||
1852 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1853 stats->rate.bitrate ) ||
1854 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1855 stats->txMpdu ) ||
1856 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1857 stats->rxMpdu ) ||
1858 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1859 stats->mpduLost ) ||
1860 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1861 stats->retries) ||
1862 nla_put_u32(vendor_event,
1863 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1864 stats->retriesShort ) ||
1865 nla_put_u32(vendor_event,
1866 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1867 stats->retriesLong))
1868 {
1869 hddLog(VOS_TRACE_LEVEL_ERROR,
1870 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1871 return FALSE;
1872 }
1873 return TRUE;
1874}
1875
1876static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1877 struct sk_buff *vendor_event)
1878{
1879 u32 i = 0;
1880 struct nlattr *rateInfo;
1881 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1882 stats->type) ||
1883 nla_put(vendor_event,
1884 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1885 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1886 nla_put_u32(vendor_event,
1887 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1888 stats->capabilities) ||
1889 nla_put_u32(vendor_event,
1890 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1891 stats->numRate))
1892 {
1893 hddLog(VOS_TRACE_LEVEL_ERROR,
1894 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1895 goto error;
1896 }
1897
1898 rateInfo = nla_nest_start(vendor_event,
1899 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301900 if(!rateInfo)
1901 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301902 for (i = 0; i < stats->numRate; i++)
1903 {
1904 struct nlattr *rates;
1905 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1906 stats->rateStats +
1907 (i * sizeof(tSirWifiRateStat)));
1908 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301909 if(!rates)
1910 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301911
1912 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1913 {
1914 hddLog(VOS_TRACE_LEVEL_ERROR,
1915 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1916 return FALSE;
1917 }
1918 nla_nest_end(vendor_event, rates);
1919 }
1920 nla_nest_end(vendor_event, rateInfo);
1921
1922 return TRUE;
1923error:
1924 return FALSE;
1925}
1926
1927static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1928 struct sk_buff *vendor_event)
1929{
1930 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1931 stats->ac ) ||
1932 nla_put_u32(vendor_event,
1933 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1934 stats->txMpdu ) ||
1935 nla_put_u32(vendor_event,
1936 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1937 stats->rxMpdu ) ||
1938 nla_put_u32(vendor_event,
1939 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1940 stats->txMcast ) ||
1941 nla_put_u32(vendor_event,
1942 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1943 stats->rxMcast ) ||
1944 nla_put_u32(vendor_event,
1945 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1946 stats->rxAmpdu ) ||
1947 nla_put_u32(vendor_event,
1948 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1949 stats->txAmpdu ) ||
1950 nla_put_u32(vendor_event,
1951 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1952 stats->mpduLost )||
1953 nla_put_u32(vendor_event,
1954 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1955 stats->retries ) ||
1956 nla_put_u32(vendor_event,
1957 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1958 stats->retriesShort ) ||
1959 nla_put_u32(vendor_event,
1960 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1961 stats->retriesLong ) ||
1962 nla_put_u32(vendor_event,
1963 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1964 stats->contentionTimeMin ) ||
1965 nla_put_u32(vendor_event,
1966 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1967 stats->contentionTimeMax ) ||
1968 nla_put_u32(vendor_event,
1969 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1970 stats->contentionTimeAvg ) ||
1971 nla_put_u32(vendor_event,
1972 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1973 stats->contentionNumSamples ))
1974 {
1975 hddLog(VOS_TRACE_LEVEL_ERROR,
1976 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1977 return FALSE;
1978 }
1979 return TRUE;
1980}
1981
1982static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1983 struct sk_buff *vendor_event)
1984{
Dino Myclec8f3f332014-07-21 16:48:27 +05301985 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301986 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1987 nla_put(vendor_event,
1988 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
1989 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
1990 nla_put_u32(vendor_event,
1991 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
1992 stats->state ) ||
1993 nla_put_u32(vendor_event,
1994 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
1995 stats->roaming ) ||
1996 nla_put_u32(vendor_event,
1997 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
1998 stats->capabilities ) ||
1999 nla_put(vendor_event,
2000 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
2001 strlen(stats->ssid), stats->ssid) ||
2002 nla_put(vendor_event,
2003 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
2004 WNI_CFG_BSSID_LEN, stats->bssid) ||
2005 nla_put(vendor_event,
2006 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
2007 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
2008 nla_put(vendor_event,
2009 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
2010 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
2011 )
2012 {
2013 hddLog(VOS_TRACE_LEVEL_ERROR,
2014 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2015 return FALSE;
2016 }
2017 return TRUE;
2018}
2019
Dino Mycle3b9536d2014-07-09 22:05:24 +05302020static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
2021 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302022 struct sk_buff *vendor_event)
2023{
2024 int i = 0;
2025 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302026 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2027 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302028 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302029
Sunil Duttc69bccb2014-05-26 21:30:20 +05302030 if (FALSE == put_wifi_interface_info(
2031 &pWifiIfaceStat->info,
2032 vendor_event))
2033 {
2034 hddLog(VOS_TRACE_LEVEL_ERROR,
2035 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2036 return FALSE;
2037
2038 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05302039 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
2040 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
2041 if (NULL == pWifiIfaceStatTL)
2042 {
2043 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2044 return FALSE;
2045 }
2046
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302047 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
2048 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
2049 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
2050 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
2051
2052 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
2053 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
2054 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
2055 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302056
2057 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
2058 {
2059 if (VOS_STATUS_SUCCESS ==
2060 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2061 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
2062 {
2063 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
2064 * obtained from TL structure
2065 */
2066
2067 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
2068 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302069 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
2070
Srinivas Dasari98947432014-11-07 19:41:24 +05302071 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
2072 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
2073 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
2074 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
2075 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
2076 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
2077 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
2078 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302079
Srinivas Dasari98947432014-11-07 19:41:24 +05302080 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
2081 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
2082 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
2083 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
2084 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
2085 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
2086 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
2087 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302088
Srinivas Dasari98947432014-11-07 19:41:24 +05302089 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
2090 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
2091 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
2092 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
2093 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
2094 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
2095 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
2096 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302097 }
2098 else
2099 {
2100 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
2101 }
2102
Dino Mycle3b9536d2014-07-09 22:05:24 +05302103 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
2104 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
2105 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
2106 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
2107 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
2108 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
2109 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
2110 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
2111 }
2112 else
2113 {
2114 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
2115 }
2116
2117
Sunil Duttc69bccb2014-05-26 21:30:20 +05302118
2119 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302120 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2121 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
2122 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302123 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
2124 pWifiIfaceStat->beaconRx) ||
2125 nla_put_u32(vendor_event,
2126 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
2127 pWifiIfaceStat->mgmtRx) ||
2128 nla_put_u32(vendor_event,
2129 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
2130 pWifiIfaceStat->mgmtActionRx) ||
2131 nla_put_u32(vendor_event,
2132 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
2133 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302134 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302135 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
2136 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302137 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302138 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
2139 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302140 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302141 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
2142 pWifiIfaceStat->rssiAck))
2143 {
2144 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302145 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2146 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302147 return FALSE;
2148 }
2149
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302150#ifdef FEATURE_EXT_LL_STAT
2151 /*
2152 * Ensure when EXT_LL_STAT is supported by both host and fwr,
2153 * then host should send Leaky AP stats to upper layer,
2154 * otherwise no need to send these stats.
2155 */
2156 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
2157 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
2158 )
2159 {
2160 hddLog(VOS_TRACE_LEVEL_INFO,
2161 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
2162 pWifiIfaceStat->leakyApStat.is_leaky_ap,
2163 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
2164 pWifiIfaceStat->leakyApStat.rx_leak_window,
2165 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
2166 if (nla_put_u32(vendor_event,
2167 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
2168 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
2169 nla_put_u32(vendor_event,
2170 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
2171 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
2172 nla_put_u32(vendor_event,
2173 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
2174 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05302175 hdd_wlan_nla_put_u64(vendor_event,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302176 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
2177 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
2178 {
2179 hddLog(VOS_TRACE_LEVEL_ERROR,
2180 FL("EXT_LL_STAT put fail"));
2181 vos_mem_free(pWifiIfaceStatTL);
2182 return FALSE;
2183 }
2184 }
2185#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05302186 wmmInfo = nla_nest_start(vendor_event,
2187 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302188 if(!wmmInfo)
2189 {
2190 vos_mem_free(pWifiIfaceStatTL);
2191 return FALSE;
2192 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302193 for (i = 0; i < WIFI_AC_MAX; i++)
2194 {
2195 struct nlattr *wmmStats;
2196 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302197 if(!wmmStats)
2198 {
2199 vos_mem_free(pWifiIfaceStatTL);
2200 return FALSE;
2201 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302202 if (FALSE == put_wifi_wmm_ac_stat(
2203 &pWifiIfaceStat->AccessclassStats[i],
2204 vendor_event))
2205 {
2206 hddLog(VOS_TRACE_LEVEL_ERROR,
2207 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05302208 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302209 return FALSE;
2210 }
2211
2212 nla_nest_end(vendor_event, wmmStats);
2213 }
2214 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05302215 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302216 return TRUE;
2217}
2218
2219static tSirWifiInterfaceMode
2220 hdd_map_device_to_ll_iface_mode ( int deviceMode )
2221{
2222 switch (deviceMode)
2223 {
2224 case WLAN_HDD_INFRA_STATION:
2225 return WIFI_INTERFACE_STA;
2226 case WLAN_HDD_SOFTAP:
2227 return WIFI_INTERFACE_SOFTAP;
2228 case WLAN_HDD_P2P_CLIENT:
2229 return WIFI_INTERFACE_P2P_CLIENT;
2230 case WLAN_HDD_P2P_GO:
2231 return WIFI_INTERFACE_P2P_GO;
2232 case WLAN_HDD_IBSS:
2233 return WIFI_INTERFACE_IBSS;
2234 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05302235 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302236 }
2237}
2238
2239static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
2240 tpSirWifiInterfaceInfo pInfo)
2241{
2242 v_U8_t *staMac = NULL;
2243 hdd_station_ctx_t *pHddStaCtx;
2244 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2245 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
2246
2247 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
2248
2249 vos_mem_copy(pInfo->macAddr,
2250 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
2251
2252 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2253 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
2254 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
2255 {
2256 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2257 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
2258 {
2259 pInfo->state = WIFI_DISCONNECTED;
2260 }
2261 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
2262 {
2263 hddLog(VOS_TRACE_LEVEL_ERROR,
2264 "%s: Session ID %d, Connection is in progress", __func__,
2265 pAdapter->sessionId);
2266 pInfo->state = WIFI_ASSOCIATING;
2267 }
2268 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
2269 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
2270 {
2271 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
2272 hddLog(VOS_TRACE_LEVEL_ERROR,
2273 "%s: client " MAC_ADDRESS_STR
2274 " is in the middle of WPS/EAPOL exchange.", __func__,
2275 MAC_ADDR_ARRAY(staMac));
2276 pInfo->state = WIFI_AUTHENTICATING;
2277 }
2278 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
2279 {
2280 pInfo->state = WIFI_ASSOCIATED;
2281 vos_mem_copy(pInfo->bssid,
2282 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
2283 vos_mem_copy(pInfo->ssid,
2284 pHddStaCtx->conn_info.SSID.SSID.ssId,
2285 pHddStaCtx->conn_info.SSID.SSID.length);
2286 //NULL Terminate the string.
2287 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
2288 }
2289 }
2290 vos_mem_copy(pInfo->countryStr,
2291 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2292
2293 vos_mem_copy(pInfo->apCountryStr,
2294 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2295
2296 return TRUE;
2297}
2298
2299/*
2300 * hdd_link_layer_process_peer_stats () - This function is called after
2301 * receiving Link Layer Peer statistics from FW.This function converts
2302 * the firmware data to the NL data and sends the same to the kernel/upper
2303 * layers.
2304 */
2305static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
2306 v_VOID_t *pData)
2307{
2308 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302309 tpSirWifiPeerStat pWifiPeerStat;
2310 tpSirWifiPeerInfo pWifiPeerInfo;
2311 struct nlattr *peerInfo;
2312 struct sk_buff *vendor_event;
2313 int status, i;
2314
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302315 ENTER();
2316
Sunil Duttc69bccb2014-05-26 21:30:20 +05302317 status = wlan_hdd_validate_context(pHddCtx);
2318 if (0 != status)
2319 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302320 return;
2321 }
2322
2323 pWifiPeerStat = (tpSirWifiPeerStat) pData;
2324
2325 hddLog(VOS_TRACE_LEVEL_INFO,
2326 "LL_STATS_PEER_ALL : numPeers %u",
2327 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302328 /*
2329 * Allocate a size of 4096 for the peer stats comprising
2330 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
2331 * sizeof (tSirWifiRateStat).Each field is put with an
2332 * NL attribute.The size of 4096 is considered assuming
2333 * that number of rates shall not exceed beyond 50 with
2334 * the sizeof (tSirWifiRateStat) being 32.
2335 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302336 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2337 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302338 if (!vendor_event)
2339 {
2340 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302341 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05302342 __func__);
2343 return;
2344 }
2345 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302346 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2347 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
2348 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302349 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
2350 pWifiPeerStat->numPeers))
2351 {
2352 hddLog(VOS_TRACE_LEVEL_ERROR,
2353 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
2354 kfree_skb(vendor_event);
2355 return;
2356 }
2357
2358 peerInfo = nla_nest_start(vendor_event,
2359 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302360 if(!peerInfo)
2361 {
2362 hddLog(VOS_TRACE_LEVEL_ERROR,
2363 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
2364 __func__);
2365 kfree_skb(vendor_event);
2366 return;
2367 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302368
2369 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2370 pWifiPeerStat->peerInfo);
2371
2372 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
2373 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302374 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302375 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302376
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302377 if(!peers)
2378 {
2379 hddLog(VOS_TRACE_LEVEL_ERROR,
2380 "%s: peer stats put fail",
2381 __func__);
2382 kfree_skb(vendor_event);
2383 return;
2384 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302385 if (FALSE == put_wifi_peer_info(
2386 pWifiPeerInfo, vendor_event))
2387 {
2388 hddLog(VOS_TRACE_LEVEL_ERROR,
2389 "%s: put_wifi_peer_info put fail", __func__);
2390 kfree_skb(vendor_event);
2391 return;
2392 }
2393
2394 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2395 pWifiPeerStat->peerInfo +
2396 (i * sizeof(tSirWifiPeerInfo)) +
2397 (numRate * sizeof (tSirWifiRateStat)));
2398 nla_nest_end(vendor_event, peers);
2399 }
2400 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302401 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302402 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302403}
2404
2405/*
2406 * hdd_link_layer_process_iface_stats () - This function is called after
2407 * receiving Link Layer Interface statistics from FW.This function converts
2408 * the firmware data to the NL data and sends the same to the kernel/upper
2409 * layers.
2410 */
2411static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
2412 v_VOID_t *pData)
2413{
2414 tpSirWifiIfaceStat pWifiIfaceStat;
2415 struct sk_buff *vendor_event;
2416 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2417 int status;
2418
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302419 ENTER();
2420
Sunil Duttc69bccb2014-05-26 21:30:20 +05302421 status = wlan_hdd_validate_context(pHddCtx);
2422 if (0 != status)
2423 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302424 return;
2425 }
2426 /*
2427 * Allocate a size of 4096 for the interface stats comprising
2428 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
2429 * assuming that all these fit with in the limit.Please take
2430 * a call on the limit based on the data requirements on
2431 * interface statistics.
2432 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302433 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2434 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302435 if (!vendor_event)
2436 {
2437 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302438 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302439 return;
2440 }
2441
2442 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
2443
Dino Mycle3b9536d2014-07-09 22:05:24 +05302444
2445 if (FALSE == hdd_get_interface_info( pAdapter,
2446 &pWifiIfaceStat->info))
2447 {
2448 hddLog(VOS_TRACE_LEVEL_ERROR,
2449 FL("hdd_get_interface_info get fail") );
2450 kfree_skb(vendor_event);
2451 return;
2452 }
2453
2454 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
2455 vendor_event))
2456 {
2457 hddLog(VOS_TRACE_LEVEL_ERROR,
2458 FL("put_wifi_iface_stats fail") );
2459 kfree_skb(vendor_event);
2460 return;
2461 }
2462
Sunil Duttc69bccb2014-05-26 21:30:20 +05302463 hddLog(VOS_TRACE_LEVEL_INFO,
2464 "WMI_LINK_STATS_IFACE Data");
2465
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302466 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302467
2468 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302469}
2470
2471/*
2472 * hdd_link_layer_process_radio_stats () - This function is called after
2473 * receiving Link Layer Radio statistics from FW.This function converts
2474 * the firmware data to the NL data and sends the same to the kernel/upper
2475 * layers.
2476 */
2477static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
2478 v_VOID_t *pData)
2479{
2480 int status, i;
2481 tpSirWifiRadioStat pWifiRadioStat;
2482 tpSirWifiChannelStats pWifiChannelStats;
2483 struct sk_buff *vendor_event;
2484 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2485 struct nlattr *chList;
2486
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302487 ENTER();
2488
Sunil Duttc69bccb2014-05-26 21:30:20 +05302489 status = wlan_hdd_validate_context(pHddCtx);
2490 if (0 != status)
2491 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302492 return;
2493 }
2494 pWifiRadioStat = (tpSirWifiRadioStat) pData;
2495
2496 hddLog(VOS_TRACE_LEVEL_INFO,
2497 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302498 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05302499 " radio is %d onTime is %u "
2500 " txTime is %u rxTime is %u "
2501 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05302502 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05302503 " onTimePnoScan is %u onTimeHs20 is %u "
2504 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302505 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302506 pWifiRadioStat->radio, pWifiRadioStat->onTime,
2507 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
2508 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302509 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302510 pWifiRadioStat->onTimeRoamScan,
2511 pWifiRadioStat->onTimePnoScan,
2512 pWifiRadioStat->onTimeHs20,
2513 pWifiRadioStat->numChannels);
2514 /*
2515 * Allocate a size of 4096 for the Radio stats comprising
2516 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
2517 * (tSirWifiChannelStats).Each channel data is put with an
2518 * NL attribute.The size of 4096 is considered assuming that
2519 * number of channels shall not exceed beyond 60 with the
2520 * sizeof (tSirWifiChannelStats) being 24 bytes.
2521 */
2522
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302523 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2524 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302525 if (!vendor_event)
2526 {
2527 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302528 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302529 return;
2530 }
2531
2532 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302533 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2534 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2535 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302536 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2537 pWifiRadioStat->radio) ||
2538 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302539 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2540 NUM_RADIOS) ||
2541 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302542 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2543 pWifiRadioStat->onTime) ||
2544 nla_put_u32(vendor_event,
2545 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2546 pWifiRadioStat->txTime) ||
2547 nla_put_u32(vendor_event,
2548 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2549 pWifiRadioStat->rxTime) ||
2550 nla_put_u32(vendor_event,
2551 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2552 pWifiRadioStat->onTimeScan) ||
2553 nla_put_u32(vendor_event,
2554 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2555 pWifiRadioStat->onTimeNbd) ||
2556 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302557 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2558 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302559 nla_put_u32(vendor_event,
2560 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2561 pWifiRadioStat->onTimeRoamScan) ||
2562 nla_put_u32(vendor_event,
2563 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2564 pWifiRadioStat->onTimePnoScan) ||
2565 nla_put_u32(vendor_event,
2566 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2567 pWifiRadioStat->onTimeHs20) ||
2568 nla_put_u32(vendor_event,
2569 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2570 pWifiRadioStat->numChannels))
2571 {
2572 hddLog(VOS_TRACE_LEVEL_ERROR,
2573 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2574 kfree_skb(vendor_event);
2575 return ;
2576 }
2577
2578 chList = nla_nest_start(vendor_event,
2579 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302580 if(!chList)
2581 {
2582 hddLog(VOS_TRACE_LEVEL_ERROR,
2583 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2584 __func__);
2585 kfree_skb(vendor_event);
2586 return;
2587 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302588 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2589 {
2590 struct nlattr *chInfo;
2591
2592 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2593 pWifiRadioStat->channels +
2594 (i * sizeof(tSirWifiChannelStats)));
2595
Sunil Duttc69bccb2014-05-26 21:30:20 +05302596 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302597 if(!chInfo)
2598 {
2599 hddLog(VOS_TRACE_LEVEL_ERROR,
2600 "%s: failed to put chInfo",
2601 __func__);
2602 kfree_skb(vendor_event);
2603 return;
2604 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302605
2606 if (nla_put_u32(vendor_event,
2607 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2608 pWifiChannelStats->channel.width) ||
2609 nla_put_u32(vendor_event,
2610 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2611 pWifiChannelStats->channel.centerFreq) ||
2612 nla_put_u32(vendor_event,
2613 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2614 pWifiChannelStats->channel.centerFreq0) ||
2615 nla_put_u32(vendor_event,
2616 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2617 pWifiChannelStats->channel.centerFreq1) ||
2618 nla_put_u32(vendor_event,
2619 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2620 pWifiChannelStats->onTime) ||
2621 nla_put_u32(vendor_event,
2622 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2623 pWifiChannelStats->ccaBusyTime))
2624 {
2625 hddLog(VOS_TRACE_LEVEL_ERROR,
2626 FL("cfg80211_vendor_event_alloc failed") );
2627 kfree_skb(vendor_event);
2628 return ;
2629 }
2630 nla_nest_end(vendor_event, chInfo);
2631 }
2632 nla_nest_end(vendor_event, chList);
2633
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302634 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302635
2636 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302637 return;
2638}
2639
2640/*
2641 * hdd_link_layer_stats_ind_callback () - This function is called after
2642 * receiving Link Layer indications from FW.This callback converts the firmware
2643 * data to the NL data and send the same to the kernel/upper layers.
2644 */
2645static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2646 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302647 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302648{
Dino Mycled3d50022014-07-07 12:58:25 +05302649 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2650 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302651 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302652 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302653 int status;
2654
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302655 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302656
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302657 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302658 if (0 != status)
2659 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302660 return;
2661 }
2662
Dino Mycled3d50022014-07-07 12:58:25 +05302663 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2664 if (NULL == pAdapter)
2665 {
2666 hddLog(VOS_TRACE_LEVEL_ERROR,
2667 FL(" MAC address %pM does not exist with host"),
2668 macAddr);
2669 return;
2670 }
2671
Sunil Duttc69bccb2014-05-26 21:30:20 +05302672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302673 "%s: Interface: %s LLStats indType: %d", __func__,
2674 pAdapter->dev->name, indType);
2675
Sunil Duttc69bccb2014-05-26 21:30:20 +05302676 switch (indType)
2677 {
2678 case SIR_HAL_LL_STATS_RESULTS_RSP:
2679 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302680 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302681 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2682 "respId = %u, moreResultToFollow = %u",
2683 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2684 macAddr, linkLayerStatsResults->respId,
2685 linkLayerStatsResults->moreResultToFollow);
2686
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302687 spin_lock(&hdd_context_lock);
2688 context = &pHddCtx->ll_stats_context;
2689 /* validate response received from target */
2690 if ((context->request_id != linkLayerStatsResults->respId) ||
2691 !(context->request_bitmap & linkLayerStatsResults->paramId))
2692 {
2693 spin_unlock(&hdd_context_lock);
2694 hddLog(LOGE,
2695 FL("Error : Request id %d response id %d request bitmap 0x%x"
2696 "response bitmap 0x%x"),
2697 context->request_id, linkLayerStatsResults->respId,
2698 context->request_bitmap, linkLayerStatsResults->paramId);
2699 return;
2700 }
2701 spin_unlock(&hdd_context_lock);
2702
Sunil Duttc69bccb2014-05-26 21:30:20 +05302703 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2704 {
2705 hdd_link_layer_process_radio_stats(pAdapter,
2706 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302707 spin_lock(&hdd_context_lock);
2708 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2709 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302710 }
2711 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2712 {
2713 hdd_link_layer_process_iface_stats(pAdapter,
2714 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302715 spin_lock(&hdd_context_lock);
2716 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2717 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302718 }
2719 else if ( linkLayerStatsResults->paramId &
2720 WMI_LINK_STATS_ALL_PEER )
2721 {
2722 hdd_link_layer_process_peer_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_ALL_PEER);
2726 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302727 } /* WMI_LINK_STATS_ALL_PEER */
2728 else
2729 {
2730 hddLog(VOS_TRACE_LEVEL_ERROR,
2731 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2732 }
2733
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302734 spin_lock(&hdd_context_lock);
2735 /* complete response event if all requests are completed */
2736 if (0 == context->request_bitmap)
2737 complete(&context->response_event);
2738 spin_unlock(&hdd_context_lock);
2739
Sunil Duttc69bccb2014-05-26 21:30:20 +05302740 break;
2741 }
2742 default:
2743 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2744 break;
2745 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302746
2747 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302748 return;
2749}
2750
2751const struct
2752nla_policy
2753qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2754{
2755 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2756 { .type = NLA_U32 },
2757 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2758 { .type = NLA_U32 },
2759};
2760
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302761static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2762 struct wireless_dev *wdev,
2763 const void *data,
2764 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302765{
2766 int status;
2767 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302768 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302769 struct net_device *dev = wdev->netdev;
2770 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2771 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2772
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302773 ENTER();
2774
Sunil Duttc69bccb2014-05-26 21:30:20 +05302775 status = wlan_hdd_validate_context(pHddCtx);
2776 if (0 != status)
2777 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302778 return -EINVAL;
2779 }
2780
2781 if (NULL == pAdapter)
2782 {
2783 hddLog(VOS_TRACE_LEVEL_ERROR,
2784 FL("HDD adapter is Null"));
2785 return -ENODEV;
2786 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302787 /* check the LLStats Capability */
2788 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2789 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2790 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302791 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302792 FL("Link Layer Statistics not supported by Firmware"));
2793 return -EINVAL;
2794 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302795
2796 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2797 (struct nlattr *)data,
2798 data_len, qca_wlan_vendor_ll_set_policy))
2799 {
2800 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2801 return -EINVAL;
2802 }
2803 if (!tb_vendor
2804 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2805 {
2806 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2807 return -EINVAL;
2808 }
2809 if (!tb_vendor[
2810 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2811 {
2812 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2813 return -EINVAL;
2814 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302815 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302816 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302817
Dino Mycledf0a5d92014-07-04 09:41:55 +05302818 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302819 nla_get_u32(
2820 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2821
Dino Mycledf0a5d92014-07-04 09:41:55 +05302822 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302823 nla_get_u32(
2824 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2825
Dino Mycled3d50022014-07-07 12:58:25 +05302826 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2827 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302828
2829
2830 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302831 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2832 "Statistics Gathering = %d ",
2833 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2834 linkLayerStatsSetReq.mpduSizeThreshold,
2835 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302836
2837 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2838 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302839 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302840 {
2841 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2842 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302843 return -EINVAL;
2844
2845 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302846
Sunil Duttc69bccb2014-05-26 21:30:20 +05302847 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302848 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302849 {
2850 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2851 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302852 return -EINVAL;
2853 }
2854
2855 pAdapter->isLinkLayerStatsSet = 1;
2856
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302857 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302858 return 0;
2859}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302860static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2861 struct wireless_dev *wdev,
2862 const void *data,
2863 int data_len)
2864{
2865 int ret = 0;
2866
2867 vos_ssr_protect(__func__);
2868 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2869 vos_ssr_unprotect(__func__);
2870
2871 return ret;
2872}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302873
2874const struct
2875nla_policy
2876qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2877{
2878 /* Unsigned 32bit value provided by the caller issuing the GET stats
2879 * command. When reporting
2880 * the stats results, the driver uses the same value to indicate
2881 * which GET request the results
2882 * correspond to.
2883 */
2884 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2885
2886 /* Unsigned 32bit value . bit mask to identify what statistics are
2887 requested for retrieval */
2888 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2889};
2890
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302891static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2892 struct wireless_dev *wdev,
2893 const void *data,
2894 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302895{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302896 unsigned long rc;
2897 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302898 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2899 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302900 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302901 struct net_device *dev = wdev->netdev;
2902 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302903 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302904 int status;
2905
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302906 ENTER();
2907
Sunil Duttc69bccb2014-05-26 21:30:20 +05302908 status = wlan_hdd_validate_context(pHddCtx);
2909 if (0 != status)
2910 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302911 return -EINVAL ;
2912 }
2913
2914 if (NULL == pAdapter)
2915 {
2916 hddLog(VOS_TRACE_LEVEL_FATAL,
2917 "%s: HDD adapter is Null", __func__);
2918 return -ENODEV;
2919 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302920
2921 if (pHddStaCtx == NULL)
2922 {
2923 hddLog(VOS_TRACE_LEVEL_FATAL,
2924 "%s: HddStaCtx is Null", __func__);
2925 return -ENODEV;
2926 }
2927
Dino Mycledf0a5d92014-07-04 09:41:55 +05302928 /* check the LLStats Capability */
2929 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2930 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2931 {
2932 hddLog(VOS_TRACE_LEVEL_ERROR,
2933 FL("Link Layer Statistics not supported by Firmware"));
2934 return -EINVAL;
2935 }
2936
Sunil Duttc69bccb2014-05-26 21:30:20 +05302937
2938 if (!pAdapter->isLinkLayerStatsSet)
2939 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302940 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302941 "%s: isLinkLayerStatsSet : %d",
2942 __func__, pAdapter->isLinkLayerStatsSet);
2943 return -EINVAL;
2944 }
2945
Mukul Sharma10313ba2015-07-29 19:14:39 +05302946 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2947 {
2948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2949 "%s: Roaming in progress, so unable to proceed this request", __func__);
2950 return -EBUSY;
2951 }
2952
Sunil Duttc69bccb2014-05-26 21:30:20 +05302953 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2954 (struct nlattr *)data,
2955 data_len, qca_wlan_vendor_ll_get_policy))
2956 {
2957 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2958 return -EINVAL;
2959 }
2960
2961 if (!tb_vendor
2962 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2963 {
2964 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2965 return -EINVAL;
2966 }
2967
2968 if (!tb_vendor
2969 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2970 {
2971 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2972 return -EINVAL;
2973 }
2974
Sunil Duttc69bccb2014-05-26 21:30:20 +05302975
Dino Mycledf0a5d92014-07-04 09:41:55 +05302976 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302977 nla_get_u32( tb_vendor[
2978 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302979 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302980 nla_get_u32( tb_vendor[
2981 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2982
Dino Mycled3d50022014-07-07 12:58:25 +05302983 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2984 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302985
2986 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302987 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
2988 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302989 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302990
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302991 spin_lock(&hdd_context_lock);
2992 context = &pHddCtx->ll_stats_context;
2993 context->request_id = linkLayerStatsGetReq.reqId;
2994 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
2995 INIT_COMPLETION(context->response_event);
2996 spin_unlock(&hdd_context_lock);
2997
Sunil Duttc69bccb2014-05-26 21:30:20 +05302998 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302999 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303000 {
3001 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3002 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303003 return -EINVAL;
3004 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303005
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303006 rc = wait_for_completion_timeout(&context->response_event,
3007 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
3008 if (!rc)
3009 {
3010 hddLog(LOGE,
3011 FL("Target response timed out request id %d request bitmap 0x%x"),
3012 context->request_id, context->request_bitmap);
3013 return -ETIMEDOUT;
3014 }
3015
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303016 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303017 return 0;
3018}
3019
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303020static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
3021 struct wireless_dev *wdev,
3022 const void *data,
3023 int data_len)
3024{
3025 int ret = 0;
3026
3027 vos_ssr_protect(__func__);
3028 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
3029 vos_ssr_unprotect(__func__);
3030
3031 return ret;
3032}
3033
Sunil Duttc69bccb2014-05-26 21:30:20 +05303034const struct
3035nla_policy
3036qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
3037{
3038 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
3039 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
3040 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
3041 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
3042};
3043
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303044static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3045 struct wireless_dev *wdev,
3046 const void *data,
3047 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303048{
3049 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3050 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05303051 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303052 struct net_device *dev = wdev->netdev;
3053 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3054 u32 statsClearReqMask;
3055 u8 stopReq;
3056 int status;
3057
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303058 ENTER();
3059
Sunil Duttc69bccb2014-05-26 21:30:20 +05303060 status = wlan_hdd_validate_context(pHddCtx);
3061 if (0 != status)
3062 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303063 return -EINVAL;
3064 }
3065
3066 if (NULL == pAdapter)
3067 {
3068 hddLog(VOS_TRACE_LEVEL_FATAL,
3069 "%s: HDD adapter is Null", __func__);
3070 return -ENODEV;
3071 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05303072 /* check the LLStats Capability */
3073 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
3074 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
3075 {
3076 hddLog(VOS_TRACE_LEVEL_ERROR,
3077 FL("Enable LLStats Capability"));
3078 return -EINVAL;
3079 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05303080
3081 if (!pAdapter->isLinkLayerStatsSet)
3082 {
3083 hddLog(VOS_TRACE_LEVEL_FATAL,
3084 "%s: isLinkLayerStatsSet : %d",
3085 __func__, pAdapter->isLinkLayerStatsSet);
3086 return -EINVAL;
3087 }
3088
3089 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
3090 (struct nlattr *)data,
3091 data_len, qca_wlan_vendor_ll_clr_policy))
3092 {
3093 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
3094 return -EINVAL;
3095 }
3096
3097 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
3098
3099 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
3100 {
3101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
3102 return -EINVAL;
3103
3104 }
3105
Sunil Duttc69bccb2014-05-26 21:30:20 +05303106
Dino Mycledf0a5d92014-07-04 09:41:55 +05303107 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303108 nla_get_u32(
3109 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
3110
Dino Mycledf0a5d92014-07-04 09:41:55 +05303111 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303112 nla_get_u8(
3113 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
3114
3115 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05303116 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303117
Dino Mycled3d50022014-07-07 12:58:25 +05303118 vos_mem_copy(linkLayerStatsClearReq.macAddr,
3119 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05303120
3121 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05303122 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
3123 "statsClearReqMask = 0x%X, stopReq = %d",
3124 linkLayerStatsClearReq.reqId,
3125 linkLayerStatsClearReq.macAddr,
3126 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303127 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303128
3129 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303130 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303131 {
3132 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05303133 hdd_station_ctx_t *pHddStaCtx;
3134
3135 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3136 if (VOS_STATUS_SUCCESS !=
3137 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
3138 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
3139 {
3140 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3141 "WLANTL_ClearInterfaceStats Failed", __func__);
3142 return -EINVAL;
3143 }
3144 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
3145 (statsClearReqMask & WIFI_STATS_IFACE)) {
3146 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
3147 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
3148 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
3149 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
3150 }
3151
Sunil Duttc69bccb2014-05-26 21:30:20 +05303152 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
3153 2 * sizeof(u32) +
3154 NLMSG_HDRLEN);
3155
3156 if (temp_skbuff != NULL)
3157 {
3158
3159 if (nla_put_u32(temp_skbuff,
3160 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
3161 statsClearReqMask) ||
3162 nla_put_u32(temp_skbuff,
3163 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
3164 stopReq))
3165 {
3166 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
3167 kfree_skb(temp_skbuff);
3168 return -EINVAL;
3169 }
3170 /* If the ask is to stop the stats collection as part of clear
3171 * (stopReq = 1) , ensure that no further requests of get
3172 * go to the firmware by having isLinkLayerStatsSet set to 0.
3173 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303174 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05303175 * case the firmware is just asked to clear the statistics.
3176 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05303177 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303178 pAdapter->isLinkLayerStatsSet = 0;
3179 return cfg80211_vendor_cmd_reply(temp_skbuff);
3180 }
3181 return -ENOMEM;
3182 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303183
3184 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303185 return -EINVAL;
3186}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303187static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3188 struct wireless_dev *wdev,
3189 const void *data,
3190 int data_len)
3191{
3192 int ret = 0;
3193
3194 vos_ssr_protect(__func__);
3195 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
3196 vos_ssr_unprotect(__func__);
3197
3198 return ret;
3199
3200
3201}
Sunil Duttc69bccb2014-05-26 21:30:20 +05303202#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
3203
Dino Mycle6fb96c12014-06-10 11:52:40 +05303204#ifdef WLAN_FEATURE_EXTSCAN
3205static const struct nla_policy
3206wlan_hdd_extscan_config_policy
3207 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
3208{
3209 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
3210 { .type = NLA_U32 },
3211 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
3212 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05303213 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
3214 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303215 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
3216 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
3217 { .type = NLA_U32 },
3218 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
3219 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
3220
3221 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
3222 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
3223 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
3224 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
3225 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303226 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
3227 { .type = NLA_U32 },
3228 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
3229 { .type = NLA_U32 },
3230 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
3231 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303232 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
3233 { .type = NLA_U32 },
3234 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
3235 { .type = NLA_U32 },
3236 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
3237 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303238 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
3239 { .type = NLA_U8 },
3240 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303241 { .type = NLA_U8 },
3242 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
3243 { .type = NLA_U8 },
3244 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
3245 { .type = NLA_U8 },
3246
3247 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
3248 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05303249 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
3250 .type = NLA_UNSPEC,
3251 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05303252 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
3253 { .type = NLA_S32 },
3254 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
3255 { .type = NLA_S32 },
3256 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
3257 { .type = NLA_U32 },
3258 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
3259 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303260 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
3261 { .type = NLA_U32 },
3262 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
3263 { .type = NLA_BINARY,
3264 .len = IEEE80211_MAX_SSID_LEN + 1 },
3265 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303266 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303267 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
3268 { .type = NLA_U32 },
3269 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
3270 { .type = NLA_U8 },
3271 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
3272 { .type = NLA_S32 },
3273 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
3274 { .type = NLA_S32 },
3275 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
3276 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303277};
3278
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303279/**
3280 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
3281 * @ctx: hdd global context
3282 * @data: capabilities data
3283 *
3284 * Return: none
3285 */
3286static void
3287wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303288{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303289 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303290 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303291 tSirEXTScanCapabilitiesEvent *data =
3292 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303293
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303294 ENTER();
3295
3296 if (wlan_hdd_validate_context(pHddCtx))
3297 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303298 return;
3299 }
3300
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303301 if (!pMsg)
3302 {
3303 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3304 return;
3305 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303306
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303307 vos_spin_lock_acquire(&hdd_context_lock);
3308
3309 context = &pHddCtx->ext_scan_context;
3310 /* validate response received from target*/
3311 if (context->request_id != data->requestId)
3312 {
3313 vos_spin_lock_release(&hdd_context_lock);
3314 hddLog(LOGE,
3315 FL("Target response id did not match: request_id %d resposne_id %d"),
3316 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303317 return;
3318 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303319 else
3320 {
3321 context->capability_response = *data;
3322 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303323 }
3324
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303325 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303326
Dino Mycle6fb96c12014-06-10 11:52:40 +05303327 return;
3328}
3329
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303330/*
3331 * define short names for the global vendor params
3332 * used by wlan_hdd_send_ext_scan_capability()
3333 */
3334#define PARAM_REQUEST_ID \
3335 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3336#define PARAM_STATUS \
3337 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
3338#define MAX_SCAN_CACHE_SIZE \
3339 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
3340#define MAX_SCAN_BUCKETS \
3341 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
3342#define MAX_AP_CACHE_PER_SCAN \
3343 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
3344#define MAX_RSSI_SAMPLE_SIZE \
3345 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
3346#define MAX_SCAN_RPT_THRHOLD \
3347 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
3348#define MAX_HOTLIST_BSSIDS \
3349 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
3350#define MAX_BSSID_HISTORY_ENTRIES \
3351 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
3352#define MAX_HOTLIST_SSIDS \
3353 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303354#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
3355 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303356
3357static int wlan_hdd_send_ext_scan_capability(void *ctx)
3358{
3359 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3360 struct sk_buff *skb = NULL;
3361 int ret;
3362 tSirEXTScanCapabilitiesEvent *data;
3363 tANI_U32 nl_buf_len;
3364
3365 ret = wlan_hdd_validate_context(pHddCtx);
3366 if (0 != ret)
3367 {
3368 return ret;
3369 }
3370
3371 data = &(pHddCtx->ext_scan_context.capability_response);
3372
3373 nl_buf_len = NLMSG_HDRLEN;
3374 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
3375 (sizeof(data->status) + NLA_HDRLEN) +
3376 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
3377 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
3378 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
3379 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
3380 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
3381 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
3382 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
3383 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
3384
3385 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
3386
3387 if (!skb)
3388 {
3389 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
3390 return -ENOMEM;
3391 }
3392
3393 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
3394 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
3395 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
3396 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
3397 data->maxRssiSampleSize, data->maxScanReportingThreshold);
3398 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
3399 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
3400 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
3401
3402 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
3403 nla_put_u32(skb, PARAM_STATUS, data->status) ||
3404 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
3405 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
3406 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
3407 data->maxApPerScan) ||
3408 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
3409 data->maxRssiSampleSize) ||
3410 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
3411 data->maxScanReportingThreshold) ||
3412 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
3413 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
3414 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303415 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
3416 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303417 {
3418 hddLog(LOGE, FL("nla put fail"));
3419 goto nla_put_failure;
3420 }
3421
3422 cfg80211_vendor_cmd_reply(skb);
3423 return 0;
3424
3425nla_put_failure:
3426 kfree_skb(skb);
3427 return -EINVAL;;
3428}
3429
3430/*
3431 * done with short names for the global vendor params
3432 * used by wlan_hdd_send_ext_scan_capability()
3433 */
3434#undef PARAM_REQUEST_ID
3435#undef PARAM_STATUS
3436#undef MAX_SCAN_CACHE_SIZE
3437#undef MAX_SCAN_BUCKETS
3438#undef MAX_AP_CACHE_PER_SCAN
3439#undef MAX_RSSI_SAMPLE_SIZE
3440#undef MAX_SCAN_RPT_THRHOLD
3441#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303442#undef MAX_BSSID_HISTORY_ENTRIES
3443#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05303444
3445static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
3446{
3447 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
3448 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303449 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303450 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303451
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303452 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303453
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303454 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303455 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303456
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303457 if (!pMsg)
3458 {
3459 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460 return;
3461 }
3462
Dino Mycle6fb96c12014-06-10 11:52:40 +05303463 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3464 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
3465
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303466 context = &pHddCtx->ext_scan_context;
3467 spin_lock(&hdd_context_lock);
3468 if (context->request_id == pData->requestId) {
3469 context->response_status = pData->status ? -EINVAL : 0;
3470 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303471 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303472 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303473
3474 /*
3475 * Store the Request ID for comparing with the requestID obtained
3476 * in other requests.HDD shall return a failure is the extscan_stop
3477 * request is issued with a different requestId as that of the
3478 * extscan_start request. Also, This requestId shall be used while
3479 * indicating the full scan results to the upper layers.
3480 * The requestId is stored with the assumption that the firmware
3481 * shall return the ext scan start request's requestId in ext scan
3482 * start response.
3483 */
3484 if (pData->status == 0)
3485 pMac->sme.extScanStartReqId = pData->requestId;
3486
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303487 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303488 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303489}
3490
3491
3492static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
3493{
3494 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
3495 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303496 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303497
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303498 ENTER();
3499
3500 if (wlan_hdd_validate_context(pHddCtx)){
3501 return;
3502 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303503
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303504 if (!pMsg)
3505 {
3506 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303507 return;
3508 }
3509
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303510 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3511 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303512
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303513 context = &pHddCtx->ext_scan_context;
3514 spin_lock(&hdd_context_lock);
3515 if (context->request_id == pData->requestId) {
3516 context->response_status = pData->status ? -EINVAL : 0;
3517 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303518 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303519 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303520
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303521 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303522 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303523}
3524
Dino Mycle6fb96c12014-06-10 11:52:40 +05303525static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3526 void *pMsg)
3527{
3528 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303529 tpSirEXTScanSetBssidHotListRspParams pData =
3530 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303531 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303532
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303533 ENTER();
3534
3535 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303536 return;
3537 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303538
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303539 if (!pMsg)
3540 {
3541 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3542 return;
3543 }
3544
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303545 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3546 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303547
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303548 context = &pHddCtx->ext_scan_context;
3549 spin_lock(&hdd_context_lock);
3550 if (context->request_id == pData->requestId) {
3551 context->response_status = pData->status ? -EINVAL : 0;
3552 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303553 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303554 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303555
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303556 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303557 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303558}
3559
3560static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3561 void *pMsg)
3562{
3563 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303564 tpSirEXTScanResetBssidHotlistRspParams pData =
3565 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303566 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303567
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303568 ENTER();
3569
3570 if (wlan_hdd_validate_context(pHddCtx)) {
3571 return;
3572 }
3573 if (!pMsg)
3574 {
3575 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303576 return;
3577 }
3578
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303579 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3580 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303581
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303582 context = &pHddCtx->ext_scan_context;
3583 spin_lock(&hdd_context_lock);
3584 if (context->request_id == pData->requestId) {
3585 context->response_status = pData->status ? -EINVAL : 0;
3586 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303587 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303588 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303589
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303590 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303591 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303592}
3593
Dino Mycle6fb96c12014-06-10 11:52:40 +05303594static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3595 void *pMsg)
3596{
3597 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3598 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303599 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303600 tANI_S32 totalResults;
3601 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303602 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3603 struct hdd_ext_scan_context *context;
3604 bool ignore_cached_results = false;
3605 tExtscanCachedScanResult *result;
3606 struct nlattr *nla_results;
3607 tANI_U16 ieLength= 0;
3608 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303609
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303610 ENTER();
3611
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303612 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303613 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303614
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303615 if (!pMsg)
3616 {
3617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3618 return;
3619 }
3620
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303621 spin_lock(&hdd_context_lock);
3622 context = &pHddCtx->ext_scan_context;
3623 ignore_cached_results = context->ignore_cached_results;
3624 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303625
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303626 if (ignore_cached_results) {
3627 hddLog(LOGE,
3628 FL("Ignore the cached results received after timeout"));
3629 return;
3630 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303631
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303632 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3633 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303634
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303635 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303636
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303637 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3638 scan_id_index++) {
3639 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303640
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303641 totalResults = result->num_results;
3642 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3643 result->scan_id, result->flags, totalResults);
3644 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303645
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303646 do{
3647 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3648 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3649 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303650
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303651 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3652 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3653
3654 if (!skb) {
3655 hddLog(VOS_TRACE_LEVEL_ERROR,
3656 FL("cfg80211_vendor_event_alloc failed"));
3657 return;
3658 }
3659
3660 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3661
3662 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3663 pData->requestId) ||
3664 nla_put_u32(skb,
3665 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3666 resultsPerEvent)) {
3667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3668 goto fail;
3669 }
3670 if (nla_put_u8(skb,
3671 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3672 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303673 {
3674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3675 goto fail;
3676 }
3677
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303678 if (nla_put_u32(skb,
3679 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3680 result->scan_id)) {
3681 hddLog(LOGE, FL("put fail"));
3682 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303683 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303684
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303685 nla_results = nla_nest_start(skb,
3686 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3687 if (!nla_results)
3688 goto fail;
3689
3690 if (resultsPerEvent) {
3691 struct nlattr *aps;
3692 struct nlattr *nla_result;
3693
3694 nla_result = nla_nest_start(skb, scan_id_index);
3695 if(!nla_result)
3696 goto fail;
3697
3698 if (nla_put_u32(skb,
3699 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3700 result->scan_id) ||
3701 nla_put_u32(skb,
3702 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3703 result->flags) ||
3704 nla_put_u32(skb,
3705 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3706 totalResults)) {
3707 hddLog(LOGE, FL("put fail"));
3708 goto fail;
3709 }
3710
3711 aps = nla_nest_start(skb,
3712 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3713 if (!aps)
3714 {
3715 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3716 goto fail;
3717 }
3718
3719 head_ptr = (tpSirWifiScanResult) &(result->ap);
3720
3721 for (j = 0; j < resultsPerEvent; j++, i++) {
3722 struct nlattr *ap;
3723 pSirWifiScanResult = head_ptr + i;
3724
3725 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303726 * Firmware returns timestamp from extscan_start till
3727 * BSSID was cached (in micro seconds). Add this with
3728 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303729 * to derive the time since boot when the
3730 * BSSID was cached.
3731 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303732 pSirWifiScanResult->ts +=
3733 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303734 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3735 "Ssid (%s)"
3736 "Bssid: %pM "
3737 "Channel (%u)"
3738 "Rssi (%d)"
3739 "RTT (%u)"
3740 "RTT_SD (%u)"
3741 "Beacon Period %u"
3742 "Capability 0x%x "
3743 "Ie length %d",
3744 i,
3745 pSirWifiScanResult->ts,
3746 pSirWifiScanResult->ssid,
3747 pSirWifiScanResult->bssid,
3748 pSirWifiScanResult->channel,
3749 pSirWifiScanResult->rssi,
3750 pSirWifiScanResult->rtt,
3751 pSirWifiScanResult->rtt_sd,
3752 pSirWifiScanResult->beaconPeriod,
3753 pSirWifiScanResult->capability,
3754 ieLength);
3755
3756 ap = nla_nest_start(skb, j + 1);
3757 if (!ap)
3758 {
3759 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3760 goto fail;
3761 }
3762
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303763 if (hdd_wlan_nla_put_u64(skb,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303764 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3765 pSirWifiScanResult->ts) )
3766 {
3767 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3768 goto fail;
3769 }
3770 if (nla_put(skb,
3771 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3772 sizeof(pSirWifiScanResult->ssid),
3773 pSirWifiScanResult->ssid) )
3774 {
3775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3776 goto fail;
3777 }
3778 if (nla_put(skb,
3779 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3780 sizeof(pSirWifiScanResult->bssid),
3781 pSirWifiScanResult->bssid) )
3782 {
3783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3784 goto fail;
3785 }
3786 if (nla_put_u32(skb,
3787 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3788 pSirWifiScanResult->channel) )
3789 {
3790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3791 goto fail;
3792 }
3793 if (nla_put_s32(skb,
3794 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3795 pSirWifiScanResult->rssi) )
3796 {
3797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3798 goto fail;
3799 }
3800 if (nla_put_u32(skb,
3801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3802 pSirWifiScanResult->rtt) )
3803 {
3804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3805 goto fail;
3806 }
3807 if (nla_put_u32(skb,
3808 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3809 pSirWifiScanResult->rtt_sd))
3810 {
3811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3812 goto fail;
3813 }
3814 if (nla_put_u32(skb,
3815 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3816 pSirWifiScanResult->beaconPeriod))
3817 {
3818 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3819 goto fail;
3820 }
3821 if (nla_put_u32(skb,
3822 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3823 pSirWifiScanResult->capability))
3824 {
3825 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3826 goto fail;
3827 }
3828 if (nla_put_u32(skb,
3829 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3830 ieLength))
3831 {
3832 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3833 goto fail;
3834 }
3835
3836 if (ieLength)
3837 if (nla_put(skb,
3838 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3839 ieLength, ie)) {
3840 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3841 goto fail;
3842 }
3843
3844 nla_nest_end(skb, ap);
3845 }
3846 nla_nest_end(skb, aps);
3847 nla_nest_end(skb, nla_result);
3848 }
3849
3850 nla_nest_end(skb, nla_results);
3851
3852 cfg80211_vendor_cmd_reply(skb);
3853
3854 } while (totalResults > 0);
3855 }
3856
3857 if (!pData->moreData) {
3858 spin_lock(&hdd_context_lock);
3859 context->response_status = 0;
3860 complete(&context->response_event);
3861 spin_unlock(&hdd_context_lock);
3862 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303863
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303864 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303865 return;
3866fail:
3867 kfree_skb(skb);
3868 return;
3869}
3870
3871static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3872 void *pMsg)
3873{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303874 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303875 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3876 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303877 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303878
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303879 ENTER();
3880
3881 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303882 hddLog(LOGE,
3883 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303884 return;
3885 }
3886 if (!pMsg)
3887 {
3888 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303889 return;
3890 }
3891
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303892 if (pData->bss_found)
3893 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3894 else
3895 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3896
Dino Mycle6fb96c12014-06-10 11:52:40 +05303897 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303898#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3899 NULL,
3900#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303901 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303902 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303903
3904 if (!skb) {
3905 hddLog(VOS_TRACE_LEVEL_ERROR,
3906 FL("cfg80211_vendor_event_alloc failed"));
3907 return;
3908 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303909
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303910 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3911 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3912 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3913 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3914
3915 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303916 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3917 "Ssid (%s) "
3918 "Bssid (" MAC_ADDRESS_STR ") "
3919 "Channel (%u) "
3920 "Rssi (%d) "
3921 "RTT (%u) "
3922 "RTT_SD (%u) ",
3923 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303924 pData->bssHotlist[i].ts,
3925 pData->bssHotlist[i].ssid,
3926 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3927 pData->bssHotlist[i].channel,
3928 pData->bssHotlist[i].rssi,
3929 pData->bssHotlist[i].rtt,
3930 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303931 }
3932
3933 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3934 pData->requestId) ||
3935 nla_put_u32(skb,
3936 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303937 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3939 goto fail;
3940 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303941 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303942 struct nlattr *aps;
3943
3944 aps = nla_nest_start(skb,
3945 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3946 if (!aps)
3947 goto fail;
3948
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303949 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303950 struct nlattr *ap;
3951
3952 ap = nla_nest_start(skb, i + 1);
3953 if (!ap)
3954 goto fail;
3955
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303956 if (hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303957 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303958 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303959 nla_put(skb,
3960 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303961 sizeof(pData->bssHotlist[i].ssid),
3962 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303963 nla_put(skb,
3964 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303965 sizeof(pData->bssHotlist[i].bssid),
3966 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303967 nla_put_u32(skb,
3968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303969 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303970 nla_put_s32(skb,
3971 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303972 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303973 nla_put_u32(skb,
3974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303975 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303976 nla_put_u32(skb,
3977 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303978 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303979 goto fail;
3980
3981 nla_nest_end(skb, ap);
3982 }
3983 nla_nest_end(skb, aps);
3984
3985 if (nla_put_u8(skb,
3986 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3987 pData->moreData))
3988 goto fail;
3989 }
3990
3991 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303992 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303993 return;
3994
3995fail:
3996 kfree_skb(skb);
3997 return;
3998
3999}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304000
4001static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
4002 void *pMsg)
4003{
4004 struct sk_buff *skb;
4005 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4006 tpSirWifiFullScanResultEvent pData =
4007 (tpSirWifiFullScanResultEvent) (pMsg);
4008
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304009 ENTER();
4010
4011 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304012 hddLog(LOGE,
4013 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304014 return;
4015 }
4016 if (!pMsg)
4017 {
4018 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304019 return;
4020 }
4021
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304022 /*
4023 * If the full scan result including IE data exceeds NL 4K size
4024 * limitation, drop that beacon/probe rsp frame.
4025 */
4026 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
4027 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
4028 return;
4029 }
4030
Dino Mycle6fb96c12014-06-10 11:52:40 +05304031 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304032#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4033 NULL,
4034#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304035 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4036 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
4037 GFP_KERNEL);
4038
4039 if (!skb) {
4040 hddLog(VOS_TRACE_LEVEL_ERROR,
4041 FL("cfg80211_vendor_event_alloc failed"));
4042 return;
4043 }
4044
Dino Mycle6fb96c12014-06-10 11:52:40 +05304045 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
4046 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
4047 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
4048 "Ssid (%s)"
4049 "Bssid (" MAC_ADDRESS_STR ")"
4050 "Channel (%u)"
4051 "Rssi (%d)"
4052 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304053 "RTT_SD (%u)"
4054 "Bcn Period %d"
4055 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05304056 pData->ap.ts,
4057 pData->ap.ssid,
4058 MAC_ADDR_ARRAY(pData->ap.bssid),
4059 pData->ap.channel,
4060 pData->ap.rssi,
4061 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304062 pData->ap.rtt_sd,
4063 pData->ap.beaconPeriod,
4064 pData->ap.capability);
4065
Dino Mycle6fb96c12014-06-10 11:52:40 +05304066 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
4067 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4068 pData->requestId) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304069 hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304070 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
4071 pData->ap.ts) ||
4072 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
4073 sizeof(pData->ap.ssid),
4074 pData->ap.ssid) ||
4075 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
4076 WNI_CFG_BSSID_LEN,
4077 pData->ap.bssid) ||
4078 nla_put_u32(skb,
4079 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
4080 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05304081 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304082 pData->ap.rssi) ||
4083 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
4084 pData->ap.rtt) ||
4085 nla_put_u32(skb,
4086 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
4087 pData->ap.rtt_sd) ||
4088 nla_put_u16(skb,
4089 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
4090 pData->ap.beaconPeriod) ||
4091 nla_put_u16(skb,
4092 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
4093 pData->ap.capability) ||
4094 nla_put_u32(skb,
4095 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304096 pData->ieLength) ||
4097 nla_put_u8(skb,
4098 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
4099 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304100 {
4101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4102 goto nla_put_failure;
4103 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304104
4105 if (pData->ieLength) {
4106 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
4107 pData->ieLength,
4108 pData->ie))
4109 {
4110 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4111 goto nla_put_failure;
4112 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304113 }
4114
4115 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304116 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304117 return;
4118
4119nla_put_failure:
4120 kfree_skb(skb);
4121 return;
4122}
4123
4124static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
4125 void *pMsg)
4126{
4127 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4128 struct sk_buff *skb = NULL;
4129 tpSirEXTScanResultsAvailableIndParams pData =
4130 (tpSirEXTScanResultsAvailableIndParams) pMsg;
4131
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304132 ENTER();
4133
4134 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304135 hddLog(LOGE,
4136 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304137 return;
4138 }
4139 if (!pMsg)
4140 {
4141 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304142 return;
4143 }
4144
4145 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304146#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4147 NULL,
4148#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304149 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4150 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
4151 GFP_KERNEL);
4152
4153 if (!skb) {
4154 hddLog(VOS_TRACE_LEVEL_ERROR,
4155 FL("cfg80211_vendor_event_alloc failed"));
4156 return;
4157 }
4158
Dino Mycle6fb96c12014-06-10 11:52:40 +05304159 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
4160 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
4161 pData->numResultsAvailable);
4162 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4163 pData->requestId) ||
4164 nla_put_u32(skb,
4165 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
4166 pData->numResultsAvailable)) {
4167 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4168 goto nla_put_failure;
4169 }
4170
4171 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304172 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304173 return;
4174
4175nla_put_failure:
4176 kfree_skb(skb);
4177 return;
4178}
4179
4180static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
4181{
4182 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4183 struct sk_buff *skb = NULL;
4184 tpSirEXTScanProgressIndParams pData =
4185 (tpSirEXTScanProgressIndParams) pMsg;
4186
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304187 ENTER();
4188
4189 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304190 hddLog(LOGE,
4191 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304192 return;
4193 }
4194 if (!pMsg)
4195 {
4196 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304197 return;
4198 }
4199
4200 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304201#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4202 NULL,
4203#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304204 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4205 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
4206 GFP_KERNEL);
4207
4208 if (!skb) {
4209 hddLog(VOS_TRACE_LEVEL_ERROR,
4210 FL("cfg80211_vendor_event_alloc failed"));
4211 return;
4212 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304213 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304214 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
4215 pData->extScanEventType);
4216 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
4217 pData->status);
4218
4219 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
4220 pData->extScanEventType) ||
4221 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05304222 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4223 pData->requestId) ||
4224 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304225 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
4226 pData->status)) {
4227 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4228 goto nla_put_failure;
4229 }
4230
4231 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304232 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304233 return;
4234
4235nla_put_failure:
4236 kfree_skb(skb);
4237 return;
4238}
4239
4240void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
4241 void *pMsg)
4242{
4243 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4244
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304245 ENTER();
4246
Dino Mycle6fb96c12014-06-10 11:52:40 +05304247 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304248 return;
4249 }
4250
4251 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
4252
4253
4254 switch(evType) {
4255 case SIR_HAL_EXTSCAN_START_RSP:
4256 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
4257 break;
4258
4259 case SIR_HAL_EXTSCAN_STOP_RSP:
4260 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
4261 break;
4262 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
4263 /* There is no need to send this response to upper layer
4264 Just log the message */
4265 hddLog(VOS_TRACE_LEVEL_INFO,
4266 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
4267 break;
4268 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
4269 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
4270 break;
4271
4272 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
4273 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
4274 break;
4275
Dino Mycle6fb96c12014-06-10 11:52:40 +05304276 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304277 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304278 break;
4279 case SIR_HAL_EXTSCAN_PROGRESS_IND:
4280 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
4281 break;
4282 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
4283 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
4284 break;
4285 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
4286 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
4287 break;
4288 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
4289 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
4290 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304291 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
4292 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
4293 break;
4294 default:
4295 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
4296 break;
4297 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304298 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304299}
4300
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304301static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4302 struct wireless_dev *wdev,
4303 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304304{
Dino Myclee8843b32014-07-04 14:21:45 +05304305 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304306 struct net_device *dev = wdev->netdev;
4307 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4308 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4309 struct nlattr
4310 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4311 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304312 struct hdd_ext_scan_context *context;
4313 unsigned long rc;
4314 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304315
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304316 ENTER();
4317
Dino Mycle6fb96c12014-06-10 11:52:40 +05304318 status = wlan_hdd_validate_context(pHddCtx);
4319 if (0 != status)
4320 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304321 return -EINVAL;
4322 }
Dino Myclee8843b32014-07-04 14:21:45 +05304323 /* check the EXTScan Capability */
4324 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304325 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4326 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304327 {
4328 hddLog(VOS_TRACE_LEVEL_ERROR,
4329 FL("EXTScan not enabled/supported by Firmware"));
4330 return -EINVAL;
4331 }
4332
Dino Mycle6fb96c12014-06-10 11:52:40 +05304333 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4334 data, dataLen,
4335 wlan_hdd_extscan_config_policy)) {
4336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4337 return -EINVAL;
4338 }
4339
4340 /* Parse and fetch request Id */
4341 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4342 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4343 return -EINVAL;
4344 }
4345
Dino Myclee8843b32014-07-04 14:21:45 +05304346 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304347 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304348 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304349
Dino Myclee8843b32014-07-04 14:21:45 +05304350 reqMsg.sessionId = pAdapter->sessionId;
4351 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304352
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304353 vos_spin_lock_acquire(&hdd_context_lock);
4354 context = &pHddCtx->ext_scan_context;
4355 context->request_id = reqMsg.requestId;
4356 INIT_COMPLETION(context->response_event);
4357 vos_spin_lock_release(&hdd_context_lock);
4358
Dino Myclee8843b32014-07-04 14:21:45 +05304359 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304360 if (!HAL_STATUS_SUCCESS(status)) {
4361 hddLog(VOS_TRACE_LEVEL_ERROR,
4362 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304363 return -EINVAL;
4364 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304365
4366 rc = wait_for_completion_timeout(&context->response_event,
4367 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4368 if (!rc) {
4369 hddLog(LOGE, FL("Target response timed out"));
4370 return -ETIMEDOUT;
4371 }
4372
4373 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
4374 if (ret)
4375 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
4376
4377 return ret;
4378
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304379 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304380 return 0;
4381}
4382
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304383static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4384 struct wireless_dev *wdev,
4385 const void *data, int dataLen)
4386{
4387 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304388
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304389 vos_ssr_protect(__func__);
4390 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
4391 vos_ssr_unprotect(__func__);
4392
4393 return ret;
4394}
4395
4396static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4397 struct wireless_dev *wdev,
4398 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304399{
Dino Myclee8843b32014-07-04 14:21:45 +05304400 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304401 struct net_device *dev = wdev->netdev;
4402 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4403 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4404 struct nlattr
4405 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4406 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304407 struct hdd_ext_scan_context *context;
4408 unsigned long rc;
4409 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304410
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304411 ENTER();
4412
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304413 if (VOS_FTM_MODE == hdd_get_conparam()) {
4414 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4415 return -EINVAL;
4416 }
4417
Dino Mycle6fb96c12014-06-10 11:52:40 +05304418 status = wlan_hdd_validate_context(pHddCtx);
4419 if (0 != status)
4420 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304421 return -EINVAL;
4422 }
Dino Myclee8843b32014-07-04 14:21:45 +05304423 /* check the EXTScan Capability */
4424 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304425 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4426 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304427 {
4428 hddLog(VOS_TRACE_LEVEL_ERROR,
4429 FL("EXTScan not enabled/supported by Firmware"));
4430 return -EINVAL;
4431 }
4432
Dino Mycle6fb96c12014-06-10 11:52:40 +05304433 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4434 data, dataLen,
4435 wlan_hdd_extscan_config_policy)) {
4436 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4437 return -EINVAL;
4438 }
4439 /* Parse and fetch request Id */
4440 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4441 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4442 return -EINVAL;
4443 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304444
Dino Myclee8843b32014-07-04 14:21:45 +05304445 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304446 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4447
Dino Myclee8843b32014-07-04 14:21:45 +05304448 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304449
Dino Myclee8843b32014-07-04 14:21:45 +05304450 reqMsg.sessionId = pAdapter->sessionId;
4451 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304452
4453 /* Parse and fetch flush parameter */
4454 if (!tb
4455 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
4456 {
4457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
4458 goto failed;
4459 }
Dino Myclee8843b32014-07-04 14:21:45 +05304460 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304461 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
4462
Dino Myclee8843b32014-07-04 14:21:45 +05304463 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304464
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304465 spin_lock(&hdd_context_lock);
4466 context = &pHddCtx->ext_scan_context;
4467 context->request_id = reqMsg.requestId;
4468 context->ignore_cached_results = false;
4469 INIT_COMPLETION(context->response_event);
4470 spin_unlock(&hdd_context_lock);
4471
Dino Myclee8843b32014-07-04 14:21:45 +05304472 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304473 if (!HAL_STATUS_SUCCESS(status)) {
4474 hddLog(VOS_TRACE_LEVEL_ERROR,
4475 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304476 return -EINVAL;
4477 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304478
4479 rc = wait_for_completion_timeout(&context->response_event,
4480 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4481 if (!rc) {
4482 hddLog(LOGE, FL("Target response timed out"));
4483 retval = -ETIMEDOUT;
4484 spin_lock(&hdd_context_lock);
4485 context->ignore_cached_results = true;
4486 spin_unlock(&hdd_context_lock);
4487 } else {
4488 spin_lock(&hdd_context_lock);
4489 retval = context->response_status;
4490 spin_unlock(&hdd_context_lock);
4491 }
4492
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304493 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304494 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304495
4496failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05304497 return -EINVAL;
4498}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304499static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4500 struct wireless_dev *wdev,
4501 const void *data, int dataLen)
4502{
4503 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304504
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304505 vos_ssr_protect(__func__);
4506 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
4507 vos_ssr_unprotect(__func__);
4508
4509 return ret;
4510}
4511
4512static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304513 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05304514 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304515{
4516 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
4517 struct net_device *dev = wdev->netdev;
4518 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4519 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4520 struct nlattr
4521 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4522 struct nlattr
4523 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4524 struct nlattr *apTh;
4525 eHalStatus status;
4526 tANI_U8 i = 0;
4527 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304528 struct hdd_ext_scan_context *context;
4529 tANI_U32 request_id;
4530 unsigned long rc;
4531 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304532
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304533 ENTER();
4534
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304535 if (VOS_FTM_MODE == hdd_get_conparam()) {
4536 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4537 return -EINVAL;
4538 }
4539
Dino Mycle6fb96c12014-06-10 11:52:40 +05304540 status = wlan_hdd_validate_context(pHddCtx);
4541 if (0 != status)
4542 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304543 return -EINVAL;
4544 }
Dino Myclee8843b32014-07-04 14:21:45 +05304545 /* check the EXTScan Capability */
4546 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304547 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4548 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304549 {
4550 hddLog(VOS_TRACE_LEVEL_ERROR,
4551 FL("EXTScan not enabled/supported by Firmware"));
4552 return -EINVAL;
4553 }
4554
Dino Mycle6fb96c12014-06-10 11:52:40 +05304555 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4556 data, dataLen,
4557 wlan_hdd_extscan_config_policy)) {
4558 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4559 return -EINVAL;
4560 }
4561
4562 /* Parse and fetch request Id */
4563 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4564 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4565 return -EINVAL;
4566 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304567 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4568 vos_mem_malloc(sizeof(*pReqMsg));
4569 if (!pReqMsg) {
4570 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4571 return -ENOMEM;
4572 }
4573
Dino Myclee8843b32014-07-04 14:21:45 +05304574
Dino Mycle6fb96c12014-06-10 11:52:40 +05304575 pReqMsg->requestId = nla_get_u32(
4576 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4577 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4578
4579 /* Parse and fetch number of APs */
4580 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4582 goto fail;
4583 }
4584
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304585 /* Parse and fetch lost ap sample size */
4586 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4587 hddLog(LOGE, FL("attr lost ap sample size failed"));
4588 goto fail;
4589 }
4590
4591 pReqMsg->lostBssidSampleSize = nla_get_u32(
4592 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4593 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4594
Dino Mycle6fb96c12014-06-10 11:52:40 +05304595 pReqMsg->sessionId = pAdapter->sessionId;
4596 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4597
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304598 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304599 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304600 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4601 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4602 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4603 goto fail;
4604 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304605 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304606
4607 nla_for_each_nested(apTh,
4608 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304609 if (i == pReqMsg->numBssid) {
4610 hddLog(LOGW, FL("Ignoring excess AP"));
4611 break;
4612 }
4613
Dino Mycle6fb96c12014-06-10 11:52:40 +05304614 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4615 nla_data(apTh), nla_len(apTh),
4616 NULL)) {
4617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4618 goto fail;
4619 }
4620
4621 /* Parse and fetch MAC address */
4622 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4623 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4624 goto fail;
4625 }
4626 memcpy(pReqMsg->ap[i].bssid, nla_data(
4627 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4628 sizeof(tSirMacAddr));
4629 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4630
4631 /* Parse and fetch low RSSI */
4632 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4633 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4634 goto fail;
4635 }
4636 pReqMsg->ap[i].low = nla_get_s32(
4637 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4638 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4639
4640 /* Parse and fetch high RSSI */
4641 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4642 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4643 goto fail;
4644 }
4645 pReqMsg->ap[i].high = nla_get_s32(
4646 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4647 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4648 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304649 i++;
4650 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304651
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304652 if (i < pReqMsg->numBssid) {
4653 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4654 i, pReqMsg->numBssid);
4655 pReqMsg->numBssid = i;
4656 }
4657
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304658 context = &pHddCtx->ext_scan_context;
4659 spin_lock(&hdd_context_lock);
4660 INIT_COMPLETION(context->response_event);
4661 context->request_id = request_id = pReqMsg->requestId;
4662 spin_unlock(&hdd_context_lock);
4663
Dino Mycle6fb96c12014-06-10 11:52:40 +05304664 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4665 if (!HAL_STATUS_SUCCESS(status)) {
4666 hddLog(VOS_TRACE_LEVEL_ERROR,
4667 FL("sme_SetBssHotlist failed(err=%d)"), status);
4668 vos_mem_free(pReqMsg);
4669 return -EINVAL;
4670 }
4671
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304672 /* request was sent -- wait for the response */
4673 rc = wait_for_completion_timeout(&context->response_event,
4674 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4675
4676 if (!rc) {
4677 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4678 retval = -ETIMEDOUT;
4679 } else {
4680 spin_lock(&hdd_context_lock);
4681 if (context->request_id == request_id)
4682 retval = context->response_status;
4683 else
4684 retval = -EINVAL;
4685 spin_unlock(&hdd_context_lock);
4686 }
4687
Dino Myclee8843b32014-07-04 14:21:45 +05304688 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304689 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304690 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304691
4692fail:
4693 vos_mem_free(pReqMsg);
4694 return -EINVAL;
4695}
4696
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304697static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4698 struct wireless_dev *wdev,
4699 const void *data, int dataLen)
4700{
4701 int ret = 0;
4702
4703 vos_ssr_protect(__func__);
4704 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4705 dataLen);
4706 vos_ssr_unprotect(__func__);
4707
4708 return ret;
4709}
4710
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304711static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304712 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304713 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304714{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304715 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4716 struct net_device *dev = wdev->netdev;
4717 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4718 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4719 uint8_t num_channels = 0;
4720 uint8_t num_chan_new = 0;
4721 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304722 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304723 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304724 tWifiBand wifiBand;
4725 eHalStatus status;
4726 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304727 tANI_U8 i,j,k;
4728 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304729
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304730 ENTER();
4731
Dino Mycle6fb96c12014-06-10 11:52:40 +05304732 status = wlan_hdd_validate_context(pHddCtx);
4733 if (0 != status)
4734 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304735 return -EINVAL;
4736 }
Dino Myclee8843b32014-07-04 14:21:45 +05304737
Dino Mycle6fb96c12014-06-10 11:52:40 +05304738 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4739 data, dataLen,
4740 wlan_hdd_extscan_config_policy)) {
4741 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4742 return -EINVAL;
4743 }
4744
4745 /* Parse and fetch request Id */
4746 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4747 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4748 return -EINVAL;
4749 }
4750 requestId = nla_get_u32(
4751 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4752 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4753
4754 /* Parse and fetch wifi band */
4755 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4756 {
4757 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4758 return -EINVAL;
4759 }
4760 wifiBand = nla_get_u32(
4761 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4762 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4763
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304764 /* Parse and fetch max channels */
4765 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4766 {
4767 hddLog(LOGE, FL("attr max channels failed"));
4768 return -EINVAL;
4769 }
4770 maxChannels = nla_get_u32(
4771 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4772 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4773
Dino Mycle6fb96c12014-06-10 11:52:40 +05304774 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304775 wifiBand, chan_list,
4776 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304777 if (eHAL_STATUS_SUCCESS != status) {
4778 hddLog(VOS_TRACE_LEVEL_ERROR,
4779 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4780 return -EINVAL;
4781 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304782
Agrawal Ashish16abf782016-08-18 22:42:59 +05304783 num_channels = VOS_MIN(num_channels, maxChannels);
4784 num_chan_new = num_channels;
4785 /* remove the indoor only channels if iface is SAP */
4786 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4787 {
4788 num_chan_new = 0;
4789 for (i = 0; i < num_channels; i++)
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304790 for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) {
Agrawal Ashish16abf782016-08-18 22:42:59 +05304791 if (wiphy->bands[j] == NULL)
4792 continue;
4793 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4794 if ((chan_list[i] ==
4795 wiphy->bands[j]->channels[k].center_freq) &&
4796 (!(wiphy->bands[j]->channels[k].flags &
4797 IEEE80211_CHAN_INDOOR_ONLY))) {
4798 chan_list[num_chan_new] = chan_list[i];
4799 num_chan_new++;
4800 }
4801 }
4802 }
4803 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304804
Agrawal Ashish16abf782016-08-18 22:42:59 +05304805 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4806 for (i = 0; i < num_chan_new; i++)
4807 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4808 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304809
4810 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304811 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304812 NLMSG_HDRLEN);
4813
4814 if (!replySkb) {
4815 hddLog(VOS_TRACE_LEVEL_ERROR,
4816 FL("valid channels: buffer alloc fail"));
4817 return -EINVAL;
4818 }
4819 if (nla_put_u32(replySkb,
4820 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304821 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304822 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304823 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304824
4825 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4826 kfree_skb(replySkb);
4827 return -EINVAL;
4828 }
4829
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304830 ret = cfg80211_vendor_cmd_reply(replySkb);
4831
4832 EXIT();
4833 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304834}
4835
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304836static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4837 struct wireless_dev *wdev,
4838 const void *data, int dataLen)
4839{
4840 int ret = 0;
4841
4842 vos_ssr_protect(__func__);
4843 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4844 dataLen);
4845 vos_ssr_unprotect(__func__);
4846
4847 return ret;
4848}
4849
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304850static int hdd_extscan_start_fill_bucket_channel_spec(
4851 hdd_context_t *pHddCtx,
4852 tpSirEXTScanStartReqParams pReqMsg,
4853 struct nlattr **tb)
4854{
4855 struct nlattr *bucket[
4856 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4857 struct nlattr *channel[
4858 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4859 struct nlattr *buckets;
4860 struct nlattr *channels;
4861 int rem1, rem2;
4862 eHalStatus status;
4863 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304864 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304865 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4866 tANI_U32 passive_max_chn_time, active_max_chn_time;
4867
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304868 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304869 bktIndex = 0;
4870
4871 nla_for_each_nested(buckets,
4872 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304873 if (bktIndex >= expected_buckets) {
4874 hddLog(LOGW, FL("ignoring excess buckets"));
4875 break;
4876 }
4877
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304878 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304879 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4880 nla_data(buckets), nla_len(buckets),
4881 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304882 hddLog(LOGE, FL("nla_parse failed"));
4883 return -EINVAL;
4884 }
4885
4886 /* Parse and fetch bucket spec */
4887 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4888 hddLog(LOGE, FL("attr bucket index failed"));
4889 return -EINVAL;
4890 }
4891 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4892 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4893 hddLog(LOG1, FL("Bucket spec Index %d"),
4894 pReqMsg->buckets[bktIndex].bucket);
4895
4896 /* Parse and fetch wifi band */
4897 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4898 hddLog(LOGE, FL("attr wifi band failed"));
4899 return -EINVAL;
4900 }
4901 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4902 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4903 hddLog(LOG1, FL("Wifi band %d"),
4904 pReqMsg->buckets[bktIndex].band);
4905
4906 /* Parse and fetch period */
4907 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4908 hddLog(LOGE, FL("attr period failed"));
4909 return -EINVAL;
4910 }
4911 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4912 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4913 hddLog(LOG1, FL("period %d"),
4914 pReqMsg->buckets[bktIndex].period);
4915
4916 /* Parse and fetch report events */
4917 if (!bucket[
4918 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4919 hddLog(LOGE, FL("attr report events failed"));
4920 return -EINVAL;
4921 }
4922 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4923 bucket[
4924 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4925 hddLog(LOG1, FL("report events %d"),
4926 pReqMsg->buckets[bktIndex].reportEvents);
4927
4928 /* Parse and fetch max period */
4929 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4930 hddLog(LOGE, FL("attr max period failed"));
4931 return -EINVAL;
4932 }
4933 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4934 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4935 hddLog(LOG1, FL("max period %u"),
4936 pReqMsg->buckets[bktIndex].max_period);
4937
4938 /* Parse and fetch exponent */
4939 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4940 hddLog(LOGE, FL("attr exponent failed"));
4941 return -EINVAL;
4942 }
4943 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4944 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4945 hddLog(LOG1, FL("exponent %u"),
4946 pReqMsg->buckets[bktIndex].exponent);
4947
4948 /* Parse and fetch step count */
4949 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4950 hddLog(LOGE, FL("attr step count failed"));
4951 return -EINVAL;
4952 }
4953 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4954 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4955 hddLog(LOG1, FL("Step count %u"),
4956 pReqMsg->buckets[bktIndex].step_count);
4957
4958 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4959 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4960
4961 /* Framework shall pass the channel list if the input WiFi band is
4962 * WIFI_BAND_UNSPECIFIED.
4963 * If the input WiFi band is specified (any value other than
4964 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4965 */
4966 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4967 numChannels = 0;
4968 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4969 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4970 pReqMsg->buckets[bktIndex].band,
4971 chanList, &numChannels);
4972 if (!HAL_STATUS_SUCCESS(status)) {
4973 hddLog(LOGE,
4974 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4975 status);
4976 return -EINVAL;
4977 }
4978
4979 pReqMsg->buckets[bktIndex].numChannels =
4980 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4981 hddLog(LOG1, FL("Num channels %d"),
4982 pReqMsg->buckets[bktIndex].numChannels);
4983
4984 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4985 j++) {
4986 pReqMsg->buckets[bktIndex].channels[j].channel =
4987 chanList[j];
4988 pReqMsg->buckets[bktIndex].channels[j].
4989 chnlClass = 0;
4990 if (CSR_IS_CHANNEL_DFS(
4991 vos_freq_to_chan(chanList[j]))) {
4992 pReqMsg->buckets[bktIndex].channels[j].
4993 passive = 1;
4994 pReqMsg->buckets[bktIndex].channels[j].
4995 dwellTimeMs = passive_max_chn_time;
4996 } else {
4997 pReqMsg->buckets[bktIndex].channels[j].
4998 passive = 0;
4999 pReqMsg->buckets[bktIndex].channels[j].
5000 dwellTimeMs = active_max_chn_time;
5001 }
5002
5003 hddLog(LOG1,
5004 "Channel %u Passive %u Dwell time %u ms",
5005 pReqMsg->buckets[bktIndex].channels[j].channel,
5006 pReqMsg->buckets[bktIndex].channels[j].passive,
5007 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5008 }
5009
5010 bktIndex++;
5011 continue;
5012 }
5013
5014 /* Parse and fetch number of channels */
5015 if (!bucket[
5016 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
5017 hddLog(LOGE, FL("attr num channels failed"));
5018 return -EINVAL;
5019 }
5020
5021 pReqMsg->buckets[bktIndex].numChannels =
5022 nla_get_u32(bucket[
5023 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
5024 hddLog(LOG1, FL("num channels %d"),
5025 pReqMsg->buckets[bktIndex].numChannels);
5026
5027 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
5028 hddLog(LOGE, FL("attr channel spec failed"));
5029 return -EINVAL;
5030 }
5031
5032 j = 0;
5033 nla_for_each_nested(channels,
5034 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
5035 if (nla_parse(channel,
5036 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5037 nla_data(channels), nla_len(channels),
5038 wlan_hdd_extscan_config_policy)) {
5039 hddLog(LOGE, FL("nla_parse failed"));
5040 return -EINVAL;
5041 }
5042
5043 /* Parse and fetch channel */
5044 if (!channel[
5045 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
5046 hddLog(LOGE, FL("attr channel failed"));
5047 return -EINVAL;
5048 }
5049 pReqMsg->buckets[bktIndex].channels[j].channel =
5050 nla_get_u32(channel[
5051 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
5052 hddLog(LOG1, FL("channel %u"),
5053 pReqMsg->buckets[bktIndex].channels[j].channel);
5054
5055 /* Parse and fetch dwell time */
5056 if (!channel[
5057 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
5058 hddLog(LOGE, FL("attr dwelltime failed"));
5059 return -EINVAL;
5060 }
5061 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
5062 nla_get_u32(channel[
5063 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
5064
5065 hddLog(LOG1, FL("Dwell time (%u ms)"),
5066 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5067
5068
5069 /* Parse and fetch channel spec passive */
5070 if (!channel[
5071 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
5072 hddLog(LOGE,
5073 FL("attr channel spec passive failed"));
5074 return -EINVAL;
5075 }
5076 pReqMsg->buckets[bktIndex].channels[j].passive =
5077 nla_get_u8(channel[
5078 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
5079 hddLog(LOG1, FL("Chnl spec passive %u"),
5080 pReqMsg->buckets[bktIndex].channels[j].passive);
5081
5082 j++;
5083 }
5084
5085 bktIndex++;
5086 }
5087
5088 return 0;
5089}
5090
5091
5092/*
5093 * define short names for the global vendor params
5094 * used by wlan_hdd_cfg80211_extscan_start()
5095 */
5096#define PARAM_MAX \
5097QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
5098#define PARAM_REQUEST_ID \
5099QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
5100#define PARAM_BASE_PERIOD \
5101QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
5102#define PARAM_MAX_AP_PER_SCAN \
5103QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
5104#define PARAM_RPT_THRHLD_PERCENT \
5105QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
5106#define PARAM_RPT_THRHLD_NUM_SCANS \
5107QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
5108#define PARAM_NUM_BUCKETS \
5109QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
5110
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305111static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305112 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305113 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305114{
Dino Myclee8843b32014-07-04 14:21:45 +05305115 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305116 struct net_device *dev = wdev->netdev;
5117 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5118 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5119 struct nlattr *tb[PARAM_MAX + 1];
5120 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305121 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305122 tANI_U32 request_id;
5123 struct hdd_ext_scan_context *context;
5124 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305125
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305126 ENTER();
5127
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305128 if (VOS_FTM_MODE == hdd_get_conparam()) {
5129 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5130 return -EINVAL;
5131 }
5132
Dino Mycle6fb96c12014-06-10 11:52:40 +05305133 status = wlan_hdd_validate_context(pHddCtx);
5134 if (0 != status)
5135 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305136 return -EINVAL;
5137 }
Dino Myclee8843b32014-07-04 14:21:45 +05305138 /* check the EXTScan Capability */
5139 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305140 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5141 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305142 {
5143 hddLog(VOS_TRACE_LEVEL_ERROR,
5144 FL("EXTScan not enabled/supported by Firmware"));
5145 return -EINVAL;
5146 }
5147
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305148 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305149 data, dataLen,
5150 wlan_hdd_extscan_config_policy)) {
5151 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5152 return -EINVAL;
5153 }
5154
5155 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305156 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305157 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5158 return -EINVAL;
5159 }
5160
Dino Myclee8843b32014-07-04 14:21:45 +05305161 pReqMsg = (tpSirEXTScanStartReqParams)
5162 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305163 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305164 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5165 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305166 }
5167
5168 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305169 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305170 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5171
5172 pReqMsg->sessionId = pAdapter->sessionId;
5173 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5174
5175 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305176 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305177 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5178 goto fail;
5179 }
5180 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305181 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305182 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5183 pReqMsg->basePeriod);
5184
5185 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305186 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305187 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5188 goto fail;
5189 }
5190 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305191 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305192 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5193 pReqMsg->maxAPperScan);
5194
5195 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305196 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305197 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5198 goto fail;
5199 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305200 pReqMsg->reportThresholdPercent = nla_get_u8(
5201 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305202 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305203 pReqMsg->reportThresholdPercent);
5204
5205 /* Parse and fetch report threshold num scans */
5206 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5207 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5208 goto fail;
5209 }
5210 pReqMsg->reportThresholdNumScans = nla_get_u8(
5211 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5212 hddLog(LOG1, FL("Report Threshold num scans %d"),
5213 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305214
5215 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305216 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305217 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5218 goto fail;
5219 }
5220 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305221 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305222 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5223 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5224 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5225 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5226 }
5227 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5228 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305229
Dino Mycle6fb96c12014-06-10 11:52:40 +05305230 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5231 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5232 goto fail;
5233 }
5234
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305235 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305236
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305237 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5238 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305239
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305240 context = &pHddCtx->ext_scan_context;
5241 spin_lock(&hdd_context_lock);
5242 INIT_COMPLETION(context->response_event);
5243 context->request_id = request_id = pReqMsg->requestId;
5244 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305245
Dino Mycle6fb96c12014-06-10 11:52:40 +05305246 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5247 if (!HAL_STATUS_SUCCESS(status)) {
5248 hddLog(VOS_TRACE_LEVEL_ERROR,
5249 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305250 goto fail;
5251 }
5252
Srinivas Dasari91727c12016-03-23 17:59:06 +05305253 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5254
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305255 /* request was sent -- wait for the response */
5256 rc = wait_for_completion_timeout(&context->response_event,
5257 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5258
5259 if (!rc) {
5260 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5261 retval = -ETIMEDOUT;
5262 } else {
5263 spin_lock(&hdd_context_lock);
5264 if (context->request_id == request_id)
5265 retval = context->response_status;
5266 else
5267 retval = -EINVAL;
5268 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305269 }
5270
Dino Myclee8843b32014-07-04 14:21:45 +05305271 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305272 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305273 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305274
5275fail:
5276 vos_mem_free(pReqMsg);
5277 return -EINVAL;
5278}
5279
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305280/*
5281 * done with short names for the global vendor params
5282 * used by wlan_hdd_cfg80211_extscan_start()
5283 */
5284#undef PARAM_MAX
5285#undef PARAM_REQUEST_ID
5286#undef PARAM_BASE_PERIOD
5287#undef PARAMS_MAX_AP_PER_SCAN
5288#undef PARAMS_RPT_THRHLD_PERCENT
5289#undef PARAMS_RPT_THRHLD_NUM_SCANS
5290#undef PARAMS_NUM_BUCKETS
5291
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305292static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5293 struct wireless_dev *wdev,
5294 const void *data, int dataLen)
5295{
5296 int ret = 0;
5297
5298 vos_ssr_protect(__func__);
5299 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5300 vos_ssr_unprotect(__func__);
5301
5302 return ret;
5303}
5304
5305static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305306 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305307 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305308{
Dino Myclee8843b32014-07-04 14:21:45 +05305309 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305310 struct net_device *dev = wdev->netdev;
5311 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5312 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5313 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5314 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305315 int retval;
5316 unsigned long rc;
5317 struct hdd_ext_scan_context *context;
5318 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305319
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305320 ENTER();
5321
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305322 if (VOS_FTM_MODE == hdd_get_conparam()) {
5323 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5324 return -EINVAL;
5325 }
5326
Dino Mycle6fb96c12014-06-10 11:52:40 +05305327 status = wlan_hdd_validate_context(pHddCtx);
5328 if (0 != status)
5329 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305330 return -EINVAL;
5331 }
Dino Myclee8843b32014-07-04 14:21:45 +05305332 /* check the EXTScan Capability */
5333 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305334 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5335 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305336 {
5337 hddLog(VOS_TRACE_LEVEL_ERROR,
5338 FL("EXTScan not enabled/supported by Firmware"));
5339 return -EINVAL;
5340 }
5341
Dino Mycle6fb96c12014-06-10 11:52:40 +05305342 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5343 data, dataLen,
5344 wlan_hdd_extscan_config_policy)) {
5345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5346 return -EINVAL;
5347 }
5348
5349 /* Parse and fetch request Id */
5350 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5352 return -EINVAL;
5353 }
5354
Dino Myclee8843b32014-07-04 14:21:45 +05305355 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305356 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305357 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305358
Dino Myclee8843b32014-07-04 14:21:45 +05305359 reqMsg.sessionId = pAdapter->sessionId;
5360 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305361
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305362 context = &pHddCtx->ext_scan_context;
5363 spin_lock(&hdd_context_lock);
5364 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305365 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305366 spin_unlock(&hdd_context_lock);
5367
Dino Myclee8843b32014-07-04 14:21:45 +05305368 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305369 if (!HAL_STATUS_SUCCESS(status)) {
5370 hddLog(VOS_TRACE_LEVEL_ERROR,
5371 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305372 return -EINVAL;
5373 }
5374
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305375 /* request was sent -- wait for the response */
5376 rc = wait_for_completion_timeout(&context->response_event,
5377 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5378
5379 if (!rc) {
5380 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5381 retval = -ETIMEDOUT;
5382 } else {
5383 spin_lock(&hdd_context_lock);
5384 if (context->request_id == request_id)
5385 retval = context->response_status;
5386 else
5387 retval = -EINVAL;
5388 spin_unlock(&hdd_context_lock);
5389 }
5390
5391 return retval;
5392
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305393 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305394 return 0;
5395}
5396
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305397static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5398 struct wireless_dev *wdev,
5399 const void *data, int dataLen)
5400{
5401 int ret = 0;
5402
5403 vos_ssr_protect(__func__);
5404 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5405 vos_ssr_unprotect(__func__);
5406
5407 return ret;
5408}
5409
5410static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305411 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305412 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305413{
Dino Myclee8843b32014-07-04 14:21:45 +05305414 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305415 struct net_device *dev = wdev->netdev;
5416 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5417 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5418 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5419 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305420 struct hdd_ext_scan_context *context;
5421 tANI_U32 request_id;
5422 unsigned long rc;
5423 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305424
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305425 ENTER();
5426
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305427 if (VOS_FTM_MODE == hdd_get_conparam()) {
5428 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5429 return -EINVAL;
5430 }
5431
Dino Mycle6fb96c12014-06-10 11:52:40 +05305432 status = wlan_hdd_validate_context(pHddCtx);
5433 if (0 != status)
5434 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305435 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305436 return -EINVAL;
5437 }
Dino Myclee8843b32014-07-04 14:21:45 +05305438 /* check the EXTScan Capability */
5439 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305440 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5441 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305442 {
5443 hddLog(VOS_TRACE_LEVEL_ERROR,
5444 FL("EXTScan not enabled/supported by Firmware"));
5445 return -EINVAL;
5446 }
5447
Dino Mycle6fb96c12014-06-10 11:52:40 +05305448 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5449 data, dataLen,
5450 wlan_hdd_extscan_config_policy)) {
5451 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5452 return -EINVAL;
5453 }
5454
5455 /* Parse and fetch request Id */
5456 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5458 return -EINVAL;
5459 }
5460
Dino Myclee8843b32014-07-04 14:21:45 +05305461 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305462 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305463 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305464
Dino Myclee8843b32014-07-04 14:21:45 +05305465 reqMsg.sessionId = pAdapter->sessionId;
5466 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305467
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305468 context = &pHddCtx->ext_scan_context;
5469 spin_lock(&hdd_context_lock);
5470 INIT_COMPLETION(context->response_event);
5471 context->request_id = request_id = reqMsg.requestId;
5472 spin_unlock(&hdd_context_lock);
5473
Dino Myclee8843b32014-07-04 14:21:45 +05305474 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305475 if (!HAL_STATUS_SUCCESS(status)) {
5476 hddLog(VOS_TRACE_LEVEL_ERROR,
5477 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305478 return -EINVAL;
5479 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305480
5481 /* request was sent -- wait for the response */
5482 rc = wait_for_completion_timeout(&context->response_event,
5483 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5484 if (!rc) {
5485 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5486 retval = -ETIMEDOUT;
5487 } else {
5488 spin_lock(&hdd_context_lock);
5489 if (context->request_id == request_id)
5490 retval = context->response_status;
5491 else
5492 retval = -EINVAL;
5493 spin_unlock(&hdd_context_lock);
5494 }
5495
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305496 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305497 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305498}
5499
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305500static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5501 struct wireless_dev *wdev,
5502 const void *data, int dataLen)
5503{
5504 int ret = 0;
5505
5506 vos_ssr_protect(__func__);
5507 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5508 vos_ssr_unprotect(__func__);
5509
5510 return ret;
5511}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305512#endif /* WLAN_FEATURE_EXTSCAN */
5513
Atul Mittal115287b2014-07-08 13:26:33 +05305514/*EXT TDLS*/
5515static const struct nla_policy
5516wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5517{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305518 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5519 .type = NLA_UNSPEC,
5520 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305521 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5522 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5523 {.type = NLA_S32 },
5524 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5525 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5526
5527};
5528
5529static const struct nla_policy
5530wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5531{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305532 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5533 .type = NLA_UNSPEC,
5534 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305535
5536};
5537
5538static const struct nla_policy
5539wlan_hdd_tdls_config_state_change_policy[
5540 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5541{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305542 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5543 .type = NLA_UNSPEC,
5544 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305545 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5546 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305547 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5548 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5549 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305550
5551};
5552
5553static const struct nla_policy
5554wlan_hdd_tdls_config_get_status_policy[
5555 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5556{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305557 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5558 .type = NLA_UNSPEC,
5559 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305560 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5561 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305562 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5563 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5564 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305565
5566};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305567
5568static const struct nla_policy
5569wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5570{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305571 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5572 .type = NLA_UNSPEC,
5573 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305574};
5575
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305576static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305577 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305578 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305579 int data_len)
5580{
5581
5582 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5583 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5584
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305585 ENTER();
5586
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305587 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305588 return -EINVAL;
5589 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305590 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305591 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305592 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305593 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305594 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305595 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305596 return -ENOTSUPP;
5597 }
5598
5599 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5600 data, data_len, wlan_hdd_mac_config)) {
5601 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5602 return -EINVAL;
5603 }
5604
5605 /* Parse and fetch mac address */
5606 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5607 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5608 return -EINVAL;
5609 }
5610
5611 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5612 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5613 VOS_MAC_ADDR_LAST_3_BYTES);
5614
Siddharth Bhal76972212014-10-15 16:22:51 +05305615 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5616
5617 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305618 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5619 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305620 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5621 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5622 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5623 {
5624 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5625 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5626 VOS_MAC_ADDRESS_LEN);
5627 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305628 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305629
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305630 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5631 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305632
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305633 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305634 return 0;
5635}
5636
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305637static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5638 struct wireless_dev *wdev,
5639 const void *data,
5640 int data_len)
5641{
5642 int ret = 0;
5643
5644 vos_ssr_protect(__func__);
5645 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5646 vos_ssr_unprotect(__func__);
5647
5648 return ret;
5649}
5650
5651static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305652 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305653 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305654 int data_len)
5655{
5656 u8 peer[6] = {0};
5657 struct net_device *dev = wdev->netdev;
5658 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5659 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5660 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5661 eHalStatus ret;
5662 tANI_S32 state;
5663 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305664 tANI_S32 global_operating_class = 0;
5665 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305666 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305667 int retVal;
5668
5669 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305670
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305671 if (!pAdapter) {
5672 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5673 return -EINVAL;
5674 }
5675
Atul Mittal115287b2014-07-08 13:26:33 +05305676 ret = wlan_hdd_validate_context(pHddCtx);
5677 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305678 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305679 return -EINVAL;
5680 }
5681 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305682 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305683 return -ENOTSUPP;
5684 }
5685 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5686 data, data_len,
5687 wlan_hdd_tdls_config_get_status_policy)) {
5688 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5689 return -EINVAL;
5690 }
5691
5692 /* Parse and fetch mac address */
5693 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5695 return -EINVAL;
5696 }
5697
5698 memcpy(peer, nla_data(
5699 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5700 sizeof(peer));
5701 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5702
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305703 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305704
Atul Mittal115287b2014-07-08 13:26:33 +05305705 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305706 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305707 NLMSG_HDRLEN);
5708
5709 if (!skb) {
5710 hddLog(VOS_TRACE_LEVEL_ERROR,
5711 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5712 return -EINVAL;
5713 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305714 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 +05305715 reason,
5716 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305717 global_operating_class,
5718 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305719 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305720 if (nla_put_s32(skb,
5721 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5722 state) ||
5723 nla_put_s32(skb,
5724 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5725 reason) ||
5726 nla_put_s32(skb,
5727 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5728 global_operating_class) ||
5729 nla_put_s32(skb,
5730 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5731 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305732
5733 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5734 goto nla_put_failure;
5735 }
5736
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305737 retVal = cfg80211_vendor_cmd_reply(skb);
5738 EXIT();
5739 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305740
5741nla_put_failure:
5742 kfree_skb(skb);
5743 return -EINVAL;
5744}
5745
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305746static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5747 struct wireless_dev *wdev,
5748 const void *data,
5749 int data_len)
5750{
5751 int ret = 0;
5752
5753 vos_ssr_protect(__func__);
5754 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5755 vos_ssr_unprotect(__func__);
5756
5757 return ret;
5758}
5759
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305760static int wlan_hdd_cfg80211_exttdls_callback(
5761#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5762 const tANI_U8* mac,
5763#else
5764 tANI_U8* mac,
5765#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305766 tANI_S32 state,
5767 tANI_S32 reason,
5768 void *ctx)
5769{
5770 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305771 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305772 tANI_S32 global_operating_class = 0;
5773 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305774 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305775
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305776 ENTER();
5777
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305778 if (!pAdapter) {
5779 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5780 return -EINVAL;
5781 }
5782
5783 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305784 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305785 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305786 return -EINVAL;
5787 }
5788
5789 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305791 return -ENOTSUPP;
5792 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305793 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5794#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5795 NULL,
5796#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305797 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5798 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5799 GFP_KERNEL);
5800
5801 if (!skb) {
5802 hddLog(VOS_TRACE_LEVEL_ERROR,
5803 FL("cfg80211_vendor_event_alloc failed"));
5804 return -EINVAL;
5805 }
5806 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305807 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5808 reason,
5809 state,
5810 global_operating_class,
5811 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305812 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5813 MAC_ADDR_ARRAY(mac));
5814
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305815 if (nla_put(skb,
5816 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5817 VOS_MAC_ADDR_SIZE, mac) ||
5818 nla_put_s32(skb,
5819 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5820 state) ||
5821 nla_put_s32(skb,
5822 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5823 reason) ||
5824 nla_put_s32(skb,
5825 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5826 channel) ||
5827 nla_put_s32(skb,
5828 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5829 global_operating_class)
5830 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305831 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5832 goto nla_put_failure;
5833 }
5834
5835 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305836 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305837 return (0);
5838
5839nla_put_failure:
5840 kfree_skb(skb);
5841 return -EINVAL;
5842}
5843
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305844static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305845 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305846 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305847 int data_len)
5848{
5849 u8 peer[6] = {0};
5850 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305851 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5852 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5853 eHalStatus status;
5854 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305855 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305856 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305857
5858 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305859
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305860 if (!dev) {
5861 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5862 return -EINVAL;
5863 }
5864
5865 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5866 if (!pAdapter) {
5867 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5868 return -EINVAL;
5869 }
5870
Atul Mittal115287b2014-07-08 13:26:33 +05305871 status = wlan_hdd_validate_context(pHddCtx);
5872 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305873 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305874 return -EINVAL;
5875 }
5876 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305877 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305878 return -ENOTSUPP;
5879 }
5880 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5881 data, data_len,
5882 wlan_hdd_tdls_config_enable_policy)) {
5883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5884 return -EINVAL;
5885 }
5886
5887 /* Parse and fetch mac address */
5888 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5890 return -EINVAL;
5891 }
5892
5893 memcpy(peer, nla_data(
5894 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5895 sizeof(peer));
5896 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5897
5898 /* Parse and fetch channel */
5899 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5900 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5901 return -EINVAL;
5902 }
5903 pReqMsg.channel = nla_get_s32(
5904 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5905 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5906
5907 /* Parse and fetch global operating class */
5908 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5909 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5910 return -EINVAL;
5911 }
5912 pReqMsg.global_operating_class = nla_get_s32(
5913 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5914 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5915 pReqMsg.global_operating_class);
5916
5917 /* Parse and fetch latency ms */
5918 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5919 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5920 return -EINVAL;
5921 }
5922 pReqMsg.max_latency_ms = nla_get_s32(
5923 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5924 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5925 pReqMsg.max_latency_ms);
5926
5927 /* Parse and fetch required bandwidth kbps */
5928 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5929 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5930 return -EINVAL;
5931 }
5932
5933 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5934 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5935 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5936 pReqMsg.min_bandwidth_kbps);
5937
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305938 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305939 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305940 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305941 wlan_hdd_cfg80211_exttdls_callback);
5942
5943 EXIT();
5944 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305945}
5946
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305947static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5948 struct wireless_dev *wdev,
5949 const void *data,
5950 int data_len)
5951{
5952 int ret = 0;
5953
5954 vos_ssr_protect(__func__);
5955 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5956 vos_ssr_unprotect(__func__);
5957
5958 return ret;
5959}
5960
5961static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305962 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305963 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305964 int data_len)
5965{
5966 u8 peer[6] = {0};
5967 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305968 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5969 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5970 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305971 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305972 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305973
5974 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305975
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305976 if (!dev) {
5977 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5978 return -EINVAL;
5979 }
5980
5981 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5982 if (!pAdapter) {
5983 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5984 return -EINVAL;
5985 }
5986
Atul Mittal115287b2014-07-08 13:26:33 +05305987 status = wlan_hdd_validate_context(pHddCtx);
5988 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305989 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305990 return -EINVAL;
5991 }
5992 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305994 return -ENOTSUPP;
5995 }
5996 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5997 data, data_len,
5998 wlan_hdd_tdls_config_disable_policy)) {
5999 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6000 return -EINVAL;
6001 }
6002 /* Parse and fetch mac address */
6003 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
6004 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
6005 return -EINVAL;
6006 }
6007
6008 memcpy(peer, nla_data(
6009 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
6010 sizeof(peer));
6011 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
6012
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306013 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
6014
6015 EXIT();
6016 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05306017}
6018
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306019static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
6020 struct wireless_dev *wdev,
6021 const void *data,
6022 int data_len)
6023{
6024 int ret = 0;
6025
6026 vos_ssr_protect(__func__);
6027 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
6028 vos_ssr_unprotect(__func__);
6029
6030 return ret;
6031}
6032
Dasari Srinivas7875a302014-09-26 17:50:57 +05306033static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306034__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05306035 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306036 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05306037{
6038 struct net_device *dev = wdev->netdev;
6039 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6040 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6041 struct sk_buff *skb = NULL;
6042 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306043 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306044
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306045 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306046
6047 ret = wlan_hdd_validate_context(pHddCtx);
6048 if (0 != ret)
6049 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306050 return ret;
6051 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306052 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
6053 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
6054 fset |= WIFI_FEATURE_INFRA;
6055 }
6056
6057 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
6058 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
6059 fset |= WIFI_FEATURE_INFRA_5G;
6060 }
6061
6062#ifdef WLAN_FEATURE_P2P
6063 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
6064 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
6065 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
6066 fset |= WIFI_FEATURE_P2P;
6067 }
6068#endif
6069
6070 /* Soft-AP is supported currently by default */
6071 fset |= WIFI_FEATURE_SOFT_AP;
6072
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05306073 /* HOTSPOT is a supplicant feature, enable it by default */
6074 fset |= WIFI_FEATURE_HOTSPOT;
6075
Dasari Srinivas7875a302014-09-26 17:50:57 +05306076#ifdef WLAN_FEATURE_EXTSCAN
6077 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05306078 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
6079 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
6080 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306081 fset |= WIFI_FEATURE_EXTSCAN;
6082 }
6083#endif
6084
Dasari Srinivas7875a302014-09-26 17:50:57 +05306085 if (sme_IsFeatureSupportedByFW(NAN)) {
6086 hddLog(LOG1, FL("NAN is supported by firmware"));
6087 fset |= WIFI_FEATURE_NAN;
6088 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306089
6090 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05306091 if (sme_IsFeatureSupportedByFW(RTT) &&
6092 pHddCtx->cfg_ini->enable_rtt_support) {
6093 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306094 fset |= WIFI_FEATURE_D2AP_RTT;
6095 }
6096
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05306097 if (sme_IsFeatureSupportedByFW(RTT3)) {
6098 hddLog(LOG1, FL("RTT3 is supported by firmware"));
6099 fset |= WIFI_FEATURE_RTT3;
6100 }
6101
Dasari Srinivas7875a302014-09-26 17:50:57 +05306102#ifdef FEATURE_WLAN_BATCH_SCAN
6103 if (fset & WIFI_FEATURE_EXTSCAN) {
6104 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
6105 fset &= ~WIFI_FEATURE_BATCH_SCAN;
6106 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
6107 hddLog(LOG1, FL("Batch scan is supported by firmware"));
6108 fset |= WIFI_FEATURE_BATCH_SCAN;
6109 }
6110#endif
6111
6112#ifdef FEATURE_WLAN_SCAN_PNO
6113 if (pHddCtx->cfg_ini->configPNOScanSupport &&
6114 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
6115 hddLog(LOG1, FL("PNO is supported by firmware"));
6116 fset |= WIFI_FEATURE_PNO;
6117 }
6118#endif
6119
6120 /* STA+STA is supported currently by default */
6121 fset |= WIFI_FEATURE_ADDITIONAL_STA;
6122
6123#ifdef FEATURE_WLAN_TDLS
6124 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6125 sme_IsFeatureSupportedByFW(TDLS)) {
6126 hddLog(LOG1, FL("TDLS is supported by firmware"));
6127 fset |= WIFI_FEATURE_TDLS;
6128 }
6129
6130 /* TDLS_OFFCHANNEL is not supported currently by default */
6131#endif
6132
6133#ifdef WLAN_AP_STA_CONCURRENCY
6134 /* AP+STA concurrency is supported currently by default */
6135 fset |= WIFI_FEATURE_AP_STA;
6136#endif
6137
Mukul Sharma5add0532015-08-17 15:57:47 +05306138#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306139 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6140 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306141 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6142 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306143 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306144#endif
6145
Dasari Srinivas7875a302014-09-26 17:50:57 +05306146 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6147 NLMSG_HDRLEN);
6148
6149 if (!skb) {
6150 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6151 return -EINVAL;
6152 }
6153 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6154
6155 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6156 hddLog(LOGE, FL("nla put fail"));
6157 goto nla_put_failure;
6158 }
6159
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306160 ret = cfg80211_vendor_cmd_reply(skb);
6161 EXIT();
6162 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306163
6164nla_put_failure:
6165 kfree_skb(skb);
6166 return -EINVAL;
6167}
6168
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306169static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306170wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6171 struct wireless_dev *wdev,
6172 const void *data, int data_len)
6173{
6174 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306175 vos_ssr_protect(__func__);
6176 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6177 vos_ssr_unprotect(__func__);
6178
6179 return ret;
6180}
6181
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306182
6183static const struct
6184nla_policy
6185qca_wlan_vendor_wifi_logger_get_ring_data_policy
6186[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6187 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6188 = {.type = NLA_U32 },
6189};
6190
6191static int
6192 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6193 struct wireless_dev *wdev,
6194 const void *data,
6195 int data_len)
6196{
6197 int ret;
6198 VOS_STATUS status;
6199 uint32_t ring_id;
6200 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6201 struct nlattr *tb
6202 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6203
6204 ENTER();
6205
6206 ret = wlan_hdd_validate_context(hdd_ctx);
6207 if (0 != ret) {
6208 return ret;
6209 }
6210
6211 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6212 data, data_len,
6213 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6214 hddLog(LOGE, FL("Invalid attribute"));
6215 return -EINVAL;
6216 }
6217
6218 /* Parse and fetch ring id */
6219 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6220 hddLog(LOGE, FL("attr ATTR failed"));
6221 return -EINVAL;
6222 }
6223
6224 ring_id = nla_get_u32(
6225 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6226
6227 hddLog(LOG1, FL("Bug report triggered by framework"));
6228
6229 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6230 WLAN_LOG_INDICATOR_FRAMEWORK,
6231 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306232 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306233 );
6234 if (VOS_STATUS_SUCCESS != status) {
6235 hddLog(LOGE, FL("Failed to trigger bug report"));
6236
6237 return -EINVAL;
6238 }
6239
6240 return 0;
6241
6242
6243}
6244
6245
6246static int
6247 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6248 struct wireless_dev *wdev,
6249 const void *data,
6250 int data_len)
6251{
6252 int ret = 0;
6253
6254 vos_ssr_protect(__func__);
6255 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6256 wdev, data, data_len);
6257 vos_ssr_unprotect(__func__);
6258
6259 return ret;
6260
6261}
6262
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306263#define MAX_CONCURRENT_MATRIX \
6264 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6265#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6266 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6267static const struct nla_policy
6268wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6269 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6270};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306271
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306272static int
6273__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306274 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306275 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306276{
6277 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6278 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306279 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306280 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306281 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6282 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306283
6284 ENTER();
6285
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306286 ret = wlan_hdd_validate_context(pHddCtx);
6287 if (0 != ret)
6288 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306289 return ret;
6290 }
6291
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306292 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6293 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306294 hddLog(LOGE, FL("Invalid ATTR"));
6295 return -EINVAL;
6296 }
6297
6298 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306299 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306300 hddLog(LOGE, FL("Attr max feature set size failed"));
6301 return -EINVAL;
6302 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306303 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306304 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6305
6306 /* Fill feature combination matrix */
6307 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306308 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6309 WIFI_FEATURE_P2P;
6310
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306311 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6312 WIFI_FEATURE_SOFT_AP;
6313
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306314 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6315 WIFI_FEATURE_SOFT_AP;
6316
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306317 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6318 WIFI_FEATURE_SOFT_AP |
6319 WIFI_FEATURE_P2P;
6320
6321 /* Add more feature combinations here */
6322
6323 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6324 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6325 hddLog(LOG1, "Feature set matrix");
6326 for (i = 0; i < feature_sets; i++)
6327 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6328
6329 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6330 sizeof(u32) * feature_sets +
6331 NLMSG_HDRLEN);
6332
6333 if (reply_skb) {
6334 if (nla_put_u32(reply_skb,
6335 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6336 feature_sets) ||
6337 nla_put(reply_skb,
6338 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6339 sizeof(u32) * feature_sets, feature_set_matrix)) {
6340 hddLog(LOGE, FL("nla put fail"));
6341 kfree_skb(reply_skb);
6342 return -EINVAL;
6343 }
6344
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306345 ret = cfg80211_vendor_cmd_reply(reply_skb);
6346 EXIT();
6347 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306348 }
6349 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6350 return -ENOMEM;
6351
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306352}
6353
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306354#undef MAX_CONCURRENT_MATRIX
6355#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6356
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306357static int
6358wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6359 struct wireless_dev *wdev,
6360 const void *data, int data_len)
6361{
6362 int ret = 0;
6363
6364 vos_ssr_protect(__func__);
6365 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6366 data_len);
6367 vos_ssr_unprotect(__func__);
6368
6369 return ret;
6370}
6371
c_manjeecfd1efb2015-09-25 19:32:34 +05306372
6373static int
6374__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6375 struct wireless_dev *wdev,
6376 const void *data, int data_len)
6377{
6378 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6379 int ret;
6380 ENTER();
6381
6382 ret = wlan_hdd_validate_context(pHddCtx);
6383 if (0 != ret)
6384 {
6385 return ret;
6386 }
6387
6388 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6389 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6390 {
6391 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306392 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306393 }
6394 /*call common API for FW mem dump req*/
6395 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6396
Abhishek Singhc783fa72015-12-09 18:07:34 +05306397 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306398 {
6399 /*indicate to userspace the status of fw mem dump */
6400 wlan_indicate_mem_dump_complete(true);
6401 }
6402 else
6403 {
6404 /*else send failure to userspace */
6405 wlan_indicate_mem_dump_complete(false);
6406 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306407 EXIT();
6408 return ret;
6409}
6410
6411/**
6412 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6413 * @wiphy: pointer to wireless wiphy structure.
6414 * @wdev: pointer to wireless_dev structure.
6415 * @data: Pointer to the NL data.
6416 * @data_len:Length of @data
6417 *
6418 * This is called when wlan driver needs to get the firmware memory dump
6419 * via vendor specific command.
6420 *
6421 * Return: 0 on success, error number otherwise.
6422 */
6423
6424static int
6425wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6426 struct wireless_dev *wdev,
6427 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306428{
6429 int ret = 0;
6430 vos_ssr_protect(__func__);
6431 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6432 data_len);
6433 vos_ssr_unprotect(__func__);
6434 return ret;
6435}
c_manjeecfd1efb2015-09-25 19:32:34 +05306436
Sushant Kaushik8e644982015-09-23 12:18:54 +05306437static const struct
6438nla_policy
6439qca_wlan_vendor_wifi_logger_start_policy
6440[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6441 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6442 = {.type = NLA_U32 },
6443 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6444 = {.type = NLA_U32 },
6445 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6446 = {.type = NLA_U32 },
6447};
6448
6449/**
6450 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6451 * or disable the collection of packet statistics from the firmware
6452 * @wiphy: WIPHY structure pointer
6453 * @wdev: Wireless device structure pointer
6454 * @data: Pointer to the data received
6455 * @data_len: Length of the data received
6456 *
6457 * This function is used to enable or disable the collection of packet
6458 * statistics from the firmware
6459 *
6460 * Return: 0 on success and errno on failure
6461 */
6462static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6463 struct wireless_dev *wdev,
6464 const void *data,
6465 int data_len)
6466{
6467 eHalStatus status;
6468 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6469 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6470 tAniWifiStartLog start_log;
6471
6472 status = wlan_hdd_validate_context(hdd_ctx);
6473 if (0 != status) {
6474 return -EINVAL;
6475 }
6476
6477 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6478 data, data_len,
6479 qca_wlan_vendor_wifi_logger_start_policy)) {
6480 hddLog(LOGE, FL("Invalid attribute"));
6481 return -EINVAL;
6482 }
6483
6484 /* Parse and fetch ring id */
6485 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6486 hddLog(LOGE, FL("attr ATTR failed"));
6487 return -EINVAL;
6488 }
6489 start_log.ringId = nla_get_u32(
6490 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6491 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6492
6493 /* Parse and fetch verbose level */
6494 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6495 hddLog(LOGE, FL("attr verbose_level failed"));
6496 return -EINVAL;
6497 }
6498 start_log.verboseLevel = nla_get_u32(
6499 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6500 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6501
6502 /* Parse and fetch flag */
6503 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6504 hddLog(LOGE, FL("attr flag failed"));
6505 return -EINVAL;
6506 }
6507 start_log.flag = nla_get_u32(
6508 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6509 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6510
6511 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306512 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6513 !vos_isPktStatsEnabled()))
6514
Sushant Kaushik8e644982015-09-23 12:18:54 +05306515 {
6516 hddLog(LOGE, FL("per pkt stats not enabled"));
6517 return -EINVAL;
6518 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306519
Sushant Kaushik33200572015-08-05 16:46:20 +05306520 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306521 return 0;
6522}
6523
6524/**
6525 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6526 * or disable the collection of packet statistics from the firmware
6527 * @wiphy: WIPHY structure pointer
6528 * @wdev: Wireless device structure pointer
6529 * @data: Pointer to the data received
6530 * @data_len: Length of the data received
6531 *
6532 * This function is used to enable or disable the collection of packet
6533 * statistics from the firmware
6534 *
6535 * Return: 0 on success and errno on failure
6536 */
6537static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6538 struct wireless_dev *wdev,
6539 const void *data,
6540 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306541{
6542 int ret = 0;
6543
6544 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306545
6546 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6547 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306548 vos_ssr_unprotect(__func__);
6549
6550 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306551}
6552
6553
Agarwal Ashish738843c2014-09-25 12:27:56 +05306554static const struct nla_policy
6555wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6556 +1] =
6557{
6558 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6559};
6560
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306561static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306562 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306563 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306564 int data_len)
6565{
6566 struct net_device *dev = wdev->netdev;
6567 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6568 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6569 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6570 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6571 eHalStatus status;
6572 u32 dfsFlag = 0;
6573
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306574 ENTER();
6575
Agarwal Ashish738843c2014-09-25 12:27:56 +05306576 status = wlan_hdd_validate_context(pHddCtx);
6577 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306578 return -EINVAL;
6579 }
6580 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6581 data, data_len,
6582 wlan_hdd_set_no_dfs_flag_config_policy)) {
6583 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6584 return -EINVAL;
6585 }
6586
6587 /* Parse and fetch required bandwidth kbps */
6588 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6589 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6590 return -EINVAL;
6591 }
6592
6593 dfsFlag = nla_get_u32(
6594 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6595 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6596 dfsFlag);
6597
6598 pHddCtx->disable_dfs_flag = dfsFlag;
6599
6600 sme_disable_dfs_channel(hHal, dfsFlag);
6601 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306602
6603 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306604 return 0;
6605}
Atul Mittal115287b2014-07-08 13:26:33 +05306606
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306607static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6608 struct wireless_dev *wdev,
6609 const void *data,
6610 int data_len)
6611{
6612 int ret = 0;
6613
6614 vos_ssr_protect(__func__);
6615 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6616 vos_ssr_unprotect(__func__);
6617
6618 return ret;
6619
6620}
6621
Mukul Sharma2a271632014-10-13 14:59:01 +05306622const struct
6623nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6624{
6625 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306626 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6627 .type = NLA_UNSPEC,
6628 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306629};
6630
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306631static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306632 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306633{
6634
6635 u8 bssid[6] = {0};
6636 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6637 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6638 eHalStatus status = eHAL_STATUS_SUCCESS;
6639 v_U32_t isFwrRoamEnabled = FALSE;
6640 int ret;
6641
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306642 ENTER();
6643
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306644 ret = wlan_hdd_validate_context(pHddCtx);
6645 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306646 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306647 }
6648
6649 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6650 data, data_len,
6651 qca_wlan_vendor_attr);
6652 if (ret){
6653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6654 return -EINVAL;
6655 }
6656
6657 /* Parse and fetch Enable flag */
6658 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6660 return -EINVAL;
6661 }
6662
6663 isFwrRoamEnabled = nla_get_u32(
6664 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6665
6666 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6667
6668 /* Parse and fetch bssid */
6669 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6670 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6671 return -EINVAL;
6672 }
6673
6674 memcpy(bssid, nla_data(
6675 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6676 sizeof(bssid));
6677 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6678
6679 //Update roaming
6680 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306681 if (!HAL_STATUS_SUCCESS(status)) {
6682 hddLog(LOGE,
6683 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6684 return -EINVAL;
6685 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306686 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306687 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306688}
6689
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306690static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6691 struct wireless_dev *wdev, const void *data, int data_len)
6692{
6693 int ret = 0;
6694
6695 vos_ssr_protect(__func__);
6696 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6697 vos_ssr_unprotect(__func__);
6698
6699 return ret;
6700}
6701
Sushant Kaushik847890c2015-09-28 16:05:17 +05306702static const struct
6703nla_policy
6704qca_wlan_vendor_get_wifi_info_policy[
6705 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6706 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6707 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6708};
6709
6710
6711/**
6712 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6713 * @wiphy: pointer to wireless wiphy structure.
6714 * @wdev: pointer to wireless_dev structure.
6715 * @data: Pointer to the data to be passed via vendor interface
6716 * @data_len:Length of the data to be passed
6717 *
6718 * This is called when wlan driver needs to send wifi driver related info
6719 * (driver/fw version) to the user space application upon request.
6720 *
6721 * Return: Return the Success or Failure code.
6722 */
6723static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6724 struct wireless_dev *wdev,
6725 const void *data, int data_len)
6726{
6727 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6728 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6729 tSirVersionString version;
6730 uint32 version_len;
6731 uint8 attr;
6732 int status;
6733 struct sk_buff *reply_skb = NULL;
6734
6735 if (VOS_FTM_MODE == hdd_get_conparam()) {
6736 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6737 return -EINVAL;
6738 }
6739
6740 status = wlan_hdd_validate_context(hdd_ctx);
6741 if (0 != status) {
6742 hddLog(LOGE, FL("HDD context is not valid"));
6743 return -EINVAL;
6744 }
6745
6746 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6747 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6748 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6749 return -EINVAL;
6750 }
6751
6752 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6753 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6754 QWLAN_VERSIONSTR);
6755 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6756 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6757 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6758 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6759 hdd_ctx->fw_Version);
6760 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6761 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6762 } else {
6763 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6764 return -EINVAL;
6765 }
6766
6767 version_len = strlen(version);
6768 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6769 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6770 if (!reply_skb) {
6771 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6772 return -ENOMEM;
6773 }
6774
6775 if (nla_put(reply_skb, attr, version_len, version)) {
6776 hddLog(LOGE, FL("nla put fail"));
6777 kfree_skb(reply_skb);
6778 return -EINVAL;
6779 }
6780
6781 return cfg80211_vendor_cmd_reply(reply_skb);
6782}
6783
6784/**
6785 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6786 * @wiphy: pointer to wireless wiphy structure.
6787 * @wdev: pointer to wireless_dev structure.
6788 * @data: Pointer to the data to be passed via vendor interface
6789 * @data_len:Length of the data to be passed
6790 * @data_len: Length of the data received
6791 *
6792 * This function is used to enable or disable the collection of packet
6793 * statistics from the firmware
6794 *
6795 * Return: 0 on success and errno on failure
6796 */
6797
6798static int
6799wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6800 struct wireless_dev *wdev,
6801 const void *data, int data_len)
6802
6803
6804{
6805 int ret = 0;
6806
6807 vos_ssr_protect(__func__);
6808 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6809 wdev, data, data_len);
6810 vos_ssr_unprotect(__func__);
6811
6812 return ret;
6813}
6814
6815
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306816/*
6817 * define short names for the global vendor params
6818 * used by __wlan_hdd_cfg80211_monitor_rssi()
6819 */
6820#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6821#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6822#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6823#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6824#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6825
6826/**---------------------------------------------------------------------------
6827
6828 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6829 monitor start is completed successfully.
6830
6831 \return - None
6832
6833 --------------------------------------------------------------------------*/
6834void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6835{
6836 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6837
6838 if (NULL == pHddCtx)
6839 {
6840 hddLog(VOS_TRACE_LEVEL_ERROR,
6841 "%s: HDD context is NULL",__func__);
6842 return;
6843 }
6844
6845 if (VOS_STATUS_SUCCESS == status)
6846 {
6847 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6848 }
6849 else
6850 {
6851 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6852 }
6853
6854 return;
6855}
6856
6857/**---------------------------------------------------------------------------
6858
6859 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6860 stop is completed successfully.
6861
6862 \return - None
6863
6864 --------------------------------------------------------------------------*/
6865void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6866{
6867 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6868
6869 if (NULL == pHddCtx)
6870 {
6871 hddLog(VOS_TRACE_LEVEL_ERROR,
6872 "%s: HDD context is NULL",__func__);
6873 return;
6874 }
6875
6876 if (VOS_STATUS_SUCCESS == status)
6877 {
6878 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6879 }
6880 else
6881 {
6882 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6883 }
6884
6885 return;
6886}
6887
6888/**
6889 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6890 * @wiphy: Pointer to wireless phy
6891 * @wdev: Pointer to wireless device
6892 * @data: Pointer to data
6893 * @data_len: Data length
6894 *
6895 * Return: 0 on success, negative errno on failure
6896 */
6897
6898static int
6899__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6900 struct wireless_dev *wdev,
6901 const void *data,
6902 int data_len)
6903{
6904 struct net_device *dev = wdev->netdev;
6905 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6906 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6907 hdd_station_ctx_t *pHddStaCtx;
6908 struct nlattr *tb[PARAM_MAX + 1];
6909 tpSirRssiMonitorReq pReq;
6910 eHalStatus status;
6911 int ret;
6912 uint32_t control;
6913 static const struct nla_policy policy[PARAM_MAX + 1] = {
6914 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6915 [PARAM_CONTROL] = { .type = NLA_U32 },
6916 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6917 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6918 };
6919
6920 ENTER();
6921
6922 ret = wlan_hdd_validate_context(hdd_ctx);
6923 if (0 != ret) {
6924 return -EINVAL;
6925 }
6926
6927 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6928 hddLog(LOGE, FL("Not in Connected state!"));
6929 return -ENOTSUPP;
6930 }
6931
6932 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6933 hddLog(LOGE, FL("Invalid ATTR"));
6934 return -EINVAL;
6935 }
6936
6937 if (!tb[PARAM_REQUEST_ID]) {
6938 hddLog(LOGE, FL("attr request id failed"));
6939 return -EINVAL;
6940 }
6941
6942 if (!tb[PARAM_CONTROL]) {
6943 hddLog(LOGE, FL("attr control failed"));
6944 return -EINVAL;
6945 }
6946
6947 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6948
6949 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6950 if(NULL == pReq)
6951 {
6952 hddLog(LOGE,
6953 FL("vos_mem_alloc failed "));
6954 return eHAL_STATUS_FAILED_ALLOC;
6955 }
6956 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6957
6958 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6959 pReq->sessionId = pAdapter->sessionId;
6960 pReq->rssiMonitorCbContext = hdd_ctx;
6961 control = nla_get_u32(tb[PARAM_CONTROL]);
6962 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6963
6964 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6965 pReq->requestId, pReq->sessionId, control);
6966
6967 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6968 if (!tb[PARAM_MIN_RSSI]) {
6969 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306970 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306971 }
6972
6973 if (!tb[PARAM_MAX_RSSI]) {
6974 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306975 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306976 }
6977
6978 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6979 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6980 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6981
6982 if (!(pReq->minRssi < pReq->maxRssi)) {
6983 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6984 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306985 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306986 }
6987 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6988 pReq->minRssi, pReq->maxRssi);
6989 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6990
6991 }
6992 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6993 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6994 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6995 }
6996 else {
6997 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306998 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306999 }
7000
7001 if (!HAL_STATUS_SUCCESS(status)) {
7002 hddLog(LOGE,
7003 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307004 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307005 }
7006
7007 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307008fail:
7009 vos_mem_free(pReq);
7010 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307011}
7012
7013/*
7014 * done with short names for the global vendor params
7015 * used by __wlan_hdd_cfg80211_monitor_rssi()
7016 */
7017#undef PARAM_MAX
7018#undef PARAM_CONTROL
7019#undef PARAM_REQUEST_ID
7020#undef PARAM_MAX_RSSI
7021#undef PARAM_MIN_RSSI
7022
7023/**
7024 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
7025 * @wiphy: wiphy structure pointer
7026 * @wdev: Wireless device structure pointer
7027 * @data: Pointer to the data received
7028 * @data_len: Length of @data
7029 *
7030 * Return: 0 on success; errno on failure
7031 */
7032static int
7033wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
7034 const void *data, int data_len)
7035{
7036 int ret;
7037
7038 vos_ssr_protect(__func__);
7039 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
7040 vos_ssr_unprotect(__func__);
7041
7042 return ret;
7043}
7044
7045/**
7046 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
7047 * @hddctx: HDD context
7048 * @data: rssi breached event data
7049 *
7050 * This function reads the rssi breached event %data and fill in the skb with
7051 * NL attributes and send up the NL event.
7052 * This callback execute in atomic context and must not invoke any
7053 * blocking calls.
7054 *
7055 * Return: none
7056 */
7057void hdd_rssi_threshold_breached_cb(void *hddctx,
7058 struct rssi_breach_event *data)
7059{
7060 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
7061 int status;
7062 struct sk_buff *skb;
7063
7064 ENTER();
7065 status = wlan_hdd_validate_context(pHddCtx);
7066
7067 if (0 != status) {
7068 return;
7069 }
7070
7071 if (!data) {
7072 hddLog(LOGE, FL("data is null"));
7073 return;
7074 }
7075
7076 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
7077#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7078 NULL,
7079#endif
7080 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
7081 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
7082 GFP_KERNEL);
7083
7084 if (!skb) {
7085 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
7086 return;
7087 }
7088
7089 hddLog(LOG1, "Req Id: %u Current rssi: %d",
7090 data->request_id, data->curr_rssi);
7091 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
7092 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
7093
7094 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
7095 data->request_id) ||
7096 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
7097 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
7098 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
7099 data->curr_rssi)) {
7100 hddLog(LOGE, FL("nla put fail"));
7101 goto fail;
7102 }
7103
7104 cfg80211_vendor_event(skb, GFP_KERNEL);
7105 return;
7106
7107fail:
7108 kfree_skb(skb);
7109 return;
7110}
7111
7112
7113
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307114/**
7115 * __wlan_hdd_cfg80211_setband() - set band
7116 * @wiphy: Pointer to wireless phy
7117 * @wdev: Pointer to wireless device
7118 * @data: Pointer to data
7119 * @data_len: Data length
7120 *
7121 * Return: 0 on success, negative errno on failure
7122 */
7123static int
7124__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7125 struct wireless_dev *wdev,
7126 const void *data,
7127 int data_len)
7128{
7129 struct net_device *dev = wdev->netdev;
7130 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7131 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7132 int ret;
7133 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7134 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7135
7136 ENTER();
7137
7138 ret = wlan_hdd_validate_context(hdd_ctx);
7139 if (0 != ret) {
7140 hddLog(LOGE, FL("HDD context is not valid"));
7141 return ret;
7142 }
7143
7144 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7145 policy)) {
7146 hddLog(LOGE, FL("Invalid ATTR"));
7147 return -EINVAL;
7148 }
7149
7150 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7151 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7152 return -EINVAL;
7153 }
7154
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307155 hdd_ctx->isSetBandByNL = TRUE;
7156 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307157 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307158 hdd_ctx->isSetBandByNL = FALSE;
7159
7160 EXIT();
7161 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307162}
7163
7164/**
7165 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7166 * @wiphy: wiphy structure pointer
7167 * @wdev: Wireless device structure pointer
7168 * @data: Pointer to the data received
7169 * @data_len: Length of @data
7170 *
7171 * Return: 0 on success; errno on failure
7172 */
7173static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7174 struct wireless_dev *wdev,
7175 const void *data,
7176 int data_len)
7177{
7178 int ret = 0;
7179
7180 vos_ssr_protect(__func__);
7181 ret = __wlan_hdd_cfg80211_setband(wiphy,
7182 wdev, data, data_len);
7183 vos_ssr_unprotect(__func__);
7184
7185 return ret;
7186}
7187
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307188#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7189/**
7190 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7191 * @hdd_ctx: HDD context
7192 * @request_id: [input] request id
7193 * @pattern_id: [output] pattern id
7194 *
7195 * This function loops through request id to pattern id array
7196 * if the slot is available, store the request id and return pattern id
7197 * if entry exists, return the pattern id
7198 *
7199 * Return: 0 on success and errno on failure
7200 */
7201static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7202 uint32_t request_id,
7203 uint8_t *pattern_id)
7204{
7205 uint32_t i;
7206
7207 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7208 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7209 {
7210 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7211 {
7212 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7213 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7214 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7215 return 0;
7216 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7217 request_id) {
7218 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7219 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7220 return 0;
7221 }
7222 }
7223 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7224 return -EINVAL;
7225}
7226
7227/**
7228 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7229 * @hdd_ctx: HDD context
7230 * @request_id: [input] request id
7231 * @pattern_id: [output] pattern id
7232 *
7233 * This function loops through request id to pattern id array
7234 * reset request id to 0 (slot available again) and
7235 * return pattern id
7236 *
7237 * Return: 0 on success and errno on failure
7238 */
7239static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7240 uint32_t request_id,
7241 uint8_t *pattern_id)
7242{
7243 uint32_t i;
7244
7245 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7246 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7247 {
7248 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7249 {
7250 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7251 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7252 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7253 return 0;
7254 }
7255 }
7256 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7257 return -EINVAL;
7258}
7259
7260
7261/*
7262 * define short names for the global vendor params
7263 * used by __wlan_hdd_cfg80211_offloaded_packets()
7264 */
7265#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7266#define PARAM_REQUEST_ID \
7267 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7268#define PARAM_CONTROL \
7269 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7270#define PARAM_IP_PACKET \
7271 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7272#define PARAM_SRC_MAC_ADDR \
7273 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7274#define PARAM_DST_MAC_ADDR \
7275 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7276#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7277
7278/**
7279 * wlan_hdd_add_tx_ptrn() - add tx pattern
7280 * @adapter: adapter pointer
7281 * @hdd_ctx: hdd context
7282 * @tb: nl attributes
7283 *
7284 * This function reads the NL attributes and forms a AddTxPtrn message
7285 * posts it to SME.
7286 *
7287 */
7288static int
7289wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7290 struct nlattr **tb)
7291{
7292 struct sSirAddPeriodicTxPtrn *add_req;
7293 eHalStatus status;
7294 uint32_t request_id, ret, len;
7295 uint8_t pattern_id = 0;
7296 v_MACADDR_t dst_addr;
7297 uint16_t eth_type = htons(ETH_P_IP);
7298
7299 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7300 {
7301 hddLog(LOGE, FL("Not in Connected state!"));
7302 return -ENOTSUPP;
7303 }
7304
7305 add_req = vos_mem_malloc(sizeof(*add_req));
7306 if (!add_req)
7307 {
7308 hddLog(LOGE, FL("memory allocation failed"));
7309 return -ENOMEM;
7310 }
7311
7312 /* Parse and fetch request Id */
7313 if (!tb[PARAM_REQUEST_ID])
7314 {
7315 hddLog(LOGE, FL("attr request id failed"));
7316 goto fail;
7317 }
7318
7319 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7320 hddLog(LOG1, FL("Request Id: %u"), request_id);
7321 if (request_id == 0)
7322 {
7323 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307324 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307325 }
7326
7327 if (!tb[PARAM_PERIOD])
7328 {
7329 hddLog(LOGE, FL("attr period failed"));
7330 goto fail;
7331 }
7332 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7333 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7334 if (add_req->usPtrnIntervalMs == 0)
7335 {
7336 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7337 goto fail;
7338 }
7339
7340 if (!tb[PARAM_SRC_MAC_ADDR])
7341 {
7342 hddLog(LOGE, FL("attr source mac address failed"));
7343 goto fail;
7344 }
7345 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7346 VOS_MAC_ADDR_SIZE);
7347 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7348 MAC_ADDR_ARRAY(add_req->macAddress));
7349
7350 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7351 VOS_MAC_ADDR_SIZE))
7352 {
7353 hddLog(LOGE,
7354 FL("input src mac address and connected ap bssid are different"));
7355 goto fail;
7356 }
7357
7358 if (!tb[PARAM_DST_MAC_ADDR])
7359 {
7360 hddLog(LOGE, FL("attr dst mac address failed"));
7361 goto fail;
7362 }
7363 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7364 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7365 MAC_ADDR_ARRAY(dst_addr.bytes));
7366
7367 if (!tb[PARAM_IP_PACKET])
7368 {
7369 hddLog(LOGE, FL("attr ip packet failed"));
7370 goto fail;
7371 }
7372 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7373 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7374
7375 if (add_req->ucPtrnSize < 0 ||
7376 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7377 HDD_ETH_HEADER_LEN))
7378 {
7379 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7380 add_req->ucPtrnSize);
7381 goto fail;
7382 }
7383
7384 len = 0;
7385 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7386 len += VOS_MAC_ADDR_SIZE;
7387 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7388 VOS_MAC_ADDR_SIZE);
7389 len += VOS_MAC_ADDR_SIZE;
7390 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7391 len += 2;
7392
7393 /*
7394 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7395 * ------------------------------------------------------------
7396 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7397 * ------------------------------------------------------------
7398 */
7399 vos_mem_copy(&add_req->ucPattern[len],
7400 nla_data(tb[PARAM_IP_PACKET]),
7401 add_req->ucPtrnSize);
7402 add_req->ucPtrnSize += len;
7403
7404 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7405 add_req->ucPattern, add_req->ucPtrnSize);
7406
7407 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7408 if (ret)
7409 {
7410 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7411 goto fail;
7412 }
7413 add_req->ucPtrnId = pattern_id;
7414 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7415
7416 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7417 if (!HAL_STATUS_SUCCESS(status))
7418 {
7419 hddLog(LOGE,
7420 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7421 goto fail;
7422 }
7423
7424 EXIT();
7425 vos_mem_free(add_req);
7426 return 0;
7427
7428fail:
7429 vos_mem_free(add_req);
7430 return -EINVAL;
7431}
7432
7433/**
7434 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7435 * @adapter: adapter pointer
7436 * @hdd_ctx: hdd context
7437 * @tb: nl attributes
7438 *
7439 * This function reads the NL attributes and forms a DelTxPtrn message
7440 * posts it to SME.
7441 *
7442 */
7443static int
7444wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7445 struct nlattr **tb)
7446{
7447 struct sSirDelPeriodicTxPtrn *del_req;
7448 eHalStatus status;
7449 uint32_t request_id, ret;
7450 uint8_t pattern_id = 0;
7451
7452 /* Parse and fetch request Id */
7453 if (!tb[PARAM_REQUEST_ID])
7454 {
7455 hddLog(LOGE, FL("attr request id failed"));
7456 return -EINVAL;
7457 }
7458 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7459 if (request_id == 0)
7460 {
7461 hddLog(LOGE, FL("request_id cannot be zero"));
7462 return -EINVAL;
7463 }
7464
7465 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7466 if (ret)
7467 {
7468 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7469 return -EINVAL;
7470 }
7471
7472 del_req = vos_mem_malloc(sizeof(*del_req));
7473 if (!del_req)
7474 {
7475 hddLog(LOGE, FL("memory allocation failed"));
7476 return -ENOMEM;
7477 }
7478
7479 vos_mem_set(del_req, sizeof(*del_req), 0);
7480 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7481 VOS_MAC_ADDR_SIZE);
7482 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7483 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7484 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7485 request_id, pattern_id, del_req->ucPatternIdBitmap);
7486
7487 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7488 if (!HAL_STATUS_SUCCESS(status))
7489 {
7490 hddLog(LOGE,
7491 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7492 goto fail;
7493 }
7494
7495 EXIT();
7496 vos_mem_free(del_req);
7497 return 0;
7498
7499fail:
7500 vos_mem_free(del_req);
7501 return -EINVAL;
7502}
7503
7504
7505/**
7506 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7507 * @wiphy: Pointer to wireless phy
7508 * @wdev: Pointer to wireless device
7509 * @data: Pointer to data
7510 * @data_len: Data length
7511 *
7512 * Return: 0 on success, negative errno on failure
7513 */
7514static int
7515__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7516 struct wireless_dev *wdev,
7517 const void *data,
7518 int data_len)
7519{
7520 struct net_device *dev = wdev->netdev;
7521 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7522 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7523 struct nlattr *tb[PARAM_MAX + 1];
7524 uint8_t control;
7525 int ret;
7526 static const struct nla_policy policy[PARAM_MAX + 1] =
7527 {
7528 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7529 [PARAM_CONTROL] = { .type = NLA_U32 },
7530 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7531 .len = VOS_MAC_ADDR_SIZE },
7532 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7533 .len = VOS_MAC_ADDR_SIZE },
7534 [PARAM_PERIOD] = { .type = NLA_U32 },
7535 };
7536
7537 ENTER();
7538
7539 ret = wlan_hdd_validate_context(hdd_ctx);
7540 if (0 != ret)
7541 {
7542 hddLog(LOGE, FL("HDD context is not valid"));
7543 return ret;
7544 }
7545
7546 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7547 {
7548 hddLog(LOGE,
7549 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7550 return -ENOTSUPP;
7551 }
7552
7553 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7554 {
7555 hddLog(LOGE, FL("Invalid ATTR"));
7556 return -EINVAL;
7557 }
7558
7559 if (!tb[PARAM_CONTROL])
7560 {
7561 hddLog(LOGE, FL("attr control failed"));
7562 return -EINVAL;
7563 }
7564 control = nla_get_u32(tb[PARAM_CONTROL]);
7565 hddLog(LOG1, FL("Control: %d"), control);
7566
7567 if (control == WLAN_START_OFFLOADED_PACKETS)
7568 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7569 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7570 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7571 else
7572 {
7573 hddLog(LOGE, FL("Invalid control: %d"), control);
7574 return -EINVAL;
7575 }
7576}
7577
7578/*
7579 * done with short names for the global vendor params
7580 * used by __wlan_hdd_cfg80211_offloaded_packets()
7581 */
7582#undef PARAM_MAX
7583#undef PARAM_REQUEST_ID
7584#undef PARAM_CONTROL
7585#undef PARAM_IP_PACKET
7586#undef PARAM_SRC_MAC_ADDR
7587#undef PARAM_DST_MAC_ADDR
7588#undef PARAM_PERIOD
7589
7590/**
7591 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7592 * @wiphy: wiphy structure pointer
7593 * @wdev: Wireless device structure pointer
7594 * @data: Pointer to the data received
7595 * @data_len: Length of @data
7596 *
7597 * Return: 0 on success; errno on failure
7598 */
7599static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7600 struct wireless_dev *wdev,
7601 const void *data,
7602 int data_len)
7603{
7604 int ret = 0;
7605
7606 vos_ssr_protect(__func__);
7607 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7608 wdev, data, data_len);
7609 vos_ssr_unprotect(__func__);
7610
7611 return ret;
7612}
7613#endif
7614
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307615static const struct
7616nla_policy
7617qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307618 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7619 .type = NLA_BINARY,
7620 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307621};
7622
7623/**
7624 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7625 * get link properties like nss, rate flags and operating frequency for
7626 * the connection with the given peer.
7627 * @wiphy: WIPHY structure pointer
7628 * @wdev: Wireless device structure pointer
7629 * @data: Pointer to the data received
7630 * @data_len: Length of the data received
7631 *
7632 * This function return the above link properties on success.
7633 *
7634 * Return: 0 on success and errno on failure
7635 */
7636static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7637 struct wireless_dev *wdev,
7638 const void *data,
7639 int data_len)
7640{
7641 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7642 struct net_device *dev = wdev->netdev;
7643 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7644 hdd_station_ctx_t *hdd_sta_ctx;
7645 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7646 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7647 uint32_t sta_id;
7648 struct sk_buff *reply_skb;
7649 uint32_t rate_flags = 0;
7650 uint8_t nss;
7651 uint8_t final_rate_flags = 0;
7652 uint32_t freq;
7653 v_CONTEXT_t pVosContext = NULL;
7654 ptSapContext pSapCtx = NULL;
7655
7656 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7657 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7658 return -EINVAL;
7659 }
7660
7661 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7662 qca_wlan_vendor_attr_policy)) {
7663 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7664 return -EINVAL;
7665 }
7666
7667 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7668 hddLog(VOS_TRACE_LEVEL_ERROR,
7669 FL("Attribute peerMac not provided for mode=%d"),
7670 adapter->device_mode);
7671 return -EINVAL;
7672 }
7673
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307674 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7675 hddLog(VOS_TRACE_LEVEL_ERROR,
7676 FL("Attribute peerMac is invalid=%d"),
7677 adapter->device_mode);
7678 return -EINVAL;
7679 }
7680
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307681 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7682 sizeof(peer_mac));
7683 hddLog(VOS_TRACE_LEVEL_INFO,
7684 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7685 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7686
7687 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7688 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7689 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7690 if ((hdd_sta_ctx->conn_info.connState !=
7691 eConnectionState_Associated) ||
7692 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7693 VOS_MAC_ADDRESS_LEN)) {
7694 hddLog(VOS_TRACE_LEVEL_ERROR,
7695 FL("Not Associated to mac "MAC_ADDRESS_STR),
7696 MAC_ADDR_ARRAY(peer_mac));
7697 return -EINVAL;
7698 }
7699
7700 nss = 1; //pronto supports only one spatial stream
7701 freq = vos_chan_to_freq(
7702 hdd_sta_ctx->conn_info.operationChannel);
7703 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7704
7705 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7706 adapter->device_mode == WLAN_HDD_SOFTAP) {
7707
7708 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7709 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7710 if(pSapCtx == NULL){
7711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7712 FL("psapCtx is NULL"));
7713 return -ENOENT;
7714 }
7715
7716
7717 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7718 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7719 !vos_is_macaddr_broadcast(
7720 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7721 vos_mem_compare(
7722 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7723 peer_mac, VOS_MAC_ADDRESS_LEN))
7724 break;
7725 }
7726
7727 if (WLAN_MAX_STA_COUNT == sta_id) {
7728 hddLog(VOS_TRACE_LEVEL_ERROR,
7729 FL("No active peer with mac="MAC_ADDRESS_STR),
7730 MAC_ADDR_ARRAY(peer_mac));
7731 return -EINVAL;
7732 }
7733
7734 nss = 1; //pronto supports only one spatial stream
7735 freq = vos_chan_to_freq(
7736 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7737 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7738 } else {
7739 hddLog(VOS_TRACE_LEVEL_ERROR,
7740 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7741 MAC_ADDR_ARRAY(peer_mac));
7742 return -EINVAL;
7743 }
7744
7745 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7746 if (rate_flags & eHAL_TX_RATE_VHT80) {
7747 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307748#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7749 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307750 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307751#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307752 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7753 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307754#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7755 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307756 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307757#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307758 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7759 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7760 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7761 final_rate_flags |= RATE_INFO_FLAGS_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307762#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7763 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307764 if (rate_flags & eHAL_TX_RATE_HT40)
7765 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 }
7768
7769 if (rate_flags & eHAL_TX_RATE_SGI) {
7770 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7771 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7772 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7773 }
7774 }
7775
7776 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7777 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7778
7779 if (NULL == reply_skb) {
7780 hddLog(VOS_TRACE_LEVEL_ERROR,
7781 FL("getLinkProperties: skb alloc failed"));
7782 return -EINVAL;
7783 }
7784
7785 if (nla_put_u8(reply_skb,
7786 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7787 nss) ||
7788 nla_put_u8(reply_skb,
7789 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7790 final_rate_flags) ||
7791 nla_put_u32(reply_skb,
7792 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7793 freq)) {
7794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7795 kfree_skb(reply_skb);
7796 return -EINVAL;
7797 }
7798
7799 return cfg80211_vendor_cmd_reply(reply_skb);
7800}
7801
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307802#define BEACON_MISS_THRESH_2_4 \
7803 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7804#define BEACON_MISS_THRESH_5_0 \
7805 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307806#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7807#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7808#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7809#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307810#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7811 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307812
7813/**
7814 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7815 * vendor command
7816 *
7817 * @wiphy: wiphy device pointer
7818 * @wdev: wireless device pointer
7819 * @data: Vendor command data buffer
7820 * @data_len: Buffer length
7821 *
7822 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7823 *
7824 * Return: EOK or other error codes.
7825 */
7826
7827static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7828 struct wireless_dev *wdev,
7829 const void *data,
7830 int data_len)
7831{
7832 struct net_device *dev = wdev->netdev;
7833 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7834 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7835 hdd_station_ctx_t *pHddStaCtx;
7836 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7837 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307838 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307839 eHalStatus status;
7840 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307841 uint8_t hb_thresh_val;
7842
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307843 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7844 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7845 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307846 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7847 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7848 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307849 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7850 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307851 };
7852
7853 ENTER();
7854
7855 if (VOS_FTM_MODE == hdd_get_conparam()) {
7856 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7857 return -EINVAL;
7858 }
7859
7860 ret_val = wlan_hdd_validate_context(pHddCtx);
7861 if (ret_val) {
7862 return ret_val;
7863 }
7864
7865 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7866
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307867 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7868 hddLog(LOGE, FL("Invalid ATTR"));
7869 return -EINVAL;
7870 }
7871
7872 /* check the Wifi Capability */
7873 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7874 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7875 {
7876 hddLog(VOS_TRACE_LEVEL_ERROR,
7877 FL("WIFICONFIG not supported by Firmware"));
7878 return -EINVAL;
7879 }
7880
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307881 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7882 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7883 modifyRoamParamsReq.value =
7884 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7885
7886 if (eHAL_STATUS_SUCCESS !=
7887 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7888 {
7889 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7890 ret_val = -EINVAL;
7891 }
7892 return ret_val;
7893 }
7894
7895 /* Moved this down in order to provide provision to set beacon
7896 * miss penalty count irrespective of connection state.
7897 */
7898 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7899 hddLog(LOGE, FL("Not in Connected state!"));
7900 return -ENOTSUPP;
7901 }
7902
7903 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307904
7905 if (!pReq) {
7906 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7907 "%s: Not able to allocate memory for tSetWifiConfigParams",
7908 __func__);
7909 return eHAL_STATUS_E_MALLOC_FAILED;
7910 }
7911
7912 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7913
7914 pReq->sessionId = pAdapter->sessionId;
7915 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7916
7917 if (tb[PARAM_MODULATED_DTIM]) {
7918 pReq->paramValue = nla_get_u32(
7919 tb[PARAM_MODULATED_DTIM]);
7920 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7921 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307922 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307923 hdd_set_pwrparams(pHddCtx);
7924 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7925 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7926
7927 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7928 iw_full_power_cbfn, pAdapter,
7929 eSME_FULL_PWR_NEEDED_BY_HDD);
7930 }
7931 else
7932 {
7933 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7934 }
7935 }
7936
7937 if (tb[PARAM_STATS_AVG_FACTOR]) {
7938 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7939 pReq->paramValue = nla_get_u16(
7940 tb[PARAM_STATS_AVG_FACTOR]);
7941 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7942 pReq->paramType, pReq->paramValue);
7943 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7944
7945 if (eHAL_STATUS_SUCCESS != status)
7946 {
7947 vos_mem_free(pReq);
7948 pReq = NULL;
7949 ret_val = -EPERM;
7950 return ret_val;
7951 }
7952 }
7953
7954
7955 if (tb[PARAM_GUARD_TIME]) {
7956 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7957 pReq->paramValue = nla_get_u32(
7958 tb[PARAM_GUARD_TIME]);
7959 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7960 pReq->paramType, pReq->paramValue);
7961 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7962
7963 if (eHAL_STATUS_SUCCESS != status)
7964 {
7965 vos_mem_free(pReq);
7966 pReq = NULL;
7967 ret_val = -EPERM;
7968 return ret_val;
7969 }
7970
7971 }
7972
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307973 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7974 hb_thresh_val = nla_get_u8(
7975 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7976
7977 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7978 hb_thresh_val);
7979 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7980 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7981 NULL, eANI_BOOLEAN_FALSE);
7982
7983 status = sme_update_hb_threshold(
7984 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7985 WNI_CFG_HEART_BEAT_THRESHOLD,
7986 hb_thresh_val, eCSR_BAND_24);
7987 if (eHAL_STATUS_SUCCESS != status) {
7988 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7989 vos_mem_free(pReq);
7990 pReq = NULL;
7991 return -EPERM;
7992 }
7993 }
7994
7995 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7996 hb_thresh_val = nla_get_u8(
7997 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7998
7999 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
8000 hb_thresh_val);
8001 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
8002 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
8003 NULL, eANI_BOOLEAN_FALSE);
8004
8005 status = sme_update_hb_threshold(
8006 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
8007 WNI_CFG_HEART_BEAT_THRESHOLD,
8008 hb_thresh_val, eCSR_BAND_5G);
8009 if (eHAL_STATUS_SUCCESS != status) {
8010 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
8011 vos_mem_free(pReq);
8012 pReq = NULL;
8013 return -EPERM;
8014 }
8015 }
8016
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308017 EXIT();
8018 return ret_val;
8019}
8020
8021/**
8022 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
8023 * vendor command
8024 *
8025 * @wiphy: wiphy device pointer
8026 * @wdev: wireless device pointer
8027 * @data: Vendor command data buffer
8028 * @data_len: Buffer length
8029 *
8030 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
8031 *
8032 * Return: EOK or other error codes.
8033 */
8034static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
8035 struct wireless_dev *wdev,
8036 const void *data,
8037 int data_len)
8038{
8039 int ret;
8040
8041 vos_ssr_protect(__func__);
8042 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
8043 data, data_len);
8044 vos_ssr_unprotect(__func__);
8045
8046 return ret;
8047}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308048
8049/*
8050 * define short names for the global vendor params
8051 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8052 */
8053#define STATS_SET_INVALID \
8054 QCA_ATTR_NUD_STATS_SET_INVALID
8055#define STATS_SET_START \
8056 QCA_ATTR_NUD_STATS_SET_START
8057#define STATS_GW_IPV4 \
8058 QCA_ATTR_NUD_STATS_GW_IPV4
8059#define STATS_SET_MAX \
8060 QCA_ATTR_NUD_STATS_SET_MAX
8061
8062const struct nla_policy
8063qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
8064{
8065 [STATS_SET_START] = {.type = NLA_FLAG },
8066 [STATS_GW_IPV4] = {.type = NLA_U32 },
8067};
8068
8069/**
8070 * hdd_set_nud_stats_cb() - hdd callback api to get status
8071 * @data: pointer to adapter
8072 * @rsp: status
8073 *
8074 * Return: None
8075 */
8076static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
8077{
8078
8079 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8080
8081 if (NULL == adapter)
8082 return;
8083
8084 if (VOS_STATUS_SUCCESS == rsp) {
8085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8086 "%s success received STATS_SET_START", __func__);
8087 } else {
8088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8089 "%s STATS_SET_START Failed!!", __func__);
8090 }
8091 return;
8092}
8093
8094/**
8095 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8096 * @wiphy: pointer to wireless wiphy structure.
8097 * @wdev: pointer to wireless_dev structure.
8098 * @data: pointer to apfind configuration data.
8099 * @data_len: the length in byte of apfind data.
8100 *
8101 * This is called when wlan driver needs to send arp stats to
8102 * firmware.
8103 *
8104 * Return: An error code or 0 on success.
8105 */
8106static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8107 struct wireless_dev *wdev,
8108 const void *data, int data_len)
8109{
8110 struct nlattr *tb[STATS_SET_MAX + 1];
8111 struct net_device *dev = wdev->netdev;
8112 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8113 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308114 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308115 setArpStatsParams arp_stats_params;
8116 int err = 0;
8117
8118 ENTER();
8119
8120 err = wlan_hdd_validate_context(hdd_ctx);
8121 if (0 != err)
8122 return err;
8123
8124 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8125 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8126 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8127 return -EINVAL;
8128 }
8129
8130 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8131 qca_wlan_vendor_set_nud_stats);
8132 if (err)
8133 {
8134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8135 "%s STATS_SET_START ATTR", __func__);
8136 return err;
8137 }
8138
8139 if (tb[STATS_SET_START])
8140 {
8141 if (!tb[STATS_GW_IPV4]) {
8142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8143 "%s STATS_SET_START CMD", __func__);
8144 return -EINVAL;
8145 }
8146 arp_stats_params.flag = true;
8147 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8148 } else {
8149 arp_stats_params.flag = false;
8150 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308151 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8153 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308154 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8155 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308156
8157 arp_stats_params.pkt_type = 1; // ARP packet type
8158
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308159 if (arp_stats_params.flag) {
8160 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8161 WLANTL_SetARPFWDatapath(pVosContext, true);
8162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8163 "%s Set FW in data path for ARP with tgt IP :%d",
8164 __func__, hdd_ctx->track_arp_ip);
8165 }
8166 else {
8167 WLANTL_SetARPFWDatapath(pVosContext, false);
8168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8169 "%s Remove FW from data path", __func__);
8170 }
8171
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308172 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8173 arp_stats_params.data_ctx = adapter;
8174
8175 if (eHAL_STATUS_SUCCESS !=
8176 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8178 "%s STATS_SET_START CMD Failed!!", __func__);
8179 return -EINVAL;
8180 }
8181
8182 EXIT();
8183
8184 return err;
8185}
8186
8187/**
8188 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8189 * @wiphy: pointer to wireless wiphy structure.
8190 * @wdev: pointer to wireless_dev structure.
8191 * @data: pointer to apfind configuration data.
8192 * @data_len: the length in byte of apfind data.
8193 *
8194 * This is called when wlan driver needs to send arp stats to
8195 * firmware.
8196 *
8197 * Return: An error code or 0 on success.
8198 */
8199static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8200 struct wireless_dev *wdev,
8201 const void *data, int data_len)
8202{
8203 int ret;
8204
8205 vos_ssr_protect(__func__);
8206 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8207 vos_ssr_unprotect(__func__);
8208
8209 return ret;
8210}
8211#undef STATS_SET_INVALID
8212#undef STATS_SET_START
8213#undef STATS_GW_IPV4
8214#undef STATS_SET_MAX
8215
8216/*
8217 * define short names for the global vendor params
8218 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8219 */
8220#define STATS_GET_INVALID \
8221 QCA_ATTR_NUD_STATS_SET_INVALID
8222#define COUNT_FROM_NETDEV \
8223 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8224#define COUNT_TO_LOWER_MAC \
8225 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8226#define RX_COUNT_BY_LOWER_MAC \
8227 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8228#define COUNT_TX_SUCCESS \
8229 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8230#define RSP_RX_COUNT_BY_LOWER_MAC \
8231 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8232#define RSP_RX_COUNT_BY_UPPER_MAC \
8233 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8234#define RSP_COUNT_TO_NETDEV \
8235 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8236#define RSP_COUNT_OUT_OF_ORDER_DROP \
8237 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8238#define AP_LINK_ACTIVE \
8239 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8240#define AP_LINK_DAD \
8241 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8242#define STATS_GET_MAX \
8243 QCA_ATTR_NUD_STATS_GET_MAX
8244
8245const struct nla_policy
8246qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8247{
8248 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8249 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8250 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8251 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8252 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8253 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8254 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8255 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8256 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8257 [AP_LINK_DAD] = {.type = NLA_FLAG },
8258};
8259
8260static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8261{
8262
8263 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308264 hdd_context_t *hdd_ctx;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308265 struct hdd_nud_stats_context *context;
8266 int status;
8267
8268 ENTER();
8269
8270 if (NULL == adapter)
8271 return;
8272
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308273 if (!rsp) {
8274 hddLog(LOGE, FL("data is null"));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308275 return;
8276 }
8277
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308278 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8279 status = wlan_hdd_validate_context(hdd_ctx);
8280 if (0 != status) {
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308281 return;
8282 }
8283
8284 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8285 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8286 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8287 adapter->dad |= rsp->dad;
8288
8289 spin_lock(&hdd_context_lock);
8290 context = &hdd_ctx->nud_stats_context;
8291 complete(&context->response_event);
8292 spin_unlock(&hdd_context_lock);
8293
8294 return;
8295}
8296static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8297 struct wireless_dev *wdev,
8298 const void *data, int data_len)
8299{
8300 int err = 0;
8301 unsigned long rc;
8302 struct hdd_nud_stats_context *context;
8303 struct net_device *dev = wdev->netdev;
8304 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8305 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8306 getArpStatsParams arp_stats_params;
8307 struct sk_buff *skb;
8308
8309 ENTER();
8310
8311 err = wlan_hdd_validate_context(hdd_ctx);
8312 if (0 != err)
8313 return err;
8314
8315 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8316 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8317 arp_stats_params.data_ctx = adapter;
8318
8319 spin_lock(&hdd_context_lock);
8320 context = &hdd_ctx->nud_stats_context;
8321 INIT_COMPLETION(context->response_event);
8322 spin_unlock(&hdd_context_lock);
8323
8324 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8326 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8327 return -EINVAL;
8328 }
8329
8330 if (eHAL_STATUS_SUCCESS !=
8331 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8333 "%s STATS_SET_START CMD Failed!!", __func__);
8334 return -EINVAL;
8335 }
8336
8337 rc = wait_for_completion_timeout(&context->response_event,
8338 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8339 if (!rc)
8340 {
8341 hddLog(LOGE,
8342 FL("Target response timed out request "));
8343 return -ETIMEDOUT;
8344 }
8345
8346 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8347 WLAN_NUD_STATS_LEN);
8348 if (!skb)
8349 {
8350 hddLog(VOS_TRACE_LEVEL_ERROR,
8351 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8352 __func__);
8353 return -ENOMEM;
8354 }
8355
8356 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8357 adapter->hdd_stats.hddArpStats.txCount) ||
8358 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8359 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8360 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8361 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8362 nla_put_u16(skb, COUNT_TX_SUCCESS,
8363 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8364 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8365 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8366 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8367 adapter->hdd_stats.hddArpStats.rxCount) ||
8368 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8369 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8370 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8371 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8372 hddLog(LOGE, FL("nla put fail"));
8373 kfree_skb(skb);
8374 return -EINVAL;
8375 }
8376 if (adapter->con_status)
8377 nla_put_flag(skb, AP_LINK_ACTIVE);
8378 if (adapter->dad)
8379 nla_put_flag(skb, AP_LINK_DAD);
8380
8381 cfg80211_vendor_cmd_reply(skb);
8382 return err;
8383}
8384
8385static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8386 struct wireless_dev *wdev,
8387 const void *data, int data_len)
8388{
8389 int ret;
8390
8391 vos_ssr_protect(__func__);
8392 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8393 vos_ssr_unprotect(__func__);
8394
8395 return ret;
8396}
8397
8398#undef QCA_ATTR_NUD_STATS_SET_INVALID
8399#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8400#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8401#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8402#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8403#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8404#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8405#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8406#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8407#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8408#undef QCA_ATTR_NUD_STATS_GET_MAX
8409
8410
8411
Kapil Guptaee33bf12016-12-20 18:27:37 +05308412#ifdef WLAN_FEATURE_APFIND
8413/**
8414 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8415 * @wiphy: pointer to wireless wiphy structure.
8416 * @wdev: pointer to wireless_dev structure.
8417 * @data: pointer to apfind configuration data.
8418 * @data_len: the length in byte of apfind data.
8419 *
8420 * This is called when wlan driver needs to send APFIND configurations to
8421 * firmware.
8422 *
8423 * Return: An error code or 0 on success.
8424 */
8425static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8426 struct wireless_dev *wdev,
8427 const void *data, int data_len)
8428{
8429 struct sme_ap_find_request_req apfind_req;
8430 VOS_STATUS status;
8431 int ret_val;
8432 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8433
8434 ENTER();
8435
8436 ret_val = wlan_hdd_validate_context(hdd_ctx);
8437 if (ret_val)
8438 return ret_val;
8439
8440 if (VOS_FTM_MODE == hdd_get_conparam()) {
8441 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8442 return -EPERM;
8443 }
8444
8445 apfind_req.request_data_len = data_len;
8446 apfind_req.request_data = data;
8447
8448 status = sme_apfind_set_cmd(&apfind_req);
8449 if (VOS_STATUS_SUCCESS != status) {
8450 ret_val = -EIO;
8451 }
8452 return ret_val;
8453}
8454
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 int ret;
8472
8473 vos_ssr_protect(__func__);
8474 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8475 vos_ssr_unprotect(__func__);
8476
8477 return ret;
8478}
8479#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308480const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8481{
Mukul Sharma2a271632014-10-13 14:59:01 +05308482 {
8483 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8484 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8485 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8486 WIPHY_VENDOR_CMD_NEED_NETDEV |
8487 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308488 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308489 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308490
8491 {
8492 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8493 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8494 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8495 WIPHY_VENDOR_CMD_NEED_NETDEV |
8496 WIPHY_VENDOR_CMD_NEED_RUNNING,
8497 .doit = wlan_hdd_cfg80211_nan_request
8498 },
8499
Sunil Duttc69bccb2014-05-26 21:30:20 +05308500#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8501 {
8502 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8503 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8504 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8505 WIPHY_VENDOR_CMD_NEED_NETDEV |
8506 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308507 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308508 },
8509
8510 {
8511 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8512 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8513 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8514 WIPHY_VENDOR_CMD_NEED_NETDEV |
8515 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308516 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308517 },
8518
8519 {
8520 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8521 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8522 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8523 WIPHY_VENDOR_CMD_NEED_NETDEV |
8524 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308525 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308526 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308527#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308528#ifdef WLAN_FEATURE_EXTSCAN
8529 {
8530 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8531 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8532 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8533 WIPHY_VENDOR_CMD_NEED_NETDEV |
8534 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308535 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308536 },
8537 {
8538 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8539 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8540 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8541 WIPHY_VENDOR_CMD_NEED_NETDEV |
8542 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308543 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308544 },
8545 {
8546 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8547 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8548 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8549 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308550 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308551 },
8552 {
8553 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8554 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8555 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8556 WIPHY_VENDOR_CMD_NEED_NETDEV |
8557 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308558 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308559 },
8560 {
8561 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8562 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8563 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8564 WIPHY_VENDOR_CMD_NEED_NETDEV |
8565 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308566 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308567 },
8568 {
8569 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8570 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8571 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8572 WIPHY_VENDOR_CMD_NEED_NETDEV |
8573 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308574 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308575 },
8576 {
8577 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8578 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8579 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8580 WIPHY_VENDOR_CMD_NEED_NETDEV |
8581 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308582 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308583 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308584#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308585/*EXT TDLS*/
8586 {
8587 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8588 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8589 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8590 WIPHY_VENDOR_CMD_NEED_NETDEV |
8591 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308592 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308593 },
8594 {
8595 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8596 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8597 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8598 WIPHY_VENDOR_CMD_NEED_NETDEV |
8599 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308600 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308601 },
8602 {
8603 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8604 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8605 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8606 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308607 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308608 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308609 {
8610 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8611 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8612 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8613 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308614 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308615 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308616 {
8617 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8618 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8619 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8620 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308621 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308622 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308623 {
8624 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8625 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8626 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8627 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308628 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308629 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308630 {
8631 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8632 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8633 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8634 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308635 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308636 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308637 {
8638 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308639 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8640 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8641 WIPHY_VENDOR_CMD_NEED_NETDEV |
8642 WIPHY_VENDOR_CMD_NEED_RUNNING,
8643 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8644 },
8645 {
8646 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308647 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8648 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8649 WIPHY_VENDOR_CMD_NEED_NETDEV |
8650 WIPHY_VENDOR_CMD_NEED_RUNNING,
8651 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308652 },
8653 {
8654 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8655 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8656 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8657 WIPHY_VENDOR_CMD_NEED_NETDEV,
8658 .doit = wlan_hdd_cfg80211_wifi_logger_start
8659 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308660 {
8661 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8662 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8663 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8664 WIPHY_VENDOR_CMD_NEED_NETDEV|
8665 WIPHY_VENDOR_CMD_NEED_RUNNING,
8666 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308667 },
8668 {
8669 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8670 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8671 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8672 WIPHY_VENDOR_CMD_NEED_NETDEV |
8673 WIPHY_VENDOR_CMD_NEED_RUNNING,
8674 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308675 },
8676 {
8677 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8678 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8679 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8680 WIPHY_VENDOR_CMD_NEED_NETDEV |
8681 WIPHY_VENDOR_CMD_NEED_RUNNING,
8682 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308683 },
8684#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8685 {
8686 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8687 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8688 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8689 WIPHY_VENDOR_CMD_NEED_NETDEV |
8690 WIPHY_VENDOR_CMD_NEED_RUNNING,
8691 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308692 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308693#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308694 {
8695 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8696 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8697 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8698 WIPHY_VENDOR_CMD_NEED_NETDEV |
8699 WIPHY_VENDOR_CMD_NEED_RUNNING,
8700 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308701 },
8702 {
8703 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8704 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8705 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8706 WIPHY_VENDOR_CMD_NEED_NETDEV |
8707 WIPHY_VENDOR_CMD_NEED_RUNNING,
8708 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308709 },
8710#ifdef WLAN_FEATURE_APFIND
8711 {
8712 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8713 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8714 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8715 WIPHY_VENDOR_CMD_NEED_NETDEV,
8716 .doit = wlan_hdd_cfg80211_apfind_cmd
8717 },
8718#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308719 {
8720 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8721 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8722 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8723 WIPHY_VENDOR_CMD_NEED_NETDEV |
8724 WIPHY_VENDOR_CMD_NEED_RUNNING,
8725 .doit = wlan_hdd_cfg80211_set_nud_stats
8726 },
8727 {
8728 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8729 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8730 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8731 WIPHY_VENDOR_CMD_NEED_NETDEV |
8732 WIPHY_VENDOR_CMD_NEED_RUNNING,
8733 .doit = wlan_hdd_cfg80211_get_nud_stats
8734 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308735 {
8736 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8737 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8738 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8739 WIPHY_VENDOR_CMD_NEED_NETDEV |
8740 WIPHY_VENDOR_CMD_NEED_RUNNING,
8741 .doit = hdd_cfg80211_get_station_cmd
8742 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308743};
8744
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008745/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308746static const
8747struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008748{
8749#ifdef FEATURE_WLAN_CH_AVOID
8750 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308751 .vendor_id = QCA_NL80211_VENDOR_ID,
8752 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008753 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308754#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8755#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8756 {
8757 /* Index = 1*/
8758 .vendor_id = QCA_NL80211_VENDOR_ID,
8759 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8760 },
8761 {
8762 /* Index = 2*/
8763 .vendor_id = QCA_NL80211_VENDOR_ID,
8764 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8765 },
8766 {
8767 /* Index = 3*/
8768 .vendor_id = QCA_NL80211_VENDOR_ID,
8769 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8770 },
8771 {
8772 /* Index = 4*/
8773 .vendor_id = QCA_NL80211_VENDOR_ID,
8774 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8775 },
8776 {
8777 /* Index = 5*/
8778 .vendor_id = QCA_NL80211_VENDOR_ID,
8779 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8780 },
8781 {
8782 /* Index = 6*/
8783 .vendor_id = QCA_NL80211_VENDOR_ID,
8784 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8785 },
8786#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308787#ifdef WLAN_FEATURE_EXTSCAN
8788 {
8789 .vendor_id = QCA_NL80211_VENDOR_ID,
8790 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8791 },
8792 {
8793 .vendor_id = QCA_NL80211_VENDOR_ID,
8794 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8795 },
8796 {
8797 .vendor_id = QCA_NL80211_VENDOR_ID,
8798 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8799 },
8800 {
8801 .vendor_id = QCA_NL80211_VENDOR_ID,
8802 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8803 },
8804 {
8805 .vendor_id = QCA_NL80211_VENDOR_ID,
8806 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8807 },
8808 {
8809 .vendor_id = QCA_NL80211_VENDOR_ID,
8810 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8811 },
8812 {
8813 .vendor_id = QCA_NL80211_VENDOR_ID,
8814 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8815 },
8816 {
8817 .vendor_id = QCA_NL80211_VENDOR_ID,
8818 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8819 },
8820 {
8821 .vendor_id = QCA_NL80211_VENDOR_ID,
8822 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8823 },
8824 {
8825 .vendor_id = QCA_NL80211_VENDOR_ID,
8826 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8827 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308828#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308829/*EXT TDLS*/
8830 {
8831 .vendor_id = QCA_NL80211_VENDOR_ID,
8832 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8833 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308834 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8835 .vendor_id = QCA_NL80211_VENDOR_ID,
8836 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8837 },
8838
Srinivas Dasari030bad32015-02-18 23:23:54 +05308839
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308840 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308841 .vendor_id = QCA_NL80211_VENDOR_ID,
8842 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8843 },
8844
Sushant Kaushik084f6592015-09-10 13:11:56 +05308845 {
8846 .vendor_id = QCA_NL80211_VENDOR_ID,
8847 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308848 },
8849 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8850 .vendor_id = QCA_NL80211_VENDOR_ID,
8851 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8852 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308853 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8854 .vendor_id = QCA_NL80211_VENDOR_ID,
8855 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8856 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308857 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8858 .vendor_id = QCA_NL80211_VENDOR_ID,
8859 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8860 },
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05308861 [QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
8862 .vendor_id = QCA_NL80211_VENDOR_ID,
8863 .subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
8864 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008865};
8866
Jeff Johnson295189b2012-06-20 16:38:30 -07008867/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308868 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308869 * This function is called by hdd_wlan_startup()
8870 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308871 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008872 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308873struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008874{
8875 struct wiphy *wiphy;
8876 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308877 /*
8878 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008879 */
8880 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8881
8882 if (!wiphy)
8883 {
8884 /* Print error and jump into err label and free the memory */
8885 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8886 return NULL;
8887 }
8888
Sunil Duttc69bccb2014-05-26 21:30:20 +05308889
Jeff Johnson295189b2012-06-20 16:38:30 -07008890 return wiphy;
8891}
8892
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308893#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8894 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8895/**
8896 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8897 * @wiphy: pointer to wiphy
8898 * @config: pointer to config
8899 *
8900 * Return: None
8901 */
8902static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8903 hdd_config_t *config)
8904{
8905 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
8906 if (config->max_sched_scan_plan_interval)
8907 wiphy->max_sched_scan_plan_interval =
8908 config->max_sched_scan_plan_interval;
8909 if (config->max_sched_scan_plan_iterations)
8910 wiphy->max_sched_scan_plan_iterations =
8911 config->max_sched_scan_plan_iterations;
8912}
8913#else
8914static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8915 hdd_config_t *config)
8916{
8917}
8918#endif
8919
Jeff Johnson295189b2012-06-20 16:38:30 -07008920/*
8921 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308922 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07008923 * private ioctl to change the band value
8924 */
8925int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
8926{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308927 int i, j;
8928 eNVChannelEnabledType channelEnabledState;
8929
Jeff Johnsone7245742012-09-05 17:12:55 -07008930 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308931
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308932 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008933 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308934
8935 if (NULL == wiphy->bands[i])
8936 {
8937 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
8938 __func__, i);
8939 continue;
8940 }
8941
8942 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8943 {
8944 struct ieee80211_supported_band *band = wiphy->bands[i];
8945
8946 channelEnabledState = vos_nv_getChannelEnabledState(
8947 band->channels[j].hw_value);
8948
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308949 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308950 {
Abhishek Singh678227a2014-11-04 10:52:38 +05308951 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308952 continue;
8953 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308954 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308955 {
8956 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8957 continue;
8958 }
8959
8960 if (NV_CHANNEL_DISABLE == channelEnabledState ||
8961 NV_CHANNEL_INVALID == channelEnabledState)
8962 {
8963 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8964 }
8965 else if (NV_CHANNEL_DFS == channelEnabledState)
8966 {
8967 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8968 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
8969 }
8970 else
8971 {
8972 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
8973 |IEEE80211_CHAN_RADAR);
8974 }
8975 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008976 }
8977 return 0;
8978}
8979/*
8980 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308981 * This function is called by hdd_wlan_startup()
8982 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07008983 * This function is used to initialize and register wiphy structure.
8984 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308985int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008986 struct wiphy *wiphy,
8987 hdd_config_t *pCfg
8988 )
8989{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308990 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308991 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8992
Jeff Johnsone7245742012-09-05 17:12:55 -07008993 ENTER();
8994
Jeff Johnson295189b2012-06-20 16:38:30 -07008995 /* Now bind the underlying wlan device with wiphy */
8996 set_wiphy_dev(wiphy, dev);
8997
8998 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008999
Kiet Lam6c583332013-10-14 05:37:09 +05309000#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009001 /* the flag for the other case would be initialzed in
9002 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05309003#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9004 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
9005#else
Amar Singhal0a402232013-10-11 20:57:16 -07009006 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05309007#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05309008#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009009
Amar Singhalfddc28c2013-09-05 13:03:40 -07009010 /* This will disable updating of NL channels from passive to
9011 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309012#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9013 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
9014#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07009015 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309016#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07009017
Amar Singhala49cbc52013-10-08 18:37:44 -07009018
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009019#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009020 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
9021 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
9022 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07009023 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309024#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05309025 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309026#else
9027 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
9028#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009029#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009030
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009031#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009032 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08009033#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009034 || pCfg->isFastRoamIniFeatureEnabled
9035#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009036#ifdef FEATURE_WLAN_ESE
9037 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009038#endif
9039 )
9040 {
9041 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
9042 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08009043#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009044#ifdef FEATURE_WLAN_TDLS
9045 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
9046 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
9047#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309048#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05309049 if (pCfg->configPNOScanSupport)
9050 {
9051 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
9052 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
9053 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
9054 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
9055 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309056#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009057
Abhishek Singh10d85972015-04-17 10:27:23 +05309058#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9059 wiphy->features |= NL80211_FEATURE_HT_IBSS;
9060#endif
9061
Amar Singhalfddc28c2013-09-05 13:03:40 -07009062#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009063 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
9064 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07009065 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009066 driver need to determine what to do with both
9067 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07009068
9069 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07009070#else
9071 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009072#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009073
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309074 wiphy->max_scan_ssids = MAX_SCAN_SSID;
9075
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05309076 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07009077
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309078 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
9079
Jeff Johnson295189b2012-06-20 16:38:30 -07009080 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05309081 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
9082 | BIT(NL80211_IFTYPE_ADHOC)
9083 | BIT(NL80211_IFTYPE_P2P_CLIENT)
9084 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309085 | BIT(NL80211_IFTYPE_AP)
9086 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07009087
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309088 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009089 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309090#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9091 if( pCfg->enableMCC )
9092 {
9093 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309094 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009095
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309096 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309097 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009098
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309099 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309100 wiphy->iface_combinations = wlan_hdd_iface_combination;
9101 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009102#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309103 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009104
Jeff Johnson295189b2012-06-20 16:38:30 -07009105 /* Before registering we need to update the ht capabilitied based
9106 * on ini values*/
9107 if( !pCfg->ShortGI20MhzEnable )
9108 {
9109 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
9110 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07009111 }
9112
9113 if( !pCfg->ShortGI40MhzEnable )
9114 {
9115 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9116 }
9117
9118 if( !pCfg->nChannelBondingMode5GHz )
9119 {
9120 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9121 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309122 /*
9123 * In case of static linked driver at the time of driver unload,
9124 * module exit doesn't happens. Module cleanup helps in cleaning
9125 * of static memory.
9126 * If driver load happens statically, at the time of driver unload,
9127 * wiphy flags don't get reset because of static memory.
9128 * It's better not to store channel in static memory.
9129 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309130 wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9131 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309132 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309133 if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309134 {
9135 hddLog(VOS_TRACE_LEVEL_ERROR,
9136 FL("Not enough memory to allocate channels"));
9137 return -ENOMEM;
9138 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309139 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309140 &hdd_channels_2_4_GHZ[0],
9141 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009142
Agrawal Ashish97dec502015-11-26 20:20:58 +05309143 if (true == hdd_is_5g_supported(pHddCtx))
9144 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309145 wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9146 wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309147 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309148 if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309149 {
9150 hddLog(VOS_TRACE_LEVEL_ERROR,
9151 FL("Not enough memory to allocate channels"));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309152 vos_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
9153 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
Agrawal Ashish97dec502015-11-26 20:20:58 +05309154 return -ENOMEM;
9155 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309156 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309157 &hdd_channels_5_GHZ[0],
9158 sizeof(hdd_channels_5_GHZ));
9159 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309160
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309161 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309162 {
9163
9164 if (NULL == wiphy->bands[i])
9165 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309166 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309167 __func__, i);
9168 continue;
9169 }
9170
9171 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9172 {
9173 struct ieee80211_supported_band *band = wiphy->bands[i];
9174
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309175 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309176 {
9177 // Enable social channels for P2P
9178 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9179 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9180 else
9181 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9182 continue;
9183 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309184 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309185 {
9186 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9187 continue;
9188 }
9189 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009190 }
9191 /*Initialise the supported cipher suite details*/
9192 wiphy->cipher_suites = hdd_cipher_suites;
9193 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9194
9195 /*signal strength in mBm (100*dBm) */
9196 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9197
9198#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309199 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009200#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009201
Sunil Duttc69bccb2014-05-26 21:30:20 +05309202 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9203 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009204 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9205 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9206
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309207 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
9208
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309209 EXIT();
9210 return 0;
9211}
9212
9213/* In this function we are registering wiphy. */
9214int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9215{
9216 ENTER();
9217 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009218 if (0 > wiphy_register(wiphy))
9219 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309220 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009221 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9222 return -EIO;
9223 }
9224
9225 EXIT();
9226 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309227}
Jeff Johnson295189b2012-06-20 16:38:30 -07009228
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309229/* In this function we are updating channel list when,
9230 regulatory domain is FCC and country code is US.
9231 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9232 As per FCC smart phone is not a indoor device.
9233 GO should not opeate on indoor channels */
9234void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9235{
9236 int j;
9237 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9238 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9239 //Default counrtycode from NV at the time of wiphy initialization.
9240 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9241 &defaultCountryCode[0]))
9242 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009243 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309244 }
9245 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9246 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309247 if (NULL == wiphy->bands[HDD_NL80211_BAND_5GHZ])
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309248 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309249 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[HDD_NL80211_BAND_5GHZ] is NULL",__func__ );
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309250 return;
9251 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309252 for (j = 0; j < wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels; j++)
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309253 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309254 struct ieee80211_supported_band *band = wiphy->bands[HDD_NL80211_BAND_5GHZ];
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309255 // Mark UNII -1 band channel as passive
9256 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9257 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9258 }
9259 }
9260}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309261/* This function registers for all frame which supplicant is interested in */
9262void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009263{
Jeff Johnson295189b2012-06-20 16:38:30 -07009264 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9265 /* Register for all P2P action, public action etc frames */
9266 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009267 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309268 /* Register frame indication call back */
9269 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009270 /* Right now we are registering these frame when driver is getting
9271 initialized. Once we will move to 2.6.37 kernel, in which we have
9272 frame register ops, we will move this code as a part of that */
9273 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309274 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009275 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9276
9277 /* GAS Initial Response */
9278 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9279 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309280
Jeff Johnson295189b2012-06-20 16:38:30 -07009281 /* GAS Comeback Request */
9282 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9283 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9284
9285 /* GAS Comeback Response */
9286 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9287 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9288
9289 /* P2P Public Action */
9290 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309291 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009292 P2P_PUBLIC_ACTION_FRAME_SIZE );
9293
9294 /* P2P Action */
9295 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9296 (v_U8_t*)P2P_ACTION_FRAME,
9297 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009298
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309299 /* WNM BSS Transition Request frame */
9300 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9301 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9302 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009303
9304 /* WNM-Notification */
9305 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9306 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9307 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009308}
9309
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309310void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009311{
Jeff Johnson295189b2012-06-20 16:38:30 -07009312 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9313 /* Register for all P2P action, public action etc frames */
9314 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9315
Jeff Johnsone7245742012-09-05 17:12:55 -07009316 ENTER();
9317
Jeff Johnson295189b2012-06-20 16:38:30 -07009318 /* Right now we are registering these frame when driver is getting
9319 initialized. Once we will move to 2.6.37 kernel, in which we have
9320 frame register ops, we will move this code as a part of that */
9321 /* GAS Initial Request */
9322
9323 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9324 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9325
9326 /* GAS Initial Response */
9327 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9328 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309329
Jeff Johnson295189b2012-06-20 16:38:30 -07009330 /* GAS Comeback Request */
9331 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9332 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9333
9334 /* GAS Comeback Response */
9335 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9336 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9337
9338 /* P2P Public Action */
9339 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309340 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009341 P2P_PUBLIC_ACTION_FRAME_SIZE );
9342
9343 /* P2P Action */
9344 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9345 (v_U8_t*)P2P_ACTION_FRAME,
9346 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009347 /* WNM-Notification */
9348 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9349 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9350 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009351}
9352
9353#ifdef FEATURE_WLAN_WAPI
9354void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309355 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009356{
9357 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9358 tCsrRoamSetKey setKey;
9359 v_BOOL_t isConnected = TRUE;
9360 int status = 0;
9361 v_U32_t roamId= 0xFF;
9362 tANI_U8 *pKeyPtr = NULL;
9363 int n = 0;
9364
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309365 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9366 __func__, hdd_device_modetoString(pAdapter->device_mode),
9367 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009368
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309369 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009370 setKey.keyId = key_index; // Store Key ID
9371 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9372 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9373 setKey.paeRole = 0 ; // the PAE role
9374 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9375 {
9376 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9377 }
9378 else
9379 {
9380 isConnected = hdd_connIsConnected(pHddStaCtx);
9381 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9382 }
9383 setKey.keyLength = key_Len;
9384 pKeyPtr = setKey.Key;
9385 memcpy( pKeyPtr, key, key_Len);
9386
Arif Hussain6d2a3322013-11-17 19:50:10 -08009387 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009388 __func__, key_Len);
9389 for (n = 0 ; n < key_Len; n++)
9390 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9391 __func__,n,setKey.Key[n]);
9392
9393 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9394 if ( isConnected )
9395 {
9396 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9397 pAdapter->sessionId, &setKey, &roamId );
9398 }
9399 if ( status != 0 )
9400 {
9401 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9402 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9403 __LINE__, status );
9404 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9405 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309406 /* Need to clear any trace of key value in the memory.
9407 * Thus zero out the memory even though it is local
9408 * variable.
9409 */
9410 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009411}
9412#endif /* FEATURE_WLAN_WAPI*/
9413
9414#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309415int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009416 beacon_data_t **ppBeacon,
9417 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009418#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309419int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009420 beacon_data_t **ppBeacon,
9421 struct cfg80211_beacon_data *params,
9422 int dtim_period)
9423#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309424{
Jeff Johnson295189b2012-06-20 16:38:30 -07009425 int size;
9426 beacon_data_t *beacon = NULL;
9427 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309428 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9429 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009430
Jeff Johnsone7245742012-09-05 17:12:55 -07009431 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009432 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309433 {
9434 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9435 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009436 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309437 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009438
9439 old = pAdapter->sessionCtx.ap.beacon;
9440
9441 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309442 {
9443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9444 FL("session(%d) old and new heads points to NULL"),
9445 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009446 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309447 }
9448
9449 if (params->tail && !params->tail_len)
9450 {
9451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9452 FL("tail_len is zero but tail is not NULL"));
9453 return -EINVAL;
9454 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009455
Jeff Johnson295189b2012-06-20 16:38:30 -07009456#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9457 /* Kernel 3.0 is not updating dtim_period for set beacon */
9458 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309459 {
9460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9461 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009462 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309463 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009464#endif
9465
Kapil Gupta137ef892016-12-13 19:38:00 +05309466 if (params->head)
9467 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009468 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309469 head = params->head;
9470 } else
9471 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009472 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309473 head = old->head;
9474 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009475
Kapil Gupta137ef892016-12-13 19:38:00 +05309476 if (params->tail || !old)
9477 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009478 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309479 tail = params->tail;
9480 } else
9481 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009482 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309483 tail = old->tail;
9484 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009485
Kapil Gupta137ef892016-12-13 19:38:00 +05309486 if (params->proberesp_ies || !old)
9487 {
9488 proberesp_ies_len = params->proberesp_ies_len;
9489 proberesp_ies = params->proberesp_ies;
9490 } else
9491 {
9492 proberesp_ies_len = old->proberesp_ies_len;
9493 proberesp_ies = old->proberesp_ies;
9494 }
9495
9496 if (params->assocresp_ies || !old)
9497 {
9498 assocresp_ies_len = params->assocresp_ies_len;
9499 assocresp_ies = params->assocresp_ies;
9500 } else
9501 {
9502 assocresp_ies_len = old->assocresp_ies_len;
9503 assocresp_ies = old->assocresp_ies;
9504 }
9505
9506 size = sizeof(beacon_data_t) + head_len + tail_len +
9507 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009508
9509 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009510 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309511 {
9512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9513 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009514 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309515 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009516
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009517#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309518 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009519 beacon->dtim_period = params->dtim_period;
9520 else
9521 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009522#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309523 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009524 beacon->dtim_period = dtim_period;
9525 else
9526 beacon->dtim_period = old->dtim_period;
9527#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309528
Jeff Johnson295189b2012-06-20 16:38:30 -07009529 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9530 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309531 beacon->proberesp_ies = beacon->tail + tail_len;
9532 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9533
Jeff Johnson295189b2012-06-20 16:38:30 -07009534 beacon->head_len = head_len;
9535 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309536 beacon->proberesp_ies_len = proberesp_ies_len;
9537 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009538
c_manjee527ecac2017-01-25 12:25:27 +05309539 if (head && head_len)
9540 memcpy(beacon->head, head, head_len);
9541 if (tail && tail_len)
9542 memcpy(beacon->tail, tail, tail_len);
9543 if (proberesp_ies && proberesp_ies_len)
9544 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9545 if (assocresp_ies && assocresp_ies_len)
9546 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009547
9548 *ppBeacon = beacon;
9549
9550 kfree(old);
9551
9552 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009553}
Jeff Johnson295189b2012-06-20 16:38:30 -07009554
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309555v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9556#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9557 const v_U8_t *pIes,
9558#else
9559 v_U8_t *pIes,
9560#endif
9561 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009562{
9563 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309564 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009565 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309566
Jeff Johnson295189b2012-06-20 16:38:30 -07009567 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309568 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009569 elem_id = ptr[0];
9570 elem_len = ptr[1];
9571 left -= 2;
9572 if(elem_len > left)
9573 {
9574 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009575 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009576 eid,elem_len,left);
9577 return NULL;
9578 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309579 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009580 {
9581 return ptr;
9582 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309583
Jeff Johnson295189b2012-06-20 16:38:30 -07009584 left -= elem_len;
9585 ptr += (elem_len + 2);
9586 }
9587 return NULL;
9588}
9589
Jeff Johnson295189b2012-06-20 16:38:30 -07009590/* Check if rate is 11g rate or not */
9591static int wlan_hdd_rate_is_11g(u8 rate)
9592{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009593 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009594 u8 i;
9595 for (i = 0; i < 8; i++)
9596 {
9597 if(rate == gRateArray[i])
9598 return TRUE;
9599 }
9600 return FALSE;
9601}
9602
9603/* Check for 11g rate and set proper 11g only mode */
9604static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9605 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9606{
9607 u8 i, num_rates = pIe[0];
9608
9609 pIe += 1;
9610 for ( i = 0; i < num_rates; i++)
9611 {
9612 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9613 {
9614 /* If rate set have 11g rate than change the mode to 11G */
9615 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9616 if (pIe[i] & BASIC_RATE_MASK)
9617 {
9618 /* If we have 11g rate as basic rate, it means mode
9619 is 11g only mode.
9620 */
9621 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9622 *pCheckRatesfor11g = FALSE;
9623 }
9624 }
9625 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9626 {
9627 *require_ht = TRUE;
9628 }
9629 }
9630 return;
9631}
9632
9633static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9634{
9635 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9636 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9637 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9638 u8 checkRatesfor11g = TRUE;
9639 u8 require_ht = FALSE;
9640 u8 *pIe=NULL;
9641
9642 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9643
9644 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9645 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9646 if (pIe != NULL)
9647 {
9648 pIe += 1;
9649 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9650 &pConfig->SapHw_mode);
9651 }
9652
9653 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9654 WLAN_EID_EXT_SUPP_RATES);
9655 if (pIe != NULL)
9656 {
9657
9658 pIe += 1;
9659 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9660 &pConfig->SapHw_mode);
9661 }
9662
9663 if( pConfig->channel > 14 )
9664 {
9665 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9666 }
9667
9668 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9669 WLAN_EID_HT_CAPABILITY);
9670
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309671 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009672 {
9673 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9674 if(require_ht)
9675 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9676 }
9677}
9678
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309679static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9680 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9681{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009682 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309683 v_U8_t *pIe = NULL;
9684 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9685
9686 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9687 pBeacon->tail, pBeacon->tail_len);
9688
9689 if (pIe)
9690 {
9691 ielen = pIe[1] + 2;
9692 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9693 {
9694 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9695 }
9696 else
9697 {
9698 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9699 return -EINVAL;
9700 }
9701 *total_ielen += ielen;
9702 }
9703 return 0;
9704}
9705
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009706static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9707 v_U8_t *genie, v_U8_t *total_ielen)
9708{
9709 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9710 int left = pBeacon->tail_len;
9711 v_U8_t *ptr = pBeacon->tail;
9712 v_U8_t elem_id, elem_len;
9713 v_U16_t ielen = 0;
9714
9715 if ( NULL == ptr || 0 == left )
9716 return;
9717
9718 while (left >= 2)
9719 {
9720 elem_id = ptr[0];
9721 elem_len = ptr[1];
9722 left -= 2;
9723 if (elem_len > left)
9724 {
9725 hddLog( VOS_TRACE_LEVEL_ERROR,
9726 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9727 elem_id, elem_len, left);
9728 return;
9729 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309730 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009731 {
9732 /* skipping the VSIE's which we don't want to include or
9733 * it will be included by existing code
9734 */
9735 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9736#ifdef WLAN_FEATURE_WFD
9737 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9738#endif
9739 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9740 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9741 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9742 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9743 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9744 {
9745 ielen = ptr[1] + 2;
9746 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9747 {
9748 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9749 *total_ielen += ielen;
9750 }
9751 else
9752 {
9753 hddLog( VOS_TRACE_LEVEL_ERROR,
9754 "IE Length is too big "
9755 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9756 elem_id, elem_len, *total_ielen);
9757 }
9758 }
9759 }
9760
9761 left -= elem_len;
9762 ptr += (elem_len + 2);
9763 }
9764 return;
9765}
9766
Kapil Gupta137ef892016-12-13 19:38:00 +05309767int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009768{
9769 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309770 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009771 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009772 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309773 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009774
9775 genie = vos_mem_malloc(MAX_GENIE_LEN);
9776
9777 if(genie == NULL) {
9778
9779 return -ENOMEM;
9780 }
9781
Kapil Gupta137ef892016-12-13 19:38:00 +05309782 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309783 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9784 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009785 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309786 hddLog(LOGE,
9787 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309788 ret = -EINVAL;
9789 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009790 }
9791
9792#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309793 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9794 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9795 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309796 hddLog(LOGE,
9797 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309798 ret = -EINVAL;
9799 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009800 }
9801#endif
9802
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309803 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9804 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009805 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309806 hddLog(LOGE,
9807 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309808 ret = -EINVAL;
9809 goto done;
9810 }
9811
9812 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9813 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009814 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009815 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009816
9817 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9818 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9819 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9820 {
9821 hddLog(LOGE,
9822 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009823 ret = -EINVAL;
9824 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009825 }
9826
9827 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9828 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9829 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9830 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9831 ==eHAL_STATUS_FAILURE)
9832 {
9833 hddLog(LOGE,
9834 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009835 ret = -EINVAL;
9836 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009837 }
9838
9839 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309840 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009841 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309842 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009843 u8 probe_rsp_ie_len[3] = {0};
9844 u8 counter = 0;
9845 /* Check Probe Resp Length if it is greater then 255 then Store
9846 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9847 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9848 Store More then 255 bytes into One Variable.
9849 */
9850 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9851 {
9852 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9853 {
9854 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9855 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9856 }
9857 else
9858 {
9859 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9860 rem_probe_resp_ie_len = 0;
9861 }
9862 }
9863
9864 rem_probe_resp_ie_len = 0;
9865
9866 if (probe_rsp_ie_len[0] > 0)
9867 {
9868 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9869 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05309870 (tANI_U8*)&pBeacon->
9871 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009872 probe_rsp_ie_len[0], NULL,
9873 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9874 {
9875 hddLog(LOGE,
9876 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009877 ret = -EINVAL;
9878 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009879 }
9880 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9881 }
9882
9883 if (probe_rsp_ie_len[1] > 0)
9884 {
9885 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9886 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +05309887 (tANI_U8*)&pBeacon->
9888 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009889 probe_rsp_ie_len[1], NULL,
9890 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9891 {
9892 hddLog(LOGE,
9893 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009894 ret = -EINVAL;
9895 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009896 }
9897 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9898 }
9899
9900 if (probe_rsp_ie_len[2] > 0)
9901 {
9902 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9903 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +05309904 (tANI_U8*)&pBeacon->
9905 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009906 probe_rsp_ie_len[2], NULL,
9907 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9908 {
9909 hddLog(LOGE,
9910 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009911 ret = -EINVAL;
9912 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009913 }
9914 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9915 }
9916
9917 if (probe_rsp_ie_len[1] == 0 )
9918 {
9919 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9920 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9921 eANI_BOOLEAN_FALSE) )
9922 {
9923 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009924 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009925 }
9926 }
9927
9928 if (probe_rsp_ie_len[2] == 0 )
9929 {
9930 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9931 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9932 eANI_BOOLEAN_FALSE) )
9933 {
9934 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009935 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009936 }
9937 }
9938
9939 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9940 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9941 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9942 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9943 == eHAL_STATUS_FAILURE)
9944 {
9945 hddLog(LOGE,
9946 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009947 ret = -EINVAL;
9948 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009949 }
9950 }
9951 else
9952 {
9953 // Reset WNI_CFG_PROBE_RSP Flags
9954 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
9955
9956 hddLog(VOS_TRACE_LEVEL_INFO,
9957 "%s: No Probe Response IE received in set beacon",
9958 __func__);
9959 }
9960
9961 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309962 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009963 {
9964 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05309965 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
9966 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07009967 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9968 {
9969 hddLog(LOGE,
9970 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009971 ret = -EINVAL;
9972 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009973 }
9974
9975 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9976 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
9977 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9978 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9979 == eHAL_STATUS_FAILURE)
9980 {
9981 hddLog(LOGE,
9982 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009983 ret = -EINVAL;
9984 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009985 }
9986 }
9987 else
9988 {
9989 hddLog(VOS_TRACE_LEVEL_INFO,
9990 "%s: No Assoc Response IE received in set beacon",
9991 __func__);
9992
9993 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9994 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9995 eANI_BOOLEAN_FALSE) )
9996 {
9997 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009998 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009999 }
10000 }
10001
Jeff Johnsone7245742012-09-05 17:12:55 -070010002done:
Jeff Johnson295189b2012-06-20 16:38:30 -070010003 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010004 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010005}
Jeff Johnson295189b2012-06-20 16:38:30 -070010006
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010007/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010008 * FUNCTION: wlan_hdd_validate_operation_channel
10009 * called by wlan_hdd_cfg80211_start_bss() and
10010 * wlan_hdd_cfg80211_set_channel()
10011 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010012 * channel list.
10013 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -070010014VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010015{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010016
Jeff Johnson295189b2012-06-20 16:38:30 -070010017 v_U32_t num_ch = 0;
10018 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10019 u32 indx = 0;
10020 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010021 v_U8_t fValidChannel = FALSE, count = 0;
10022 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010023
Jeff Johnson295189b2012-06-20 16:38:30 -070010024 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10025
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010026 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010027 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010028 /* Validate the channel */
10029 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010030 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010031 if ( channel == rfChannels[count].channelNum )
10032 {
10033 fValidChannel = TRUE;
10034 break;
10035 }
10036 }
10037 if (fValidChannel != TRUE)
10038 {
10039 hddLog(VOS_TRACE_LEVEL_ERROR,
10040 "%s: Invalid Channel [%d]", __func__, channel);
10041 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010042 }
10043 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010044 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010045 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010046 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10047 valid_ch, &num_ch))
10048 {
10049 hddLog(VOS_TRACE_LEVEL_ERROR,
10050 "%s: failed to get valid channel list", __func__);
10051 return VOS_STATUS_E_FAILURE;
10052 }
10053 for (indx = 0; indx < num_ch; indx++)
10054 {
10055 if (channel == valid_ch[indx])
10056 {
10057 break;
10058 }
10059 }
10060
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010061 if (indx >= num_ch)
10062 {
10063 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10064 {
10065 eCsrBand band;
10066 unsigned int freq;
10067
10068 sme_GetFreqBand(hHal, &band);
10069
10070 if (eCSR_BAND_5G == band)
10071 {
10072#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10073 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10074 {
10075 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010076 HDD_NL80211_BAND_2GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010077 }
10078 else
10079 {
10080 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010081 HDD_NL80211_BAND_5GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010082 }
10083#else
10084 freq = ieee80211_channel_to_frequency(channel);
10085#endif
10086 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
10087 return VOS_STATUS_SUCCESS;
10088 }
10089 }
10090
10091 hddLog(VOS_TRACE_LEVEL_ERROR,
10092 "%s: Invalid Channel [%d]", __func__, channel);
10093 return VOS_STATUS_E_FAILURE;
10094 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010095 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010096
Jeff Johnson295189b2012-06-20 16:38:30 -070010097 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010098
Jeff Johnson295189b2012-06-20 16:38:30 -070010099}
10100
Viral Modi3a32cc52013-02-08 11:14:52 -080010101/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010102 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -080010103 * This function is used to set the channel number
10104 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010105static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -080010106 struct ieee80211_channel *chan,
10107 enum nl80211_channel_type channel_type
10108 )
10109{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010110 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -080010111 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -070010112 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -080010113 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010114 hdd_context_t *pHddCtx;
10115 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010116
10117 ENTER();
10118
10119 if( NULL == dev )
10120 {
10121 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010122 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010123 return -ENODEV;
10124 }
10125 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010126
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010127 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10128 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10129 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010130 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010131 "%s: device_mode = %s (%d) freq = %d", __func__,
10132 hdd_device_modetoString(pAdapter->device_mode),
10133 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010134
10135 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10136 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010137 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010138 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010139 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010140 }
10141
10142 /*
10143 * Do freq to chan conversion
10144 * TODO: for 11a
10145 */
10146
10147 channel = ieee80211_frequency_to_channel(freq);
10148
10149 /* Check freq range */
10150 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10151 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10152 {
10153 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010154 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010155 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10156 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10157 return -EINVAL;
10158 }
10159
10160 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10161
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010162 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10163 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010164 {
10165 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10166 {
10167 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010168 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010169 return -EINVAL;
10170 }
10171 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10172 "%s: set channel to [%d] for device mode =%d",
10173 __func__, channel,pAdapter->device_mode);
10174 }
10175 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010176 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010177 )
10178 {
10179 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10180 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10181 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10182
10183 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10184 {
10185 /* Link is up then return cant set channel*/
10186 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010187 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010188 return -EINVAL;
10189 }
10190
10191 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10192 pHddStaCtx->conn_info.operationChannel = channel;
10193 pRoamProfile->ChannelInfo.ChannelList =
10194 &pHddStaCtx->conn_info.operationChannel;
10195 }
10196 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010197 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010198 )
10199 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010200 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10201 {
10202 if(VOS_STATUS_SUCCESS !=
10203 wlan_hdd_validate_operation_channel(pAdapter,channel))
10204 {
10205 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010206 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010207 return -EINVAL;
10208 }
10209 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10210 }
10211 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010212 {
10213 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10214
10215 /* If auto channel selection is configured as enable/ 1 then ignore
10216 channel set by supplicant
10217 */
10218 if ( cfg_param->apAutoChannelSelection )
10219 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010220 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10221 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010222 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010223 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10224 __func__, hdd_device_modetoString(pAdapter->device_mode),
10225 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010226 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010227 else
10228 {
10229 if(VOS_STATUS_SUCCESS !=
10230 wlan_hdd_validate_operation_channel(pAdapter,channel))
10231 {
10232 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010233 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010234 return -EINVAL;
10235 }
10236 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10237 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010238 }
10239 }
10240 else
10241 {
10242 hddLog(VOS_TRACE_LEVEL_FATAL,
10243 "%s: Invalid device mode failed to set valid channel", __func__);
10244 return -EINVAL;
10245 }
10246 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010247 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010248}
10249
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010250static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10251 struct net_device *dev,
10252 struct ieee80211_channel *chan,
10253 enum nl80211_channel_type channel_type
10254 )
10255{
10256 int ret;
10257
10258 vos_ssr_protect(__func__);
10259 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10260 vos_ssr_unprotect(__func__);
10261
10262 return ret;
10263}
10264
Anurag Chouhan83026002016-12-13 22:46:21 +053010265#ifdef DHCP_SERVER_OFFLOAD
10266void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10267 VOS_STATUS status)
10268{
10269 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10270
10271 ENTER();
10272
10273 if (NULL == adapter)
10274 {
10275 hddLog(VOS_TRACE_LEVEL_ERROR,
10276 "%s: adapter is NULL",__func__);
10277 return;
10278 }
10279
10280 adapter->dhcp_status.dhcp_offload_status = status;
10281 vos_event_set(&adapter->dhcp_status.vos_event);
10282 return;
10283}
10284
10285/**
10286 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10287 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010288 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010289 *
10290 * Return: None
10291 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010292VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10293 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010294{
10295 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10296 sir_dhcp_srv_offload_info dhcp_srv_info;
10297 tANI_U8 num_entries = 0;
10298 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10299 tANI_U8 num;
10300 tANI_U32 temp;
10301 VOS_STATUS ret;
10302
10303 ENTER();
10304
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010305 if (!re_init) {
10306 ret = wlan_hdd_validate_context(hdd_ctx);
10307 if (0 != ret)
10308 return VOS_STATUS_E_INVAL;
10309 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010310
10311 /* Prepare the request to send to SME */
10312 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10313 if (NULL == dhcp_srv_info) {
10314 hddLog(VOS_TRACE_LEVEL_ERROR,
10315 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10316 return VOS_STATUS_E_NOMEM;
10317 }
10318
10319 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10320
10321 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10322 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10323 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10324 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10325 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10326 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10327
10328 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10329 srv_ip,
10330 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010331 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010332 if (num_entries != IPADDR_NUM_ENTRIES) {
10333 hddLog(VOS_TRACE_LEVEL_ERROR,
10334 "%s: incorrect IP address (%s) assigned for DHCP server!",
10335 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10336 vos_mem_free(dhcp_srv_info);
10337 return VOS_STATUS_E_FAILURE;
10338 }
10339
10340 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10341 hddLog(VOS_TRACE_LEVEL_ERROR,
10342 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10343 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10344 vos_mem_free(dhcp_srv_info);
10345 return VOS_STATUS_E_FAILURE;
10346 }
10347
10348 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10349 hddLog(VOS_TRACE_LEVEL_ERROR,
10350 "%s: invalid IP address (%s)! The last field must be less than 100!",
10351 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10352 vos_mem_free(dhcp_srv_info);
10353 return VOS_STATUS_E_FAILURE;
10354 }
10355
10356 for (num = 0; num < num_entries; num++) {
10357 temp = srv_ip[num];
10358 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10359 }
10360
10361 if (eHAL_STATUS_SUCCESS !=
10362 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10363 hddLog(VOS_TRACE_LEVEL_ERROR,
10364 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10365 vos_mem_free(dhcp_srv_info);
10366 return VOS_STATUS_E_FAILURE;
10367 }
10368
10369 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10370 "%s: enable DHCP Server offload successfully!", __func__);
10371
10372 vos_mem_free(dhcp_srv_info);
10373 return 0;
10374}
10375#endif /* DHCP_SERVER_OFFLOAD */
10376
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010377/*
10378 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10379 * @wiphy_chan: wiphy channel number
10380 * @rfChannel: channel hw value
10381 * @disable: Disable/enable the flags
10382 *
10383 * Modify wiphy flags and cds state if channel is indoor.
10384 *
10385 * Return: void
10386 */
10387void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
10388 v_U32_t rfChannel, bool disable)
10389{
10390 v_U32_t channelLoop;
10391 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10392
10393 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10394
10395 if (rfChannels[channelLoop].channelNum == rfChannel) {
10396 channelEnum = (eRfChannels)channelLoop;
10397 break;
10398 }
10399 }
10400
10401 if (INVALID_RF_CHANNEL == channelEnum)
10402 return;
10403
10404 if (disable) {
10405 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10406 wiphy_chan->flags |=
10407 IEEE80211_CHAN_DISABLED;
10408 regChannels[channelEnum].enabled =
10409 NV_CHANNEL_DISABLE;
10410 }
10411 } else {
10412 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10413 wiphy_chan->flags &=
10414 ~IEEE80211_CHAN_DISABLED;
10415 /*
10416 * Indoor channels are marked as DFS
10417 * during regulatory processing
10418 */
10419
10420 regChannels[channelEnum].enabled =
10421 NV_CHANNEL_DFS;
10422 }
10423 }
10424
10425}
10426
10427void hdd_update_indoor_channel(hdd_context_t *hdd_ctx,
10428 bool disable)
10429{
10430 int band_num;
10431 int chan_num;
10432 v_U32_t rfChannel;
10433 struct ieee80211_channel *wiphy_chan;
10434 struct wiphy *wiphy;
10435
10436 ENTER();
10437 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10438
10439 wiphy = hdd_ctx->wiphy;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010440 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010441
10442 if (wiphy->bands[band_num] == NULL)
10443 continue;
10444
10445 for (chan_num = 0;
10446 chan_num < wiphy->bands[band_num]->n_channels;
10447 chan_num++) {
10448
10449 wiphy_chan =
10450 &(wiphy->bands[band_num]->channels[chan_num]);
10451 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10452
10453 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
10454 disable);
10455 }
10456 }
10457 EXIT();
10458}
10459
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010460/*
10461 * FUNCTION: wlan_hdd_disconnect
10462 * This function is used to issue a disconnect request to SME
10463 */
10464int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10465{
10466 int status, result = 0;
10467 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10468 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10469 long ret;
10470 eConnectionState prev_conn_state;
10471 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
10472
10473 ENTER();
10474
10475 status = wlan_hdd_validate_context(pHddCtx);
10476 if (0 != status)
10477 {
10478 return status;
10479 }
10480 /* Indicate sme of disconnect so that in progress connection or preauth
10481 * can be aborted
10482 */
10483 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10484 pAdapter->sessionId);
10485 pHddCtx->isAmpAllowed = VOS_TRUE;
10486
10487 /* Need to apply spin lock before decreasing active sessions
10488 * as there can be chance for double decrement if context switch
10489 * Calls hdd_DisConnectHandler.
10490 */
10491
10492 prev_conn_state = pHddStaCtx->conn_info.connState;
10493
10494 spin_lock_bh(&pAdapter->lock_for_active_session);
10495 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10496 {
10497 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10498 }
10499 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10500 spin_unlock_bh(&pAdapter->lock_for_active_session);
10501 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
10502
10503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10504 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10505
10506 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10507
10508 /*
10509 * stop tx queues before deleting STA/BSS context from the firmware.
10510 * tx has to be disabled because the firmware can get busy dropping
10511 * the tx frames after BSS/STA has been deleted and will not send
10512 * back a response resulting in WDI timeout
10513 */
10514 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10515 netif_tx_disable(pAdapter->dev);
10516 netif_carrier_off(pAdapter->dev);
10517
10518 wlan_hdd_check_and_stop_mon(pAdapter, true);
10519
10520 /*issue disconnect*/
10521 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10522 pAdapter->sessionId, reason);
10523 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
10524 prev_conn_state != eConnectionState_Connecting)
10525 {
10526 hddLog(LOG1,
10527 FL("status = %d, already disconnected"), status);
10528 result = 0;
10529 /*
10530 * Wait here instead of returning directly. This will block the
10531 * next connect command and allow processing of the disconnect
10532 * in SME else we might hit some race conditions leading to SME
10533 * and HDD out of sync. As disconnect is already in progress,
10534 * wait here for 1 sec instead of 5 sec.
10535 */
10536 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
10537 goto wait_for_disconnect;
10538 }
10539 /*
10540 * Wait here instead of returning directly, this will block the next
10541 * connect command and allow processing of the scan for ssid and
10542 * the previous connect command in CSR. Else we might hit some
10543 * race conditions leading to SME and HDD out of sync.
10544 */
10545 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10546 {
10547 hddLog(LOG1,
10548 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
10549 }
10550 else if ( 0 != status )
10551 {
10552 hddLog(LOGE,
10553 FL("csrRoamDisconnect failure, returned %d"),
10554 (int)status);
10555 result = -EINVAL;
10556 goto disconnected;
10557 }
10558wait_for_disconnect:
10559 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
10560 msecs_to_jiffies(wait_time));
10561 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
10562 {
10563 hddLog(LOGE,
10564 "%s: Failed to disconnect, timed out", __func__);
10565 result = -ETIMEDOUT;
10566 }
10567disconnected:
10568 hddLog(LOG1,
10569 FL("Set HDD connState to eConnectionState_NotConnected"));
10570 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10571#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
10572 /* Sending disconnect event to userspace for kernel version < 3.11
10573 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
10574 */
10575 hddLog(LOG1, FL("Send disconnected event to userspace"));
10576
10577 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
10578 WLAN_REASON_UNSPECIFIED);
10579#endif
10580
10581 EXIT();
10582 return result;
10583}
10584
10585/*
10586 * hdd_check_and_disconnect_sta_on_invalid_channel() - Disconnect STA if it is
10587 * on indoor channel
10588 * @hdd_ctx: pointer to hdd context
10589 *
10590 * STA should be disconnected before starting the SAP if it is on indoor
10591 * channel.
10592 *
10593 * Return: void
10594 */
10595void hdd_check_and_disconnect_sta_on_invalid_channel(hdd_context_t *hdd_ctx)
10596{
10597
10598 hdd_adapter_t *sta_adapter;
10599 tANI_U8 sta_chan;
10600
10601 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
10602
10603 if (!sta_chan) {
10604 hddLog(LOG1, FL("STA not connected"));
10605 return;
10606 }
10607
10608 hddLog(LOG1, FL("STA connected on chan %hu"), sta_chan);
10609
10610 if (sme_IsChannelValid(hdd_ctx->hHal, sta_chan)) {
10611 hddLog(LOG1, FL("STA connected on chan %hu and it is valid"),
10612 sta_chan);
10613 return;
10614 }
10615
10616 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
10617
10618 if (!sta_adapter) {
10619 hddLog(LOG1, FL("STA adapter doesn't exist"));
10620 return;
10621 }
10622
10623 hddLog(LOG1, FL("chan %hu not valid, issue disconnect"), sta_chan);
10624 /* Issue Disconnect request */
10625 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10626}
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010627
Jeff Johnson295189b2012-06-20 16:38:30 -070010628#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10629static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10630 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010631#else
10632static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10633 struct cfg80211_beacon_data *params,
10634 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010635 enum nl80211_hidden_ssid hidden_ssid,
10636 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010637#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010638{
10639 tsap_Config_t *pConfig;
10640 beacon_data_t *pBeacon = NULL;
10641 struct ieee80211_mgmt *pMgmt_frame;
10642 v_U8_t *pIe=NULL;
10643 v_U16_t capab_info;
10644 eCsrAuthType RSNAuthType;
10645 eCsrEncryptionType RSNEncryptType;
10646 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010647 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010648 tpWLAN_SAPEventCB pSapEventCallback;
10649 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070010650 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010651 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010652 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010653 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070010654 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080010655 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +053010656 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070010657 v_BOOL_t MFPCapable = VOS_FALSE;
10658 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010659 v_BOOL_t sapEnable11AC =
10660 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053010661 u_int16_t prev_rsn_length = 0;
10662
Jeff Johnson295189b2012-06-20 16:38:30 -070010663 ENTER();
10664
Nitesh Shah9b066282017-06-06 18:05:52 +053010665 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010666 iniConfig = pHddCtx->cfg_ini;
10667
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010668 /* Mark the indoor channel (passive) to disable */
10669 if (iniConfig->disable_indoor_channel) {
10670 hdd_update_indoor_channel(pHddCtx, true);
10671
10672 if (!VOS_IS_STATUS_SUCCESS(
10673 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
10674 hdd_update_indoor_channel(pHddCtx, false);
10675 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
10676 FL("Can't start BSS: update channel list failed"));
10677 return eHAL_STATUS_FAILURE;
10678 }
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010679
10680 /* check if STA is on indoor channel */
10681 if (hdd_is_sta_sap_scc_allowed_on_dfs_chan(pHddCtx))
10682 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010683 }
10684
Jeff Johnson295189b2012-06-20 16:38:30 -070010685 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
10686
10687 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
10688
10689 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
10690
10691 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
10692
10693 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
10694
10695 //channel is already set in the set_channel Call back
10696 //pConfig->channel = pCommitConfig->channel;
10697
10698 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010699 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070010700 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
10701
10702 pConfig->dtim_period = pBeacon->dtim_period;
10703
Arif Hussain6d2a3322013-11-17 19:50:10 -080010704 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070010705 pConfig->dtim_period);
10706
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080010707 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070010708 {
10709 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010710 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053010711 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
10712 {
10713 tANI_BOOLEAN restartNeeded;
10714 pConfig->ieee80211d = 1;
10715 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
10716 sme_setRegInfo(hHal, pConfig->countryCode);
10717 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
10718 }
10719 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070010720 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070010721 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070010722 pConfig->ieee80211d = 1;
10723 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
10724 sme_setRegInfo(hHal, pConfig->countryCode);
10725 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070010726 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010727 else
10728 {
10729 pConfig->ieee80211d = 0;
10730 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010731 /*
10732 * If auto channel is configured i.e. channel is 0,
10733 * so skip channel validation.
10734 */
10735 if( AUTO_CHANNEL_SELECT != pConfig->channel )
10736 {
10737 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
10738 {
10739 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010740 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010741 return -EINVAL;
10742 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010743 pConfig->user_config_channel = pConfig->channel;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010744 }
10745 else
10746 {
10747 if(1 != pHddCtx->is_dynamic_channel_range_set)
10748 {
10749 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
10750 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
10751 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
10752 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010753 pHddCtx->is_dynamic_channel_range_set = 0;
10754 pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010755 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010756 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010757 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010758 {
10759 pConfig->ieee80211d = 0;
10760 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010761
10762#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10763 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10764 pConfig->authType = eSAP_OPEN_SYSTEM;
10765 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10766 pConfig->authType = eSAP_SHARED_KEY;
10767 else
10768 pConfig->authType = eSAP_AUTO_SWITCH;
10769#else
10770 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10771 pConfig->authType = eSAP_OPEN_SYSTEM;
10772 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10773 pConfig->authType = eSAP_SHARED_KEY;
10774 else
10775 pConfig->authType = eSAP_AUTO_SWITCH;
10776#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010777
10778 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010779
10780 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070010781 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053010782#ifdef SAP_AUTH_OFFLOAD
10783 /* In case of sap offload, hostapd.conf is configuted with open mode and
10784 * security is configured from ini file. Due to open mode in hostapd.conf
10785 * privacy bit is set to false which will result in not sending,
10786 * data packets as encrypted.
10787 * If enable_sap_auth_offload is enabled in ini and
10788 * sap_auth_offload_sec_type is type of WPA2-PSK,
10789 * driver will set privacy bit to 1.
10790 */
10791 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
10792 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
10793 pConfig->privacy = VOS_TRUE;
10794#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010795
10796 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
10797
10798 /*Set wps station to configured*/
10799 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
10800
10801 if(pIe)
10802 {
10803 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
10804 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010805 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -070010806 return -EINVAL;
10807 }
10808 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
10809 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070010810 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070010811 /* Check 15 bit of WPS IE as it contain information for wps state
10812 * WPS state
10813 */
10814 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
10815 {
10816 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
10817 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
10818 {
10819 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
10820 }
10821 }
10822 }
10823 else
10824 {
10825 pConfig->wps_state = SAP_WPS_DISABLED;
10826 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010827 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070010828
c_hpothufe599e92014-06-16 11:38:55 +053010829 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10830 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10831 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
10832 eCSR_ENCRYPT_TYPE_NONE;
10833
Jeff Johnson295189b2012-06-20 16:38:30 -070010834 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053010835 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010836 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010837 WLAN_EID_RSN);
10838 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010839 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010840 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010841 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10842 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10843 pConfig->RSNWPAReqIELength);
10844 else
10845 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10846 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010847 /* The actual processing may eventually be more extensive than
10848 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070010849 * by the app.
10850 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010851 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010852 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10853 &RSNEncryptType,
10854 &mcRSNEncryptType,
10855 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010856 &MFPCapable,
10857 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010858 pConfig->RSNWPAReqIE[1]+2,
10859 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010860
10861 if( VOS_STATUS_SUCCESS == status )
10862 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010863 /* Now copy over all the security attributes you have
10864 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010865 * */
10866 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10867 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10868 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10869 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010870 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010871 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010872 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10873 }
10874 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010875
Jeff Johnson295189b2012-06-20 16:38:30 -070010876 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10877 pBeacon->tail, pBeacon->tail_len);
10878
10879 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
10880 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010881 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010882 {
10883 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053010884 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070010885 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010886 if (pConfig->RSNWPAReqIELength <=
10887 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
10888 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
10889 pIe[1] + 2);
10890 else
10891 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10892 pConfig->RSNWPAReqIELength);
10893
Jeff Johnson295189b2012-06-20 16:38:30 -070010894 }
10895 else
10896 {
10897 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010898 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10899 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10900 pConfig->RSNWPAReqIELength);
10901 else
10902 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10903 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010904 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010905 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10906 &RSNEncryptType,
10907 &mcRSNEncryptType,
10908 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010909 &MFPCapable,
10910 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010911 pConfig->RSNWPAReqIE[1]+2,
10912 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010913
10914 if( VOS_STATUS_SUCCESS == status )
10915 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010916 /* Now copy over all the security attributes you have
10917 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010918 * */
10919 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10920 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10921 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10922 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010923 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010924 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010925 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10926 }
10927 }
10928 }
10929
Kapil Gupta137ef892016-12-13 19:38:00 +053010930 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070010931 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
10932 return -EINVAL;
10933 }
10934
Jeff Johnson295189b2012-06-20 16:38:30 -070010935 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
10936
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010937#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010938 if (params->ssid != NULL)
10939 {
10940 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
10941 pConfig->SSIDinfo.ssid.length = params->ssid_len;
10942 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10943 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10944 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010945#else
10946 if (ssid != NULL)
10947 {
10948 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
10949 pConfig->SSIDinfo.ssid.length = ssid_len;
10950 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10951 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10952 }
10953#endif
10954
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010955 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070010956 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010957
Jeff Johnson295189b2012-06-20 16:38:30 -070010958 /* default value */
10959 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
10960 pConfig->num_accept_mac = 0;
10961 pConfig->num_deny_mac = 0;
10962
10963 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10964 pBeacon->tail, pBeacon->tail_len);
10965
10966 /* pIe for black list is following form:
10967 type : 1 byte
10968 length : 1 byte
10969 OUI : 4 bytes
10970 acl type : 1 byte
10971 no of mac addr in black list: 1 byte
10972 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010973 */
10974 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010975 {
10976 pConfig->SapMacaddr_acl = pIe[6];
10977 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010978 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010979 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010980 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
10981 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010982 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10983 for (i = 0; i < pConfig->num_deny_mac; i++)
10984 {
10985 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10986 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010987 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010988 }
10989 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10990 pBeacon->tail, pBeacon->tail_len);
10991
10992 /* pIe for white list is following form:
10993 type : 1 byte
10994 length : 1 byte
10995 OUI : 4 bytes
10996 acl type : 1 byte
10997 no of mac addr in white list: 1 byte
10998 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010999 */
11000 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011001 {
11002 pConfig->SapMacaddr_acl = pIe[6];
11003 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011004 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011005 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011006 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
11007 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011008 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11009 for (i = 0; i < pConfig->num_accept_mac; i++)
11010 {
11011 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11012 acl_entry++;
11013 }
11014 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011015
Jeff Johnson295189b2012-06-20 16:38:30 -070011016 wlan_hdd_set_sapHwmode(pHostapdAdapter);
11017
Jeff Johnsone7245742012-09-05 17:12:55 -070011018#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011019 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011020 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
11021 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053011022 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
11023 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011024 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
11025 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011026 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
11027 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070011028 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011029 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070011030 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011031 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011032
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011033 /* If ACS disable and selected channel <= 14
11034 * OR
11035 * ACS enabled and ACS operating band is choosen as 2.4
11036 * AND
11037 * VHT in 2.4G Disabled
11038 * THEN
11039 * Fallback to 11N mode
11040 */
11041 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
11042 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053011043 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011044 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011045 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011046 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
11047 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011048 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
11049 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011050 }
11051#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011052
Jeff Johnson295189b2012-06-20 16:38:30 -070011053 // ht_capab is not what the name conveys,this is used for protection bitmap
11054 pConfig->ht_capab =
11055 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
11056
Kapil Gupta137ef892016-12-13 19:38:00 +053011057 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070011058 {
11059 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
11060 return -EINVAL;
11061 }
11062
11063 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011064 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070011065 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
11066 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011067 pConfig->obssProtEnabled =
11068 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070011069
Chet Lanctot8cecea22014-02-11 19:09:36 -080011070#ifdef WLAN_FEATURE_11W
11071 pConfig->mfpCapable = MFPCapable;
11072 pConfig->mfpRequired = MFPRequired;
11073 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
11074 pConfig->mfpCapable, pConfig->mfpRequired);
11075#endif
11076
Arif Hussain6d2a3322013-11-17 19:50:10 -080011077 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070011078 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011079 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
11080 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
11081 (int)pConfig->channel);
11082 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
11083 pConfig->SapHw_mode, pConfig->privacy,
11084 pConfig->authType);
11085 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
11086 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
11087 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
11088 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070011089
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011090 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070011091 {
11092 //Bss already started. just return.
11093 //TODO Probably it should update some beacon params.
11094 hddLog( LOGE, "Bss Already started...Ignore the request");
11095 EXIT();
11096 return 0;
11097 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011098
Agarwal Ashish51325b52014-06-16 16:50:49 +053011099 if (vos_max_concurrent_connections_reached()) {
11100 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11101 return -EINVAL;
11102 }
11103
Jeff Johnson295189b2012-06-20 16:38:30 -070011104 pConfig->persona = pHostapdAdapter->device_mode;
11105
Peng Xu2446a892014-09-05 17:21:18 +053011106 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
11107 if ( NULL != psmeConfig)
11108 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011109 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053011110 sme_GetConfigParam(hHal, psmeConfig);
11111 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011112#ifdef WLAN_FEATURE_AP_HT40_24G
11113 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11114 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
11115 && pHddCtx->cfg_ini->apHT40_24GEnabled)
11116 {
11117 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
11118 sme_UpdateConfig (hHal, psmeConfig);
11119 }
11120#endif
Peng Xu2446a892014-09-05 17:21:18 +053011121 vos_mem_free(psmeConfig);
11122 }
Peng Xuafc34e32014-09-25 13:23:55 +053011123 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053011124
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011125 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
11126
Jeff Johnson295189b2012-06-20 16:38:30 -070011127 pSapEventCallback = hdd_hostapd_SAPEventCB;
11128 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
11129 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
11130 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011131 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011132 ret = -EINVAL;
11133 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011134 }
11135
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011136 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070011137 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
11138
11139 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011140
Jeff Johnson295189b2012-06-20 16:38:30 -070011141 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011142 {
11143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011144 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070011145 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011146 VOS_ASSERT(0);
11147 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011148
Jeff Johnson295189b2012-06-20 16:38:30 -070011149 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053011150 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
11151 VOS_STATUS_SUCCESS)
11152 {
11153 hddLog(LOGE,FL("Fail to get Softap sessionID"));
11154 VOS_ASSERT(0);
11155 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053011156 /* Initialize WMM configuation */
11157 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011158 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011159
Anurag Chouhan83026002016-12-13 22:46:21 +053011160#ifdef DHCP_SERVER_OFFLOAD
11161 /* set dhcp server offload */
11162 if (iniConfig->enable_dhcp_srv_offload &&
11163 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011164 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053011165 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053011166 if (!VOS_IS_STATUS_SUCCESS(status))
11167 {
11168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11169 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011170 vos_event_reset(&pHostapdState->vosEvent);
11171 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11172 status = vos_wait_single_event(&pHostapdState->vosEvent,
11173 10000);
11174 if (!VOS_IS_STATUS_SUCCESS(status)) {
11175 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011176 ret = -EINVAL;
11177 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011178 }
11179 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011180 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011181 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
11182 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
11183 {
11184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11185 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
11186 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011187 vos_event_reset(&pHostapdState->vosEvent);
11188 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11189 status = vos_wait_single_event(&pHostapdState->vosEvent,
11190 10000);
11191 if (!VOS_IS_STATUS_SUCCESS(status)) {
11192 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011193 ret = -EINVAL;
11194 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011195 }
11196 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011197 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011198#ifdef MDNS_OFFLOAD
11199 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011200 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011201 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
11202 if (VOS_IS_STATUS_SUCCESS(status))
11203 {
11204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11205 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011206 vos_event_reset(&pHostapdState->vosEvent);
11207 if (VOS_STATUS_SUCCESS ==
11208 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11209 status = vos_wait_single_event(&pHostapdState->vosEvent,
11210 10000);
11211 if (!VOS_IS_STATUS_SUCCESS(status)) {
11212 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011213 ret = -EINVAL;
11214 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011215 }
11216 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011217 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011218 status = vos_wait_single_event(&pHostapdAdapter->
11219 mdns_status.vos_event, 2000);
11220 if (!VOS_IS_STATUS_SUCCESS(status) ||
11221 pHostapdAdapter->mdns_status.mdns_enable_status ||
11222 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
11223 pHostapdAdapter->mdns_status.mdns_resp_status)
11224 {
11225 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11226 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
11227 pHostapdAdapter->mdns_status.mdns_enable_status,
11228 pHostapdAdapter->mdns_status.mdns_fqdn_status,
11229 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011230 vos_event_reset(&pHostapdState->vosEvent);
11231 if (VOS_STATUS_SUCCESS ==
11232 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11233 status = vos_wait_single_event(&pHostapdState->vosEvent,
11234 10000);
11235 if (!VOS_IS_STATUS_SUCCESS(status)) {
11236 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011237 ret = -EINVAL;
11238 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011239 }
11240 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011241 }
11242 }
11243#endif /* MDNS_OFFLOAD */
11244 } else {
11245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11246 ("DHCP Disabled ini %d, FW %d"),
11247 iniConfig->enable_dhcp_srv_offload,
11248 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053011249 }
11250#endif /* DHCP_SERVER_OFFLOAD */
11251
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011252#ifdef WLAN_FEATURE_P2P_DEBUG
11253 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
11254 {
11255 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
11256 {
11257 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11258 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011259 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011260 }
11261 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
11262 {
11263 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11264 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011265 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011266 }
11267 }
11268#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053011269 /* Check and restart SAP if it is on Unsafe channel */
11270 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011271
Jeff Johnson295189b2012-06-20 16:38:30 -070011272 pHostapdState->bCommit = TRUE;
11273 EXIT();
11274
11275 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011276error:
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011277 /* Revert the indoor to passive marking if START BSS fails */
11278 if (iniConfig->disable_indoor_channel) {
11279 hdd_update_indoor_channel(pHddCtx, false);
11280 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
11281 }
11282
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011283 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
11284 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011285}
11286
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011287#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011288static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011289 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011290 struct beacon_parameters *params)
11291{
11292 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011293 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011294 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011295
11296 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011297
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011298 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11299 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11300 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011301 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11302 hdd_device_modetoString(pAdapter->device_mode),
11303 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011304
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011305 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11306 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011307 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011308 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011309 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011310 }
11311
Agarwal Ashish51325b52014-06-16 16:50:49 +053011312 if (vos_max_concurrent_connections_reached()) {
11313 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11314 return -EINVAL;
11315 }
11316
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011317 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011318 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011319 )
11320 {
11321 beacon_data_t *old,*new;
11322
11323 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011324
Jeff Johnson295189b2012-06-20 16:38:30 -070011325 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011326 {
11327 hddLog(VOS_TRACE_LEVEL_WARN,
11328 FL("already beacon info added to session(%d)"),
11329 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011330 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011331 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011332
11333 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11334
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011335 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011336 {
11337 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011338 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011339 return -EINVAL;
11340 }
11341
11342 pAdapter->sessionCtx.ap.beacon = new;
11343
11344 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11345 }
11346
11347 EXIT();
11348 return status;
11349}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011350
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011351static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11352 struct net_device *dev,
11353 struct beacon_parameters *params)
11354{
11355 int ret;
11356
11357 vos_ssr_protect(__func__);
11358 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11359 vos_ssr_unprotect(__func__);
11360
11361 return ret;
11362}
11363
11364static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011365 struct net_device *dev,
11366 struct beacon_parameters *params)
11367{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011368 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011369 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11370 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011371 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011372
11373 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011374
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011375 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11376 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11377 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11378 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11379 __func__, hdd_device_modetoString(pAdapter->device_mode),
11380 pAdapter->device_mode);
11381
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011382 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11383 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011384 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011385 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011386 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011387 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011388
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011389 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011390 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011391 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011392 {
11393 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011394
Jeff Johnson295189b2012-06-20 16:38:30 -070011395 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011396
Jeff Johnson295189b2012-06-20 16:38:30 -070011397 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011398 {
11399 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11400 FL("session(%d) old and new heads points to NULL"),
11401 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011402 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011403 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011404
11405 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11406
11407 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011408 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011409 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011410 return -EINVAL;
11411 }
11412
11413 pAdapter->sessionCtx.ap.beacon = new;
11414
11415 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11416 }
11417
11418 EXIT();
11419 return status;
11420}
11421
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011422static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11423 struct net_device *dev,
11424 struct beacon_parameters *params)
11425{
11426 int ret;
11427
11428 vos_ssr_protect(__func__);
11429 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11430 vos_ssr_unprotect(__func__);
11431
11432 return ret;
11433}
11434
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011435#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11436
11437#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011438static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011439 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011440#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011441static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011442 struct net_device *dev)
11443#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011444{
11445 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070011446 hdd_context_t *pHddCtx = NULL;
11447 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011448 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011449 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011450
11451 ENTER();
11452
11453 if (NULL == pAdapter)
11454 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011456 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011457 return -ENODEV;
11458 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011459
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011460 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11461 TRACE_CODE_HDD_CFG80211_STOP_AP,
11462 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011463 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11464 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011465 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011466 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011467 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011468 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011469
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011470 pScanInfo = &pHddCtx->scan_info;
11471
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011472 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11473 __func__, hdd_device_modetoString(pAdapter->device_mode),
11474 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011475
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011476 ret = wlan_hdd_scan_abort(pAdapter);
11477
Girish Gowli4bf7a632014-06-12 13:42:11 +053011478 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011479 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11481 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011482
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011483 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011484 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11486 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011487
Jeff Johnsone7245742012-09-05 17:12:55 -070011488 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011489 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011490 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011491 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011492 }
11493
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011494 /* Delete all associated STAs before stopping AP/P2P GO */
11495 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011496 hdd_hostapd_stop(dev);
11497
Jeff Johnson295189b2012-06-20 16:38:30 -070011498 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011499 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011500 )
11501 {
11502 beacon_data_t *old;
11503
11504 old = pAdapter->sessionCtx.ap.beacon;
11505
11506 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011507 {
11508 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11509 FL("session(%d) beacon data points to NULL"),
11510 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011511 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011512 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011513
Jeff Johnson295189b2012-06-20 16:38:30 -070011514 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011515
11516 mutex_lock(&pHddCtx->sap_lock);
11517 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11518 {
Jeff Johnson4416a782013-03-25 14:17:50 -070011519 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011520 {
11521 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11522
11523 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11524
11525 if (!VOS_IS_STATUS_SUCCESS(status))
11526 {
11527 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011528 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011529 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011530 }
11531 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011532 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011533 /* BSS stopped, clear the active sessions for this device mode */
11534 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011535 }
11536 mutex_unlock(&pHddCtx->sap_lock);
11537
11538 if(status != VOS_STATUS_SUCCESS)
11539 {
11540 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011541 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011542 return -EINVAL;
11543 }
11544
Jeff Johnson4416a782013-03-25 14:17:50 -070011545 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011546 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11547 ==eHAL_STATUS_FAILURE)
11548 {
11549 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011550 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011551 }
11552
Jeff Johnson4416a782013-03-25 14:17:50 -070011553 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011554 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11555 eANI_BOOLEAN_FALSE) )
11556 {
11557 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011558 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011559 }
11560
11561 // Reset WNI_CFG_PROBE_RSP Flags
11562 wlan_hdd_reset_prob_rspies(pAdapter);
11563
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011564 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11565
Jeff Johnson295189b2012-06-20 16:38:30 -070011566 pAdapter->sessionCtx.ap.beacon = NULL;
11567 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011568#ifdef WLAN_FEATURE_P2P_DEBUG
11569 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11570 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11571 {
11572 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11573 "GO got removed");
11574 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11575 }
11576#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011577 }
11578 EXIT();
11579 return status;
11580}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011581
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011582#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11583static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
11584 struct net_device *dev)
11585{
11586 int ret;
11587
11588 vos_ssr_protect(__func__);
11589 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
11590 vos_ssr_unprotect(__func__);
11591
11592 return ret;
11593}
11594#else
11595static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
11596 struct net_device *dev)
11597{
11598 int ret;
11599
11600 vos_ssr_protect(__func__);
11601 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
11602 vos_ssr_unprotect(__func__);
11603
11604 return ret;
11605}
11606#endif
11607
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011608#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
11609
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011610static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011611 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011612 struct cfg80211_ap_settings *params)
11613{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011614 hdd_adapter_t *pAdapter;
11615 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011616 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011617
11618 ENTER();
11619
Girish Gowlib143d7a2015-02-18 19:39:55 +053011620 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011621 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053011623 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011624 return -ENODEV;
11625 }
11626
11627 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11628 if (NULL == pAdapter)
11629 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011630 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011631 "%s: HDD adapter is Null", __func__);
11632 return -ENODEV;
11633 }
11634
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011635 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11636 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
11637 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011638 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
11639 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011641 "%s: HDD adapter magic is invalid", __func__);
11642 return -ENODEV;
11643 }
11644
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011645 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11646
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011647 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011648 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011649 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011650 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011651 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011652 }
11653
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011654 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
11655 __func__, hdd_device_modetoString(pAdapter->device_mode),
11656 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011657
11658 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011659 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011660 )
11661 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011662 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011663
11664 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011665
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011666 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011667 {
11668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
11669 FL("already beacon info added to session(%d)"),
11670 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011671 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011672 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011673
Girish Gowlib143d7a2015-02-18 19:39:55 +053011674#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11675 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11676 &new,
11677 &params->beacon);
11678#else
11679 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11680 &new,
11681 &params->beacon,
11682 params->dtim_period);
11683#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011684
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011685 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011686 {
11687 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011688 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011689 return -EINVAL;
11690 }
11691 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080011692#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070011693 wlan_hdd_cfg80211_set_channel(wiphy, dev,
11694#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
11695 params->channel, params->channel_type);
11696#else
11697 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
11698#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080011699#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011700 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011701 params->ssid_len, params->hidden_ssid,
11702 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011703 }
11704
11705 EXIT();
11706 return status;
11707}
11708
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011709static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
11710 struct net_device *dev,
11711 struct cfg80211_ap_settings *params)
11712{
11713 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011714
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011715 vos_ssr_protect(__func__);
11716 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
11717 vos_ssr_unprotect(__func__);
11718
11719 return ret;
11720}
11721
11722static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011723 struct net_device *dev,
11724 struct cfg80211_beacon_data *params)
11725{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011726 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011727 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011728 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011729
11730 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011731
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011732 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11733 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
11734 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011735 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011736 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011737
11738 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11739 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011740 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011741 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011742 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011743 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011744
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011745 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011746 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011747 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011748 {
11749 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011750
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011751 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011752
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011753 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011754 {
11755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11756 FL("session(%d) beacon data points to NULL"),
11757 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011758 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011759 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011760
11761 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
11762
11763 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011764 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011765 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011766 return -EINVAL;
11767 }
11768
11769 pAdapter->sessionCtx.ap.beacon = new;
11770
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011771 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
11772 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011773 }
11774
11775 EXIT();
11776 return status;
11777}
11778
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011779static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
11780 struct net_device *dev,
11781 struct cfg80211_beacon_data *params)
11782{
11783 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011784
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011785 vos_ssr_protect(__func__);
11786 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
11787 vos_ssr_unprotect(__func__);
11788
11789 return ret;
11790}
11791
11792#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011793
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011794static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011795 struct net_device *dev,
11796 struct bss_parameters *params)
11797{
11798 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011799 hdd_context_t *pHddCtx;
11800 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011801
11802 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011803
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011804 if (NULL == pAdapter)
11805 {
11806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11807 "%s: HDD adapter is Null", __func__);
11808 return -ENODEV;
11809 }
11810 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011811 ret = wlan_hdd_validate_context(pHddCtx);
11812 if (0 != ret)
11813 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011814 return ret;
11815 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011816 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11817 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
11818 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011819 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11820 __func__, hdd_device_modetoString(pAdapter->device_mode),
11821 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011822
11823 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011824 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011825 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011826 {
11827 /* ap_isolate == -1 means that in change bss, upper layer doesn't
11828 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011829 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070011830 {
11831 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011832 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011833 }
11834
11835 EXIT();
11836 return 0;
11837}
11838
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011839static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
11840 struct net_device *dev,
11841 struct bss_parameters *params)
11842{
11843 int ret;
11844
11845 vos_ssr_protect(__func__);
11846 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
11847 vos_ssr_unprotect(__func__);
11848
11849 return ret;
11850}
Kiet Lam10841362013-11-01 11:36:50 +053011851/* FUNCTION: wlan_hdd_change_country_code_cd
11852* to wait for contry code completion
11853*/
11854void* wlan_hdd_change_country_code_cb(void *pAdapter)
11855{
11856 hdd_adapter_t *call_back_pAdapter = pAdapter;
11857 complete(&call_back_pAdapter->change_country_code);
11858 return NULL;
11859}
11860
Jeff Johnson295189b2012-06-20 16:38:30 -070011861/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011862 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070011863 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
11864 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011865int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011866 struct net_device *ndev,
11867 enum nl80211_iftype type,
11868 u32 *flags,
11869 struct vif_params *params
11870 )
11871{
11872 struct wireless_dev *wdev;
11873 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011874 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070011875 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011876 tCsrRoamProfile *pRoamProfile = NULL;
11877 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011878 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011879 eMib_dot11DesiredBssType connectedBssType;
11880 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011881 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011882
11883 ENTER();
11884
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011885 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011886 {
11887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11888 "%s: Adapter context is null", __func__);
11889 return VOS_STATUS_E_FAILURE;
11890 }
11891
11892 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11893 if (!pHddCtx)
11894 {
11895 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11896 "%s: HDD context is null", __func__);
11897 return VOS_STATUS_E_FAILURE;
11898 }
11899
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011900 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11901 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
11902 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011903 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011904 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011905 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011906 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011907 }
11908
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011909 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11910 __func__, hdd_device_modetoString(pAdapter->device_mode),
11911 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011912
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053011913 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
11914 hddLog(VOS_TRACE_LEVEL_FATAL,
11915 "%s: STA + MON is in progress, cannot change interface",
11916 __func__);
11917 }
11918
Agarwal Ashish51325b52014-06-16 16:50:49 +053011919 if (vos_max_concurrent_connections_reached()) {
11920 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11921 return -EINVAL;
11922 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011923 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011924 wdev = ndev->ieee80211_ptr;
11925
11926#ifdef WLAN_BTAMP_FEATURE
11927 if((NL80211_IFTYPE_P2P_CLIENT == type)||
11928 (NL80211_IFTYPE_ADHOC == type)||
11929 (NL80211_IFTYPE_AP == type)||
11930 (NL80211_IFTYPE_P2P_GO == type))
11931 {
11932 pHddCtx->isAmpAllowed = VOS_FALSE;
11933 // stop AMP traffic
11934 status = WLANBAP_StopAmp();
11935 if(VOS_STATUS_SUCCESS != status )
11936 {
11937 pHddCtx->isAmpAllowed = VOS_TRUE;
11938 hddLog(VOS_TRACE_LEVEL_FATAL,
11939 "%s: Failed to stop AMP", __func__);
11940 return -EINVAL;
11941 }
11942 }
11943#endif //WLAN_BTAMP_FEATURE
11944 /* Reset the current device mode bit mask*/
11945 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
11946
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053011947 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
11948 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
11949 (type == NL80211_IFTYPE_P2P_GO)))
11950 {
11951 /* Notify Mode change in case of concurrency.
11952 * Below function invokes TDLS teardown Functionality Since TDLS is
11953 * not Supported in case of concurrency i.e Once P2P session
11954 * is detected disable offchannel and teardown TDLS links
11955 */
11956 hddLog(LOG1,
11957 FL("Device mode = %d Interface type = %d"),
11958 pAdapter->device_mode, type);
11959 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
11960 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053011961
Jeff Johnson295189b2012-06-20 16:38:30 -070011962 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011963 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070011964 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011965 )
11966 {
11967 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011968 if (!pWextState)
11969 {
11970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11971 "%s: pWextState is null", __func__);
11972 return VOS_STATUS_E_FAILURE;
11973 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011974 pRoamProfile = &pWextState->roamProfile;
11975 LastBSSType = pRoamProfile->BSSType;
11976
11977 switch (type)
11978 {
11979 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011980 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011981 hddLog(VOS_TRACE_LEVEL_INFO,
11982 "%s: setting interface Type to INFRASTRUCTURE", __func__);
11983 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011984#ifdef WLAN_FEATURE_11AC
11985 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
11986 {
11987 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
11988 }
11989#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011990 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070011991 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011992 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011993 //Check for sub-string p2p to confirm its a p2p interface
11994 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011995 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053011996#ifdef FEATURE_WLAN_TDLS
11997 mutex_lock(&pHddCtx->tdls_lock);
11998 wlan_hdd_tdls_exit(pAdapter, TRUE);
11999 mutex_unlock(&pHddCtx->tdls_lock);
12000#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012001 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12002 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12003 }
12004 else
12005 {
12006 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012007 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012008 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012009 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053012010
Jeff Johnson295189b2012-06-20 16:38:30 -070012011 case NL80211_IFTYPE_ADHOC:
12012 hddLog(VOS_TRACE_LEVEL_INFO,
12013 "%s: setting interface Type to ADHOC", __func__);
12014 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
12015 pRoamProfile->phyMode =
12016 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070012017 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012018 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053012019 hdd_set_ibss_ops( pAdapter );
12020 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053012021
12022 status = hdd_sta_id_hash_attach(pAdapter);
12023 if (VOS_STATUS_SUCCESS != status) {
12024 hddLog(VOS_TRACE_LEVEL_ERROR,
12025 FL("Failed to initialize hash for IBSS"));
12026 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012027 break;
12028
12029 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012030 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012031 {
12032 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12033 "%s: setting interface Type to %s", __func__,
12034 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
12035
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012036 //Cancel any remain on channel for GO mode
12037 if (NL80211_IFTYPE_P2P_GO == type)
12038 {
12039 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
12040 }
Mohit Khanna0f232092012-09-11 14:46:08 -070012041 if (NL80211_IFTYPE_AP == type)
12042 {
12043 /* As Loading WLAN Driver one interface being created for p2p device
12044 * address. This will take one HW STA and the max number of clients
12045 * that can connect to softAP will be reduced by one. so while changing
12046 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
12047 * interface as it is not required in SoftAP mode.
12048 */
12049
12050 // Get P2P Adapter
12051 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
12052
12053 if (pP2pAdapter)
12054 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053012055 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053012056 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070012057 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12058 }
12059 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053012060 //Disable IMPS & BMPS for SAP/GO
12061 if(VOS_STATUS_E_FAILURE ==
12062 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
12063 {
12064 //Fail to Exit BMPS
12065 VOS_ASSERT(0);
12066 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053012067
12068 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
12069
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012070#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070012071
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012072 /* A Mutex Lock is introduced while changing the mode to
12073 * protect the concurrent access for the Adapters by TDLS
12074 * module.
12075 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012076 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012077#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012078 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053012079 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012080 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070012081 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12082 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012083#ifdef FEATURE_WLAN_TDLS
12084 mutex_unlock(&pHddCtx->tdls_lock);
12085#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012086 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
12087 (pConfig->apRandomBssidEnabled))
12088 {
12089 /* To meet Android requirements create a randomized
12090 MAC address of the form 02:1A:11:Fx:xx:xx */
12091 get_random_bytes(&ndev->dev_addr[3], 3);
12092 ndev->dev_addr[0] = 0x02;
12093 ndev->dev_addr[1] = 0x1A;
12094 ndev->dev_addr[2] = 0x11;
12095 ndev->dev_addr[3] |= 0xF0;
12096 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
12097 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080012098 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
12099 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012100 }
12101
Jeff Johnson295189b2012-06-20 16:38:30 -070012102 hdd_set_ap_ops( pAdapter->dev );
12103
Kiet Lam10841362013-11-01 11:36:50 +053012104 /* This is for only SAP mode where users can
12105 * control country through ini.
12106 * P2P GO follows station country code
12107 * acquired during the STA scanning. */
12108 if((NL80211_IFTYPE_AP == type) &&
12109 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
12110 {
12111 int status = 0;
12112 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
12113 "%s: setting country code from INI ", __func__);
12114 init_completion(&pAdapter->change_country_code);
12115 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
12116 (void *)(tSmeChangeCountryCallback)
12117 wlan_hdd_change_country_code_cb,
12118 pConfig->apCntryCode, pAdapter,
12119 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012120 eSIR_FALSE,
12121 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053012122 if (eHAL_STATUS_SUCCESS == status)
12123 {
12124 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012125 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053012126 &pAdapter->change_country_code,
12127 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012128 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053012129 {
12130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012131 FL("SME Timed out while setting country code %ld"),
12132 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080012133
12134 if (pHddCtx->isLogpInProgress)
12135 {
12136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12137 "%s: LOGP in Progress. Ignore!!!", __func__);
12138 return -EAGAIN;
12139 }
Kiet Lam10841362013-11-01 11:36:50 +053012140 }
12141 }
12142 else
12143 {
12144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012145 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053012146 return -EINVAL;
12147 }
12148 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053012149 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070012150 if(status != VOS_STATUS_SUCCESS)
12151 {
12152 hddLog(VOS_TRACE_LEVEL_FATAL,
12153 "%s: Error initializing the ap mode", __func__);
12154 return -EINVAL;
12155 }
12156 hdd_set_conparam(1);
12157
Nirav Shah7e3c8132015-06-22 23:51:42 +053012158 status = hdd_sta_id_hash_attach(pAdapter);
12159 if (VOS_STATUS_SUCCESS != status)
12160 {
12161 hddLog(VOS_TRACE_LEVEL_ERROR,
12162 FL("Failed to initialize hash for AP"));
12163 return -EINVAL;
12164 }
12165
Jeff Johnson295189b2012-06-20 16:38:30 -070012166 /*interface type changed update in wiphy structure*/
12167 if(wdev)
12168 {
12169 wdev->iftype = type;
12170 pHddCtx->change_iface = type;
12171 }
12172 else
12173 {
12174 hddLog(VOS_TRACE_LEVEL_ERROR,
12175 "%s: ERROR !!!! Wireless dev is NULL", __func__);
12176 return -EINVAL;
12177 }
12178 goto done;
12179 }
12180
12181 default:
12182 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12183 __func__);
12184 return -EOPNOTSUPP;
12185 }
12186 }
12187 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012188 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070012189 )
12190 {
12191 switch(type)
12192 {
12193 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012194 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012195 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053012196
12197 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012198#ifdef FEATURE_WLAN_TDLS
12199
12200 /* A Mutex Lock is introduced while changing the mode to
12201 * protect the concurrent access for the Adapters by TDLS
12202 * module.
12203 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012204 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012205#endif
c_hpothu002231a2015-02-05 14:58:51 +053012206 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012207 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012208 //Check for sub-string p2p to confirm its a p2p interface
12209 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012210 {
12211 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12212 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12213 }
12214 else
12215 {
12216 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012217 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012218 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053012219
12220 /* set con_mode to STA only when no SAP concurrency mode */
12221 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
12222 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012223 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012224 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
12225 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012226#ifdef FEATURE_WLAN_TDLS
12227 mutex_unlock(&pHddCtx->tdls_lock);
12228#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053012229 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070012230 if( VOS_STATUS_SUCCESS != status )
12231 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070012232 /* In case of JB, for P2P-GO, only change interface will be called,
12233 * This is the right place to enable back bmps_imps()
12234 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012235 if (pHddCtx->hdd_wlan_suspended)
12236 {
12237 hdd_set_pwrparams(pHddCtx);
12238 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012239 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012240 goto done;
12241 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012242 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012243 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012244 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12245 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012246 goto done;
12247 default:
12248 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12249 __func__);
12250 return -EOPNOTSUPP;
12251
12252 }
12253
12254 }
12255 else
12256 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012257 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
12258 __func__, hdd_device_modetoString(pAdapter->device_mode),
12259 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012260 return -EOPNOTSUPP;
12261 }
12262
12263
12264 if(pRoamProfile)
12265 {
12266 if ( LastBSSType != pRoamProfile->BSSType )
12267 {
12268 /*interface type changed update in wiphy structure*/
12269 wdev->iftype = type;
12270
12271 /*the BSS mode changed, We need to issue disconnect
12272 if connected or in IBSS disconnect state*/
12273 if ( hdd_connGetConnectedBssType(
12274 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
12275 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
12276 {
12277 /*need to issue a disconnect to CSR.*/
12278 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12279 if( eHAL_STATUS_SUCCESS ==
12280 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12281 pAdapter->sessionId,
12282 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12283 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012284 ret = wait_for_completion_interruptible_timeout(
12285 &pAdapter->disconnect_comp_var,
12286 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12287 if (ret <= 0)
12288 {
12289 hddLog(VOS_TRACE_LEVEL_ERROR,
12290 FL("wait on disconnect_comp_var failed %ld"), ret);
12291 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012292 }
12293 }
12294 }
12295 }
12296
12297done:
12298 /*set bitmask based on updated value*/
12299 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012300
12301 /* Only STA mode support TM now
12302 * all other mode, TM feature should be disabled */
12303 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12304 (~VOS_STA & pHddCtx->concurrency_mode) )
12305 {
12306 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12307 }
12308
Jeff Johnson295189b2012-06-20 16:38:30 -070012309#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012310 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012311 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012312 {
12313 //we are ok to do AMP
12314 pHddCtx->isAmpAllowed = VOS_TRUE;
12315 }
12316#endif //WLAN_BTAMP_FEATURE
12317 EXIT();
12318 return 0;
12319}
12320
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012321/*
12322 * FUNCTION: wlan_hdd_cfg80211_change_iface
12323 * wrapper function to protect the actual implementation from SSR.
12324 */
12325int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12326 struct net_device *ndev,
12327 enum nl80211_iftype type,
12328 u32 *flags,
12329 struct vif_params *params
12330 )
12331{
12332 int ret;
12333
12334 vos_ssr_protect(__func__);
12335 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12336 vos_ssr_unprotect(__func__);
12337
12338 return ret;
12339}
12340
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012341#ifdef FEATURE_WLAN_TDLS
12342static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012343 struct net_device *dev,
12344#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12345 const u8 *mac,
12346#else
12347 u8 *mac,
12348#endif
12349 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012350{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012351 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012352 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012353 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012354 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012355 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012356 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012357
12358 ENTER();
12359
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012360 if (!dev) {
12361 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12362 return -EINVAL;
12363 }
12364
12365 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12366 if (!pAdapter) {
12367 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12368 return -EINVAL;
12369 }
12370
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012371 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012372 {
12373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12374 "Invalid arguments");
12375 return -EINVAL;
12376 }
Hoonki Lee27511902013-03-14 18:19:06 -070012377
12378 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12379 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12380 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012381 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012382 "%s: TDLS mode is disabled OR not enabled in FW."
12383 MAC_ADDRESS_STR " Request declined.",
12384 __func__, MAC_ADDR_ARRAY(mac));
12385 return -ENOTSUPP;
12386 }
12387
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012388 if (pHddCtx->isLogpInProgress)
12389 {
12390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12391 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012392 wlan_hdd_tdls_set_link_status(pAdapter,
12393 mac,
12394 eTDLS_LINK_IDLE,
12395 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012396 return -EBUSY;
12397 }
12398
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012399 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012400 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012401
12402 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012403 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012404 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12405 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012406 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012407 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012408 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012409
12410 /* in add station, we accept existing valid staId if there is */
12411 if ((0 == update) &&
12412 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12413 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012414 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012416 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012417 " link_status %d. staId %d. add station ignored.",
12418 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012419 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012420 return 0;
12421 }
12422 /* in change station, we accept only when staId is valid */
12423 if ((1 == update) &&
12424 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12425 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12426 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012427 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012429 "%s: " MAC_ADDRESS_STR
12430 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012431 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12432 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12433 mutex_unlock(&pHddCtx->tdls_lock);
12434 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012435 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012436 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012437
12438 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012439 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012440 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12442 "%s: " MAC_ADDRESS_STR
12443 " TDLS setup is ongoing. Request declined.",
12444 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012445 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012446 }
12447
12448 /* first to check if we reached to maximum supported TDLS peer.
12449 TODO: for now, return -EPERM looks working fine,
12450 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012451 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12452 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012453 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012454 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12455 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012456 " TDLS Max peer already connected. Request declined."
12457 " Num of peers (%d), Max allowed (%d).",
12458 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12459 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012460 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012461 }
12462 else
12463 {
12464 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012465 mutex_lock(&pHddCtx->tdls_lock);
12466 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012467 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012468 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012469 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12471 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12472 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012473 return -EPERM;
12474 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012475 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012476 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012477 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012478 wlan_hdd_tdls_set_link_status(pAdapter,
12479 mac,
12480 eTDLS_LINK_CONNECTING,
12481 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012482
Jeff Johnsond75fe012013-04-06 10:53:06 -070012483 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012484 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012485 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012487 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012488 if(StaParams->htcap_present)
12489 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012491 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012492 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012493 "ht_capa->extended_capabilities: %0x",
12494 StaParams->HTCap.extendedHtCapInfo);
12495 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012497 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012498 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012499 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012500 if(StaParams->vhtcap_present)
12501 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012503 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12504 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12505 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12506 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012507 {
12508 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012510 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012512 "[%d]: %x ", i, StaParams->supported_rates[i]);
12513 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012514 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012515 else if ((1 == update) && (NULL == StaParams))
12516 {
12517 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12518 "%s : update is true, but staParams is NULL. Error!", __func__);
12519 return -EPERM;
12520 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012521
12522 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12523
12524 if (!update)
12525 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012526 /*Before adding sta make sure that device exited from BMPS*/
12527 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12528 {
12529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12530 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12531 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12532 if (status != VOS_STATUS_SUCCESS) {
12533 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12534 }
12535 }
12536
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012537 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012538 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012539 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012540 hddLog(VOS_TRACE_LEVEL_ERROR,
12541 FL("Failed to add TDLS peer STA. Enable Bmps"));
12542 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012543 return -EPERM;
12544 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012545 }
12546 else
12547 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012548 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012549 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012550 if (ret != eHAL_STATUS_SUCCESS) {
12551 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12552 return -EPERM;
12553 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012554 }
12555
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012556 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012557 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12558
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012559 mutex_lock(&pHddCtx->tdls_lock);
12560 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12561
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012562 if ((pTdlsPeer != NULL) &&
12563 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012564 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012565 hddLog(VOS_TRACE_LEVEL_ERROR,
12566 FL("peer link status %u"), pTdlsPeer->link_status);
12567 mutex_unlock(&pHddCtx->tdls_lock);
12568 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012569 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012570 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012571
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012572 if (ret <= 0)
12573 {
12574 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12575 "%s: timeout waiting for tdls add station indication %ld",
12576 __func__, ret);
12577 goto error;
12578 }
12579
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012580 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12581 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012583 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012584 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012585 }
12586
12587 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012588
12589error:
Atul Mittal115287b2014-07-08 13:26:33 +053012590 wlan_hdd_tdls_set_link_status(pAdapter,
12591 mac,
12592 eTDLS_LINK_IDLE,
12593 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012594 return -EPERM;
12595
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012596}
12597#endif
12598
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012599static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012600 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012601#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12602 const u8 *mac,
12603#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012604 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012605#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012606 struct station_parameters *params)
12607{
12608 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012609 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012610 hdd_context_t *pHddCtx;
12611 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012612 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012613 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012614#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012615 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012616 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012617 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012618 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012619#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012620
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012621 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012622
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012623 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012624 if ((NULL == pAdapter))
12625 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012627 "invalid adapter ");
12628 return -EINVAL;
12629 }
12630
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012631 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12632 TRACE_CODE_HDD_CHANGE_STATION,
12633 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053012634 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012635
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012636 ret = wlan_hdd_validate_context(pHddCtx);
12637 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053012638 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012639 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012640 }
12641
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012642 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12643
12644 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012645 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12647 "invalid HDD station context");
12648 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012649 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012650 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
12651
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012652 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
12653 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070012654 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012655 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070012656 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012657 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070012658 WLANTL_STA_AUTHENTICATED);
12659
Gopichand Nakkala29149562013-05-10 21:43:41 +053012660 if (status != VOS_STATUS_SUCCESS)
12661 {
12662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12663 "%s: Not able to change TL state to AUTHENTICATED", __func__);
12664 return -EINVAL;
12665 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012666 }
12667 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070012668 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
12669 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012670#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012671 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12672 StaParams.capability = params->capability;
12673 StaParams.uapsd_queues = params->uapsd_queues;
12674 StaParams.max_sp = params->max_sp;
12675
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012676 /* Convert (first channel , number of channels) tuple to
12677 * the total list of channels. This goes with the assumption
12678 * that if the first channel is < 14, then the next channels
12679 * are an incremental of 1 else an incremental of 4 till the number
12680 * of channels.
12681 */
12682 if (0 != params->supported_channels_len) {
12683 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
12684 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
12685 {
12686 int wifi_chan_index;
12687 StaParams.supported_channels[j] = params->supported_channels[i];
12688 wifi_chan_index =
12689 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
12690 no_of_channels = params->supported_channels[i+1];
12691 for(k=1; k <= no_of_channels; k++)
12692 {
12693 StaParams.supported_channels[j+1] =
12694 StaParams.supported_channels[j] + wifi_chan_index;
12695 j+=1;
12696 }
12697 }
12698 StaParams.supported_channels_len = j;
12699 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053012700 if (params->supported_oper_classes_len >
12701 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
12702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12703 "received oper classes:%d, resetting it to max supported %d",
12704 params->supported_oper_classes_len,
12705 SIR_MAC_MAX_SUPP_OPER_CLASSES);
12706 params->supported_oper_classes_len =
12707 SIR_MAC_MAX_SUPP_OPER_CLASSES;
12708 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012709 vos_mem_copy(StaParams.supported_oper_classes,
12710 params->supported_oper_classes,
12711 params->supported_oper_classes_len);
12712 StaParams.supported_oper_classes_len =
12713 params->supported_oper_classes_len;
12714
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012715 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
12716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12717 "received extn capabilities:%d, resetting it to max supported",
12718 params->ext_capab_len);
12719 params->ext_capab_len = sizeof(StaParams.extn_capability);
12720 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012721 if (0 != params->ext_capab_len)
12722 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012723 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012724
12725 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012726 {
12727 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012728 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012729 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012730
12731 StaParams.supported_rates_len = params->supported_rates_len;
12732
12733 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
12734 * The supported_rates array , for all the structures propogating till Add Sta
12735 * to the firmware has to be modified , if the supplicant (ieee80211) is
12736 * modified to send more rates.
12737 */
12738
12739 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
12740 */
12741 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
12742 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
12743
12744 if (0 != StaParams.supported_rates_len) {
12745 int i = 0;
12746 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
12747 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012749 "Supported Rates with Length %d", StaParams.supported_rates_len);
12750 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012752 "[%d]: %0x", i, StaParams.supported_rates[i]);
12753 }
12754
12755 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012756 {
12757 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012758 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012759 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012760
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012761 if (0 != params->ext_capab_len ) {
12762 /*Define A Macro : TODO Sunil*/
12763 if ((1<<4) & StaParams.extn_capability[3]) {
12764 isBufSta = 1;
12765 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012766 /* TDLS Channel Switching Support */
12767 if ((1<<6) & StaParams.extn_capability[3]) {
12768 isOffChannelSupported = 1;
12769 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012770 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012771
12772 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053012773 (params->ht_capa || params->vht_capa ||
12774 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012775 /* TDLS Peer is WME/QoS capable */
12776 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012777
12778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12779 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
12780 __func__, isQosWmmSta, StaParams.htcap_present);
12781
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012782 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
12783 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012784 isOffChannelSupported,
12785 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012786
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012787 if (VOS_STATUS_SUCCESS != status) {
12788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12789 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
12790 return -EINVAL;
12791 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012792 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
12793
12794 if (VOS_STATUS_SUCCESS != status) {
12795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12796 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
12797 return -EINVAL;
12798 }
12799 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012800#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053012801 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012802 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012803 return status;
12804}
12805
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012806#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
12807static int wlan_hdd_change_station(struct wiphy *wiphy,
12808 struct net_device *dev,
12809 const u8 *mac,
12810 struct station_parameters *params)
12811#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012812static int wlan_hdd_change_station(struct wiphy *wiphy,
12813 struct net_device *dev,
12814 u8 *mac,
12815 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012816#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012817{
12818 int ret;
12819
12820 vos_ssr_protect(__func__);
12821 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
12822 vos_ssr_unprotect(__func__);
12823
12824 return ret;
12825}
12826
Jeff Johnson295189b2012-06-20 16:38:30 -070012827/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012828 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012829 * This function is used to initialize the key information
12830 */
12831#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012832static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012833 struct net_device *ndev,
12834 u8 key_index, bool pairwise,
12835 const u8 *mac_addr,
12836 struct key_params *params
12837 )
12838#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012839static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012840 struct net_device *ndev,
12841 u8 key_index, const u8 *mac_addr,
12842 struct key_params *params
12843 )
12844#endif
12845{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012846 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012847 tCsrRoamSetKey setKey;
12848 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012849 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012850 v_U32_t roamId= 0xFF;
12851 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012852 hdd_hostapd_state_t *pHostapdState;
12853 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012854 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012855 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012856 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012857 v_MACADDR_t *peerMacAddr;
12858 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012859 uint8_t staid = HDD_MAX_STA_COUNT;
12860 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012861
12862 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012863
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012864 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12865 TRACE_CODE_HDD_CFG80211_ADD_KEY,
12866 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012867 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12868 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012869 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012870 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012871 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012872 }
12873
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012874 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12875 __func__, hdd_device_modetoString(pAdapter->device_mode),
12876 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012877
12878 if (CSR_MAX_NUM_KEY <= key_index)
12879 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012880 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012881 key_index);
12882
12883 return -EINVAL;
12884 }
12885
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012886 if (CSR_MAX_KEY_LEN < params->key_len)
12887 {
12888 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
12889 params->key_len);
12890
12891 return -EINVAL;
12892 }
12893
Jingxiang Gec438aea2017-10-26 16:44:00 +080012894 if (CSR_MAX_RSC_LEN < params->seq_len)
12895 {
12896 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
12897 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053012898
12899 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080012900 }
12901
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012902 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080012903 "%s: called with key index = %d & key length %d & seq length %d",
12904 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012905
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012906 peerMacAddr = (v_MACADDR_t *)mac_addr;
12907
Jeff Johnson295189b2012-06-20 16:38:30 -070012908 /*extract key idx, key len and key*/
12909 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12910 setKey.keyId = key_index;
12911 setKey.keyLength = params->key_len;
12912 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080012913 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012914
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012915 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012916 {
12917 case WLAN_CIPHER_SUITE_WEP40:
12918 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12919 break;
12920
12921 case WLAN_CIPHER_SUITE_WEP104:
12922 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
12923 break;
12924
12925 case WLAN_CIPHER_SUITE_TKIP:
12926 {
12927 u8 *pKey = &setKey.Key[0];
12928 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
12929
12930 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
12931
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012932 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070012933
12934 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012935 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012936 |--------------|----------|----------|
12937 <---16bytes---><--8bytes--><--8bytes-->
12938
12939 */
12940 /*Sme expects the 32 bytes key to be in the below order
12941
12942 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012943 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012944 |--------------|----------|----------|
12945 <---16bytes---><--8bytes--><--8bytes-->
12946 */
12947 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012948 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070012949
12950 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012951 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012952
12953 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012954 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012955
12956
12957 break;
12958 }
12959
12960 case WLAN_CIPHER_SUITE_CCMP:
12961 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
12962 break;
12963
12964#ifdef FEATURE_WLAN_WAPI
12965 case WLAN_CIPHER_SUITE_SMS4:
12966 {
12967 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12968 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
12969 params->key, params->key_len);
12970 return 0;
12971 }
12972#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012973
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012974#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012975 case WLAN_CIPHER_SUITE_KRK:
12976 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
12977 break;
12978#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012979
12980#ifdef WLAN_FEATURE_11W
12981 case WLAN_CIPHER_SUITE_AES_CMAC:
12982 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070012983 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070012984#endif
12985
Jeff Johnson295189b2012-06-20 16:38:30 -070012986 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012987 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012988 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012989 status = -EOPNOTSUPP;
12990 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012991 }
12992
12993 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
12994 __func__, setKey.encType);
12995
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012996 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070012997#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12998 (!pairwise)
12999#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013000 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013001#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013002 )
13003 {
13004 /* set group key*/
13005 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13006 "%s- %d: setting Broadcast key",
13007 __func__, __LINE__);
13008 setKey.keyDirection = eSIR_RX_ONLY;
13009 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13010 }
13011 else
13012 {
13013 /* set pairwise key*/
13014 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13015 "%s- %d: setting pairwise key",
13016 __func__, __LINE__);
13017 setKey.keyDirection = eSIR_TX_RX;
13018 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013019 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013020 }
13021 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
13022 {
13023 setKey.keyDirection = eSIR_TX_RX;
13024 /*Set the group key*/
13025 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13026 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070013027
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013028 if ( 0 != status )
13029 {
13030 hddLog(VOS_TRACE_LEVEL_ERROR,
13031 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013032 status = -EINVAL;
13033 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013034 }
13035 /*Save the keys here and call sme_RoamSetKey for setting
13036 the PTK after peer joins the IBSS network*/
13037 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
13038 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013039 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013040 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053013041 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
13042 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
13043 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013044 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013045 if( pHostapdState->bssState == BSS_START )
13046 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013047 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13048 vos_status = wlan_hdd_check_ula_done(pAdapter);
13049
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013050 if (peerMacAddr && (pairwise_set_key == true))
13051 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013052
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013053 if ( vos_status != VOS_STATUS_SUCCESS )
13054 {
13055 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13056 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13057 __LINE__, vos_status );
13058
13059 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13060
13061 status = -EINVAL;
13062 goto end;
13063 }
13064
Jeff Johnson295189b2012-06-20 16:38:30 -070013065 status = WLANSAP_SetKeySta( pVosContext, &setKey);
13066
13067 if ( status != eHAL_STATUS_SUCCESS )
13068 {
13069 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13070 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13071 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013072 status = -EINVAL;
13073 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013074 }
13075 }
13076
13077 /* Saving WEP keys */
13078 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
13079 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
13080 {
13081 //Save the wep key in ap context. Issue setkey after the BSS is started.
13082 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13083 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
13084 }
13085 else
13086 {
13087 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013088 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013089 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
13090 }
13091 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013092 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
13093 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013094 {
13095 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13096 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13097
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013098#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13099 if (!pairwise)
13100#else
13101 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
13102#endif
13103 {
13104 /* set group key*/
13105 if (pHddStaCtx->roam_info.deferKeyComplete)
13106 {
13107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13108 "%s- %d: Perform Set key Complete",
13109 __func__, __LINE__);
13110 hdd_PerformRoamSetKeyComplete(pAdapter);
13111 }
13112 }
13113
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013114 if (pairwise_set_key == true)
13115 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013116
Jeff Johnson295189b2012-06-20 16:38:30 -070013117 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
13118
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080013119 pWextState->roamProfile.Keys.defaultIndex = key_index;
13120
13121
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013122 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013123 params->key, params->key_len);
13124
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013125
Jeff Johnson295189b2012-06-20 16:38:30 -070013126 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13127
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013128 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013129 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013130 __func__, setKey.peerMac[0], setKey.peerMac[1],
13131 setKey.peerMac[2], setKey.peerMac[3],
13132 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013133 setKey.keyDirection);
13134
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013135 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053013136
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013137 if ( vos_status != VOS_STATUS_SUCCESS )
13138 {
13139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013140 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13141 __LINE__, vos_status );
13142
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013143 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013144
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013145 status = -EINVAL;
13146 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013147
13148 }
13149
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013150#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013151 /* The supplicant may attempt to set the PTK once pre-authentication
13152 is done. Save the key in the UMAC and include it in the ADD BSS
13153 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013154 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013155 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013156 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013157 hddLog(VOS_TRACE_LEVEL_INFO_MED,
13158 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013159 status = 0;
13160 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013161 }
13162 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
13163 {
13164 hddLog(VOS_TRACE_LEVEL_ERROR,
13165 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013166 status = -EINVAL;
13167 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013168 }
13169#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070013170
13171 /* issue set key request to SME*/
13172 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13173 pAdapter->sessionId, &setKey, &roamId );
13174
13175 if ( 0 != status )
13176 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013177 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013178 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
13179 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013180 status = -EINVAL;
13181 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013182 }
13183
13184
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013185 /* in case of IBSS as there was no information available about WEP keys during
13186 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070013187 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013188 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
13189 !( ( IW_AUTH_KEY_MGMT_802_1X
13190 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070013191 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
13192 )
13193 &&
13194 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
13195 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
13196 )
13197 )
13198 {
13199 setKey.keyDirection = eSIR_RX_ONLY;
13200 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13201
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013202 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013203 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013204 __func__, setKey.peerMac[0], setKey.peerMac[1],
13205 setKey.peerMac[2], setKey.peerMac[3],
13206 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013207 setKey.keyDirection);
13208
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013209 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013210 pAdapter->sessionId, &setKey, &roamId );
13211
13212 if ( 0 != status )
13213 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013214 hddLog(VOS_TRACE_LEVEL_ERROR,
13215 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013216 __func__, status);
13217 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013218 status = -EINVAL;
13219 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013220 }
13221 }
13222 }
13223
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013224 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013225 for (i = 0; i < params->seq_len; i++) {
13226 rsc_counter |= (params->seq[i] << i*8);
13227 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013228 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
13229 }
13230
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013231end:
13232 /* Need to clear any trace of key value in the memory.
13233 * Thus zero out the memory even though it is local
13234 * variable.
13235 */
13236 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013237 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013238 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013239}
13240
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013241#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13242static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13243 struct net_device *ndev,
13244 u8 key_index, bool pairwise,
13245 const u8 *mac_addr,
13246 struct key_params *params
13247 )
13248#else
13249static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13250 struct net_device *ndev,
13251 u8 key_index, const u8 *mac_addr,
13252 struct key_params *params
13253 )
13254#endif
13255{
13256 int ret;
13257 vos_ssr_protect(__func__);
13258#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13259 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
13260 mac_addr, params);
13261#else
13262 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
13263 params);
13264#endif
13265 vos_ssr_unprotect(__func__);
13266
13267 return ret;
13268}
13269
Jeff Johnson295189b2012-06-20 16:38:30 -070013270/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013271 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013272 * This function is used to get the key information
13273 */
13274#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013275static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013276 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013277 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013278 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013279 const u8 *mac_addr, void *cookie,
13280 void (*callback)(void *cookie, struct key_params*)
13281 )
13282#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013283static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013284 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013285 struct net_device *ndev,
13286 u8 key_index, const u8 *mac_addr, void *cookie,
13287 void (*callback)(void *cookie, struct key_params*)
13288 )
13289#endif
13290{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013291 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013292 hdd_wext_state_t *pWextState = NULL;
13293 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013294 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013295 hdd_context_t *pHddCtx;
13296 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013297
13298 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013299
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013300 if (NULL == pAdapter)
13301 {
13302 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13303 "%s: HDD adapter is Null", __func__);
13304 return -ENODEV;
13305 }
13306
13307 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13308 ret = wlan_hdd_validate_context(pHddCtx);
13309 if (0 != ret)
13310 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013311 return ret;
13312 }
13313
13314 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13315 pRoamProfile = &(pWextState->roamProfile);
13316
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013317 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13318 __func__, hdd_device_modetoString(pAdapter->device_mode),
13319 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013320
Jeff Johnson295189b2012-06-20 16:38:30 -070013321 memset(&params, 0, sizeof(params));
13322
13323 if (CSR_MAX_NUM_KEY <= key_index)
13324 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013325 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013326 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013327 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013328
13329 switch(pRoamProfile->EncryptionType.encryptionType[0])
13330 {
13331 case eCSR_ENCRYPT_TYPE_NONE:
13332 params.cipher = IW_AUTH_CIPHER_NONE;
13333 break;
13334
13335 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13336 case eCSR_ENCRYPT_TYPE_WEP40:
13337 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13338 break;
13339
13340 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13341 case eCSR_ENCRYPT_TYPE_WEP104:
13342 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13343 break;
13344
13345 case eCSR_ENCRYPT_TYPE_TKIP:
13346 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13347 break;
13348
13349 case eCSR_ENCRYPT_TYPE_AES:
13350 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13351 break;
13352
13353 default:
13354 params.cipher = IW_AUTH_CIPHER_NONE;
13355 break;
13356 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013357
c_hpothuaaf19692014-05-17 17:01:48 +053013358 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13359 TRACE_CODE_HDD_CFG80211_GET_KEY,
13360 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013361
Jeff Johnson295189b2012-06-20 16:38:30 -070013362 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13363 params.seq_len = 0;
13364 params.seq = NULL;
13365 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13366 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013367 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013368 return 0;
13369}
13370
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013371#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13372static int wlan_hdd_cfg80211_get_key(
13373 struct wiphy *wiphy,
13374 struct net_device *ndev,
13375 u8 key_index, bool pairwise,
13376 const u8 *mac_addr, void *cookie,
13377 void (*callback)(void *cookie, struct key_params*)
13378 )
13379#else
13380static int wlan_hdd_cfg80211_get_key(
13381 struct wiphy *wiphy,
13382 struct net_device *ndev,
13383 u8 key_index, const u8 *mac_addr, void *cookie,
13384 void (*callback)(void *cookie, struct key_params*)
13385 )
13386#endif
13387{
13388 int ret;
13389
13390 vos_ssr_protect(__func__);
13391#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13392 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13393 mac_addr, cookie, callback);
13394#else
13395 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13396 callback);
13397#endif
13398 vos_ssr_unprotect(__func__);
13399
13400 return ret;
13401}
13402
Jeff Johnson295189b2012-06-20 16:38:30 -070013403/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013404 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013405 * This function is used to delete the key information
13406 */
13407#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013408static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013409 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013410 u8 key_index,
13411 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013412 const u8 *mac_addr
13413 )
13414#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013415static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013416 struct net_device *ndev,
13417 u8 key_index,
13418 const u8 *mac_addr
13419 )
13420#endif
13421{
13422 int status = 0;
13423
13424 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013425 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013426 //it is observed that this is invalidating peer
13427 //key index whenever re-key is done. This is affecting data link.
13428 //It should be ok to ignore del_key.
13429#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013430 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13431 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013432 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13433 tCsrRoamSetKey setKey;
13434 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013435
Jeff Johnson295189b2012-06-20 16:38:30 -070013436 ENTER();
13437
13438 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13439 __func__,pAdapter->device_mode);
13440
13441 if (CSR_MAX_NUM_KEY <= key_index)
13442 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013443 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013444 key_index);
13445
13446 return -EINVAL;
13447 }
13448
13449 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13450 setKey.keyId = key_index;
13451
13452 if (mac_addr)
13453 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13454 else
13455 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13456
13457 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13458
13459 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013460 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013461 )
13462 {
13463
13464 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013465 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13466 if( pHostapdState->bssState == BSS_START)
13467 {
13468 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013469
Jeff Johnson295189b2012-06-20 16:38:30 -070013470 if ( status != eHAL_STATUS_SUCCESS )
13471 {
13472 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13473 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13474 __LINE__, status );
13475 }
13476 }
13477 }
13478 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013479 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013480 )
13481 {
13482 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13483
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013484 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13485
13486 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013487 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013488 __func__, setKey.peerMac[0], setKey.peerMac[1],
13489 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013490 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013491 if(pAdapter->sessionCtx.station.conn_info.connState ==
13492 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013493 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013494 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013495 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013496
Jeff Johnson295189b2012-06-20 16:38:30 -070013497 if ( 0 != status )
13498 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013499 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013500 "%s: sme_RoamSetKey failure, returned %d",
13501 __func__, status);
13502 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13503 return -EINVAL;
13504 }
13505 }
13506 }
13507#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013508 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013509 return status;
13510}
13511
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013512#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13513static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13514 struct net_device *ndev,
13515 u8 key_index,
13516 bool pairwise,
13517 const u8 *mac_addr
13518 )
13519#else
13520static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13521 struct net_device *ndev,
13522 u8 key_index,
13523 const u8 *mac_addr
13524 )
13525#endif
13526{
13527 int ret;
13528
13529 vos_ssr_protect(__func__);
13530#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13531 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
13532 mac_addr);
13533#else
13534 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
13535#endif
13536 vos_ssr_unprotect(__func__);
13537
13538 return ret;
13539}
13540
Jeff Johnson295189b2012-06-20 16:38:30 -070013541/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013542 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013543 * This function is used to set the default tx key index
13544 */
13545#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013546static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013547 struct net_device *ndev,
13548 u8 key_index,
13549 bool unicast, bool multicast)
13550#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013551static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013552 struct net_device *ndev,
13553 u8 key_index)
13554#endif
13555{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013556 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013557 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013558 hdd_wext_state_t *pWextState;
13559 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013560 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013561
13562 ENTER();
13563
Gopichand Nakkala29149562013-05-10 21:43:41 +053013564 if ((NULL == pAdapter))
13565 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013567 "invalid adapter");
13568 return -EINVAL;
13569 }
13570
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013571 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13572 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
13573 pAdapter->sessionId, key_index));
13574
Gopichand Nakkala29149562013-05-10 21:43:41 +053013575 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13576 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13577
13578 if ((NULL == pWextState) || (NULL == pHddStaCtx))
13579 {
13580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13581 "invalid Wext state or HDD context");
13582 return -EINVAL;
13583 }
13584
Arif Hussain6d2a3322013-11-17 19:50:10 -080013585 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013586 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013587
Jeff Johnson295189b2012-06-20 16:38:30 -070013588 if (CSR_MAX_NUM_KEY <= key_index)
13589 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013590 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013591 key_index);
13592
13593 return -EINVAL;
13594 }
13595
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013596 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13597 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013598 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013599 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013600 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013601 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013602
Jeff Johnson295189b2012-06-20 16:38:30 -070013603 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070013604 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013605 )
Jeff Johnson295189b2012-06-20 16:38:30 -070013606 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013607 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080013608 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080013609#ifdef FEATURE_WLAN_WAPI
13610 (eCSR_ENCRYPT_TYPE_WPI !=
13611 pHddStaCtx->conn_info.ucEncryptionType) &&
13612#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013613 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080013614 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070013615 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013616 {
13617 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070013618 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013619
Jeff Johnson295189b2012-06-20 16:38:30 -070013620 tCsrRoamSetKey setKey;
13621 v_U32_t roamId= 0xFF;
13622 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013623
13624 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013625 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013626
Jeff Johnson295189b2012-06-20 16:38:30 -070013627 Keys->defaultIndex = (u8)key_index;
13628 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13629 setKey.keyId = key_index;
13630 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013631
13632 vos_mem_copy(&setKey.Key[0],
13633 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013634 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013635
Gopichand Nakkala29149562013-05-10 21:43:41 +053013636 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013637
13638 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070013639 &pHddStaCtx->conn_info.bssId[0],
13640 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013641
Gopichand Nakkala29149562013-05-10 21:43:41 +053013642 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
13643 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
13644 eCSR_ENCRYPT_TYPE_WEP104)
13645 {
13646 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
13647 even though ap is configured for WEP-40 encryption. In this canse the key length
13648 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
13649 type(104) and switching encryption type to 40*/
13650 pWextState->roamProfile.EncryptionType.encryptionType[0] =
13651 eCSR_ENCRYPT_TYPE_WEP40;
13652 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
13653 eCSR_ENCRYPT_TYPE_WEP40;
13654 }
13655
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013656 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013657 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013658
Jeff Johnson295189b2012-06-20 16:38:30 -070013659 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013660 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013661 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013662
Jeff Johnson295189b2012-06-20 16:38:30 -070013663 if ( 0 != status )
13664 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013665 hddLog(VOS_TRACE_LEVEL_ERROR,
13666 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013667 status);
13668 return -EINVAL;
13669 }
13670 }
13671 }
13672
13673 /* In SoftAp mode setting key direction for default mode */
13674 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
13675 {
13676 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
13677 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
13678 (eCSR_ENCRYPT_TYPE_AES !=
13679 pWextState->roamProfile.EncryptionType.encryptionType[0])
13680 )
13681 {
13682 /* Saving key direction for default key index to TX default */
13683 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13684 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
13685 }
13686 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013687 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013688 return status;
13689}
13690
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013691#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13692static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13693 struct net_device *ndev,
13694 u8 key_index,
13695 bool unicast, bool multicast)
13696#else
13697static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13698 struct net_device *ndev,
13699 u8 key_index)
13700#endif
13701{
13702 int ret;
13703 vos_ssr_protect(__func__);
13704#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13705 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
13706 multicast);
13707#else
13708 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
13709#endif
13710 vos_ssr_unprotect(__func__);
13711
13712 return ret;
13713}
13714
Jeff Johnson295189b2012-06-20 16:38:30 -070013715/*
13716 * FUNCTION: wlan_hdd_cfg80211_inform_bss
13717 * This function is used to inform the BSS details to nl80211 interface.
13718 */
13719static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
13720 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
13721{
13722 struct net_device *dev = pAdapter->dev;
13723 struct wireless_dev *wdev = dev->ieee80211_ptr;
13724 struct wiphy *wiphy = wdev->wiphy;
13725 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
13726 int chan_no;
13727 int ie_length;
13728 const char *ie;
13729 unsigned int freq;
13730 struct ieee80211_channel *chan;
13731 int rssi = 0;
13732 struct cfg80211_bss *bss = NULL;
13733
Jeff Johnson295189b2012-06-20 16:38:30 -070013734 if( NULL == pBssDesc )
13735 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013736 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013737 return bss;
13738 }
13739
13740 chan_no = pBssDesc->channelId;
13741 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
13742 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
13743
13744 if( NULL == ie )
13745 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013746 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013747 return bss;
13748 }
13749
13750#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
13751 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
13752 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013753 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070013754 }
13755 else
13756 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013757 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070013758 }
13759#else
13760 freq = ieee80211_channel_to_frequency(chan_no);
13761#endif
13762
13763 chan = __ieee80211_get_channel(wiphy, freq);
13764
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053013765 if (!chan) {
13766 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
13767 return NULL;
13768 }
13769
Abhishek Singhaee43942014-06-16 18:55:47 +053013770 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070013771
Anand N Sunkad9f80b742015-07-30 20:05:51 +053013772 return cfg80211_inform_bss(wiphy, chan,
13773#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13774 CFG80211_BSS_FTYPE_UNKNOWN,
13775#endif
13776 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013777 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070013778 pBssDesc->capabilityInfo,
13779 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053013780 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070013781}
13782
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053013783/*
13784 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
13785 * interface that BSS might have been lost.
13786 * @pAdapter: adaptor
13787 * @bssid: bssid which might have been lost
13788 *
13789 * Return: bss which is unlinked from kernel cache
13790 */
13791struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
13792 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
13793{
13794 struct net_device *dev = pAdapter->dev;
13795 struct wireless_dev *wdev = dev->ieee80211_ptr;
13796 struct wiphy *wiphy = wdev->wiphy;
13797 struct cfg80211_bss *bss = NULL;
13798
Abhishek Singh5a597e62016-12-05 15:16:30 +053013799 bss = hdd_get_bss_entry(wiphy,
13800 NULL, bssid,
13801 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053013802 if (bss == NULL) {
13803 hddLog(LOGE, FL("BSS not present"));
13804 } else {
13805 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
13806 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
13807 cfg80211_unlink_bss(wiphy, bss);
13808 }
13809 return bss;
13810}
Jeff Johnson295189b2012-06-20 16:38:30 -070013811
13812
13813/*
13814 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
13815 * This function is used to inform the BSS details to nl80211 interface.
13816 */
13817struct cfg80211_bss*
13818wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
13819 tSirBssDescription *bss_desc
13820 )
13821{
13822 /*
13823 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
13824 already exists in bss data base of cfg80211 for that particular BSS ID.
13825 Using cfg80211_inform_bss_frame to update the bss entry instead of
13826 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
13827 now there is no possibility to get the mgmt(probe response) frame from PE,
13828 converting bss_desc to ieee80211_mgmt(probe response) and passing to
13829 cfg80211_inform_bss_frame.
13830 */
13831 struct net_device *dev = pAdapter->dev;
13832 struct wireless_dev *wdev = dev->ieee80211_ptr;
13833 struct wiphy *wiphy = wdev->wiphy;
13834 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013835#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13836 qcom_ie_age *qie_age = NULL;
13837 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
13838#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013839 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013840#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013841 const char *ie =
13842 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
13843 unsigned int freq;
13844 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013845 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013846 struct cfg80211_bss *bss_status = NULL;
13847 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
13848 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070013849 hdd_context_t *pHddCtx;
13850 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070013851#ifdef WLAN_OPEN_SOURCE
13852 struct timespec ts;
13853#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013854
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013855
Wilson Yangf80a0542013-10-07 13:02:37 -070013856 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13857 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070013858 if (0 != status)
13859 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013860 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013861 }
13862
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013863 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070013864 if (!mgmt)
13865 {
13866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13867 "%s: memory allocation failed ", __func__);
13868 return NULL;
13869 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013870
Jeff Johnson295189b2012-06-20 16:38:30 -070013871 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013872
13873#ifdef WLAN_OPEN_SOURCE
13874 /* Android does not want the timestamp from the frame.
13875 Instead it wants a monotonic increasing value */
13876 get_monotonic_boottime(&ts);
13877 mgmt->u.probe_resp.timestamp =
13878 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
13879#else
13880 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070013881 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
13882 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070013883
13884#endif
13885
Jeff Johnson295189b2012-06-20 16:38:30 -070013886 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
13887 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013888
13889#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13890 /* GPS Requirement: need age ie per entry. Using vendor specific. */
13891 /* Assuming this is the last IE, copy at the end */
13892 ie_length -=sizeof(qcom_ie_age);
13893 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
13894 qie_age->element_id = QCOM_VENDOR_IE_ID;
13895 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
13896 qie_age->oui_1 = QCOM_OUI1;
13897 qie_age->oui_2 = QCOM_OUI2;
13898 qie_age->oui_3 = QCOM_OUI3;
13899 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053013900 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
13901 * bss related timestamp is in units of ms. Due to this when scan results
13902 * are sent to lowi the scan age is high.To address this, send age in units
13903 * of 1/10 ms.
13904 */
13905 qie_age->age = (vos_timer_get_system_time() -
13906 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013907#endif
13908
Jeff Johnson295189b2012-06-20 16:38:30 -070013909 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053013910 if (bss_desc->fProbeRsp)
13911 {
13912 mgmt->frame_control |=
13913 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
13914 }
13915 else
13916 {
13917 mgmt->frame_control |=
13918 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
13919 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013920
13921#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013922 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013923 (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070013924 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013925 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070013926 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013927 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013928 (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070013929
13930 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013931 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070013932 }
13933 else
13934 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013935 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
13936 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070013937 kfree(mgmt);
13938 return NULL;
13939 }
13940#else
13941 freq = ieee80211_channel_to_frequency(chan_no);
13942#endif
13943 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013944 /*when the band is changed on the fly using the GUI, three things are done
13945 * 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)
13946 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
13947 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
13948 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
13949 * and discards the channels correponding to previous band and calls back with zero bss results.
13950 * 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
13951 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
13952 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
13953 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
13954 * So drop the bss and continue to next bss.
13955 */
13956 if(chan == NULL)
13957 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053013958 hddLog(VOS_TRACE_LEVEL_ERROR,
13959 FL("chan pointer is NULL, chan_no: %d freq: %d"),
13960 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070013961 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013962 return NULL;
13963 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053013964 /*To keep the rssi icon of the connected AP in the scan window
13965 *and the rssi icon of the wireless networks in sync
13966 * */
13967 if (( eConnectionState_Associated ==
13968 pAdapter->sessionCtx.station.conn_info.connState ) &&
13969 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
13970 pAdapter->sessionCtx.station.conn_info.bssId,
13971 WNI_CFG_BSSID_LEN)) &&
13972 (pHddCtx->hdd_wlan_suspended == FALSE))
13973 {
13974 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
13975 rssi = (pAdapter->rssi * 100);
13976 }
13977 else
13978 {
13979 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
13980 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013981
Nirav Shah20ac06f2013-12-12 18:14:06 +053013982 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053013983 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
13984 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053013985
Jeff Johnson295189b2012-06-20 16:38:30 -070013986 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
13987 frame_len, rssi, GFP_KERNEL);
13988 kfree(mgmt);
13989 return bss_status;
13990}
13991
13992/*
13993 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
13994 * This function is used to update the BSS data base of CFG8011
13995 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013996struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013997 tCsrRoamInfo *pRoamInfo
13998 )
13999{
14000 tCsrRoamConnectedProfile roamProfile;
14001 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14002 struct cfg80211_bss *bss = NULL;
14003
14004 ENTER();
14005
14006 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
14007 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
14008
14009 if (NULL != roamProfile.pBssDesc)
14010 {
Girish Gowlif4b68022014-08-28 23:18:57 +053014011 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14012 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070014013
14014 if (NULL == bss)
14015 {
14016 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
14017 __func__);
14018 }
14019
14020 sme_RoamFreeConnectProfile(hHal, &roamProfile);
14021 }
14022 else
14023 {
14024 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
14025 __func__);
14026 }
14027 return bss;
14028}
14029
14030/*
14031 * FUNCTION: wlan_hdd_cfg80211_update_bss
14032 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014033static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
14034 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070014035 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014036{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014037 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014038 tCsrScanResultInfo *pScanResult;
14039 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014040 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014041 tScanResultHandle pResult;
14042 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014043 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014044 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070014045 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014046
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014047 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14048 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
14049 NO_SESSION, pAdapter->sessionId));
14050
Wilson Yangf80a0542013-10-07 13:02:37 -070014051 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014052 ret = wlan_hdd_validate_context(pHddCtx);
14053 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070014054 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014055 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070014056 }
14057
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014058 if (pAdapter->request != NULL)
14059 {
14060 if ((pAdapter->request->n_ssids == 1)
14061 && (pAdapter->request->ssids != NULL)
14062 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
14063 is_p2p_scan = true;
14064 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014065 /*
14066 * start getting scan results and populate cgf80211 BSS database
14067 */
14068 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
14069
14070 /* no scan results */
14071 if (NULL == pResult)
14072 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014073 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
14074 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014075 wlan_hdd_get_frame_logs(pAdapter,
14076 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070014077 return status;
14078 }
14079
14080 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
14081
14082 while (pScanResult)
14083 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014084 /*
14085 * cfg80211_inform_bss() is not updating ie field of bss entry, if
14086 * entry already exists in bss data base of cfg80211 for that
14087 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
14088 * bss entry instead of cfg80211_inform_bss, But this call expects
14089 * mgmt packet as input. As of now there is no possibility to get
14090 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070014091 * ieee80211_mgmt(probe response) and passing to c
14092 * fg80211_inform_bss_frame.
14093 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014094 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
14095 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
14096 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014097 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14098 continue; //Skip the non p2p bss entries
14099 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014100 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14101 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014102
Jeff Johnson295189b2012-06-20 16:38:30 -070014103
14104 if (NULL == bss_status)
14105 {
14106 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014107 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014108 }
14109 else
14110 {
Yue Maf49ba872013-08-19 12:04:25 -070014111 cfg80211_put_bss(
14112#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
14113 wiphy,
14114#endif
14115 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070014116 }
14117
14118 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14119 }
14120
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014121 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014122 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014123 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014124}
14125
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014126void
14127hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
14128{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014129 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080014130 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014131} /****** end hddPrintMacAddr() ******/
14132
14133void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014134hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014135{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014136 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014137 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014138 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
14139 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
14140 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014141} /****** end hddPrintPmkId() ******/
14142
14143//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
14144//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
14145
14146//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
14147//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
14148
14149#define dump_bssid(bssid) \
14150 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014151 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
14152 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014153 }
14154
14155#define dump_pmkid(pMac, pmkid) \
14156 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014157 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
14158 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014159 }
14160
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070014161#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014162/*
14163 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
14164 * This function is used to notify the supplicant of a new PMKSA candidate.
14165 */
14166int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014167 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014168 int index, bool preauth )
14169{
Jeff Johnsone7245742012-09-05 17:12:55 -070014170#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014171 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014172 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014173
14174 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070014175 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014176
14177 if( NULL == pRoamInfo )
14178 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014179 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014180 return -EINVAL;
14181 }
14182
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014183 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
14184 {
14185 dump_bssid(pRoamInfo->bssid);
14186 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014187 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014188 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014189#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014190 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014191}
14192#endif //FEATURE_WLAN_LFR
14193
Yue Maef608272013-04-08 23:09:17 -070014194#ifdef FEATURE_WLAN_LFR_METRICS
14195/*
14196 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
14197 * 802.11r/LFR metrics reporting function to report preauth initiation
14198 *
14199 */
14200#define MAX_LFR_METRICS_EVENT_LENGTH 100
14201VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
14202 tCsrRoamInfo *pRoamInfo)
14203{
14204 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14205 union iwreq_data wrqu;
14206
14207 ENTER();
14208
14209 if (NULL == pAdapter)
14210 {
14211 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14212 return VOS_STATUS_E_FAILURE;
14213 }
14214
14215 /* create the event */
14216 memset(&wrqu, 0, sizeof(wrqu));
14217 memset(metrics_notification, 0, sizeof(metrics_notification));
14218
14219 wrqu.data.pointer = metrics_notification;
14220 wrqu.data.length = scnprintf(metrics_notification,
14221 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
14222 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14223
14224 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14225
14226 EXIT();
14227
14228 return VOS_STATUS_SUCCESS;
14229}
14230
14231/*
14232 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
14233 * 802.11r/LFR metrics reporting function to report preauth completion
14234 * or failure
14235 */
14236VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
14237 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
14238{
14239 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14240 union iwreq_data wrqu;
14241
14242 ENTER();
14243
14244 if (NULL == pAdapter)
14245 {
14246 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14247 return VOS_STATUS_E_FAILURE;
14248 }
14249
14250 /* create the event */
14251 memset(&wrqu, 0, sizeof(wrqu));
14252 memset(metrics_notification, 0, sizeof(metrics_notification));
14253
14254 scnprintf(metrics_notification, sizeof(metrics_notification),
14255 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
14256 MAC_ADDR_ARRAY(pRoamInfo->bssid));
14257
14258 if (1 == preauth_status)
14259 strncat(metrics_notification, " TRUE", 5);
14260 else
14261 strncat(metrics_notification, " FALSE", 6);
14262
14263 wrqu.data.pointer = metrics_notification;
14264 wrqu.data.length = strlen(metrics_notification);
14265
14266 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14267
14268 EXIT();
14269
14270 return VOS_STATUS_SUCCESS;
14271}
14272
14273/*
14274 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
14275 * 802.11r/LFR metrics reporting function to report handover initiation
14276 *
14277 */
14278VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
14279 tCsrRoamInfo *pRoamInfo)
14280{
14281 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14282 union iwreq_data wrqu;
14283
14284 ENTER();
14285
14286 if (NULL == pAdapter)
14287 {
14288 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14289 return VOS_STATUS_E_FAILURE;
14290 }
14291
14292 /* create the event */
14293 memset(&wrqu, 0, sizeof(wrqu));
14294 memset(metrics_notification, 0, sizeof(metrics_notification));
14295
14296 wrqu.data.pointer = metrics_notification;
14297 wrqu.data.length = scnprintf(metrics_notification,
14298 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14299 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14300
14301 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14302
14303 EXIT();
14304
14305 return VOS_STATUS_SUCCESS;
14306}
14307#endif
14308
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014309
14310/**
14311 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14312 * @scan_req: scan request to be checked
14313 *
14314 * Return: true or false
14315 */
14316#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14317static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14318 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014319 *scan_req, hdd_context_t
14320 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014321{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014322 if (!scan_req || !scan_req->wiphy ||
14323 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014324 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14325 return false;
14326 }
14327 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14328 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14329 return false;
14330 }
14331 return true;
14332}
14333#else
14334static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14335 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014336 *scan_req, hdd_context_t
14337 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014338{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014339 if (!scan_req || !scan_req->wiphy ||
14340 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014341 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14342 return false;
14343 }
14344 return true;
14345}
14346#endif
14347
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014348#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
14349/**
14350 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14351 * @adapter: Pointer to the adapter
14352 * @req : Scan request
14353 * @aborted : true scan aborted false scan success
14354 *
14355 * This function notifies scan done to cfg80211
14356 *
14357 * Return: none
14358 */
14359static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14360 struct cfg80211_scan_request *req,
14361 bool aborted)
14362{
14363 struct cfg80211_scan_info info = {
14364 .aborted = aborted
14365 };
14366
14367 if (adapter->dev->flags & IFF_UP)
14368 cfg80211_scan_done(req, &info);
14369 else
14370 hddLog(LOGW,
14371 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14372}
14373#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14374/**
14375 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14376 * @adapter: Pointer to the adapter
14377 * @req : Scan request
14378 * @aborted : true scan aborted false scan success
14379 *
14380 * This function notifies scan done to cfg80211
14381 *
14382 * Return: none
14383 */
14384static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14385 struct cfg80211_scan_request *req,
14386 bool aborted)
14387{
14388 if (adapter->dev->flags & IFF_UP)
14389 cfg80211_scan_done(req, aborted);
14390 else
14391 hddLog(LOGW,
14392 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14393}
14394#else
14395/**
14396 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14397 * @adapter: Pointer to the adapter
14398 * @req : Scan request
14399 * @aborted : true scan aborted false scan success
14400 *
14401 * This function notifies scan done to cfg80211
14402 *
14403 * Return: none
14404 */
14405static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14406 struct cfg80211_scan_request *req,
14407 bool aborted)
14408{
14409 cfg80211_scan_done(req, aborted);
14410}
14411#endif
14412
Mukul Sharmab392b642017-08-17 17:45:29 +053014413#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014414/*
14415 * FUNCTION: hdd_cfg80211_scan_done_callback
14416 * scanning callback function, called after finishing scan
14417 *
14418 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014419static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014420 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14421{
14422 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014423 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014424 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014425 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014426 struct cfg80211_scan_request *req = NULL;
14427 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014428 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014429 long waitRet = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014430 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014431
14432 ENTER();
14433
c_manjee1b4ab9a2016-10-26 11:36:55 +053014434 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14435 !pAdapter->dev) {
14436 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14437 return 0;
14438 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014439 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014440 if (NULL == pHddCtx) {
14441 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014442 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014443 }
14444
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014445#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014446 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014447 {
14448 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014449 }
14450#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014451 pScanInfo = &pHddCtx->scan_info;
14452
Jeff Johnson295189b2012-06-20 16:38:30 -070014453 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014454 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014455 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014456 __func__, halHandle, pContext, (int) scanId, (int) status);
14457
Kiet Lamac06e2c2013-10-23 16:25:07 +053014458 pScanInfo->mScanPendingCounter = 0;
14459
Jeff Johnson295189b2012-06-20 16:38:30 -070014460 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014461 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014462 &pScanInfo->scan_req_completion_event,
14463 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014464 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014465 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014466 hddLog(VOS_TRACE_LEVEL_ERROR,
14467 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014468 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014469 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014470 }
14471
Yue Maef608272013-04-08 23:09:17 -070014472 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014473 {
14474 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014475 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014476 }
14477
14478 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014479 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014480 {
14481 hddLog(VOS_TRACE_LEVEL_INFO,
14482 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014483 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014484 (int) scanId);
14485 }
14486
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014487#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014488 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014489#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014490 {
14491 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14492 pAdapter);
14493 if (0 > ret)
14494 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014495 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014496
Jeff Johnson295189b2012-06-20 16:38:30 -070014497 /* If any client wait scan result through WEXT
14498 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014499 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014500 {
14501 /* The other scan request waiting for current scan finish
14502 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014503 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014504 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014505 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014506 }
14507 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014508 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014509 {
14510 struct net_device *dev = pAdapter->dev;
14511 union iwreq_data wrqu;
14512 int we_event;
14513 char *msg;
14514
14515 memset(&wrqu, '\0', sizeof(wrqu));
14516 we_event = SIOCGIWSCAN;
14517 msg = NULL;
14518 wireless_send_event(dev, we_event, &wrqu, msg);
14519 }
14520 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014521 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014522
14523 /* Get the Scan Req */
14524 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014525 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014526
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014527 /* Scan is no longer pending */
14528 pScanInfo->mScanPending = VOS_FALSE;
14529
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014530 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070014531 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014532#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
14533 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053014534 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014535#endif
14536
14537 if (pAdapter->dev) {
14538 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
14539 pAdapter->dev->name);
14540 }
mukul sharmae7041822015-12-03 15:09:21 +053014541 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070014542 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014543 }
14544
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014545 /* last_scan_timestamp is used to decide if new scan
14546 * is needed or not on station interface. If last station
14547 * scan time and new station scan time is less then
14548 * last_scan_timestamp ; driver will return cached scan.
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014549 * Also only last_scan_timestamp is updated here last_scan_channellist
14550 * is updated on receiving scan request itself to make sure kernel
14551 * allocated scan request(scan_req) object is not dereferenced here,
14552 * because interface down, where kernel frees scan_req, may happen any
14553 * time while driver is processing scan_done_callback. So it's better
14554 * not to access scan_req in this routine.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014555 */
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014556 if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
14557 if (status == eCSR_SCAN_SUCCESS)
14558 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
14559 else {
14560 vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
14561 sizeof(pHddCtx->scan_info.last_scan_channelList));
14562 pHddCtx->scan_info.last_scan_numChannels = 0;
14563 pScanInfo->last_scan_timestamp = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014564 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014565 }
14566
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070014567 /*
14568 * cfg80211_scan_done informing NL80211 about completion
14569 * of scanning
14570 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014571 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
14572 {
14573 aborted = true;
14574 }
mukul sharmae7041822015-12-03 15:09:21 +053014575
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014576#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014577 if (NET_DEV_IS_IFF_UP(pAdapter) &&
14578 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014579#endif
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014580 hdd_cfg80211_scan_done(pAdapter, req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053014581
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080014582 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070014583
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014584allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014585 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
14586 ) && (pHddCtx->spoofMacAddr.isEnabled
14587 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053014588 /* Generate new random mac addr for next scan */
14589 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053014590
14591 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
14592 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053014593 }
14594
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014595 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014596 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014597
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014598 /* Acquire wakelock to handle the case where APP's tries to suspend
14599 * immediatly after the driver gets connect request(i.e after scan)
14600 * from supplicant, this result in app's is suspending and not able
14601 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014602 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014603
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014604#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014605 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014606#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014607#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014608 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014609#endif
14610
Jeff Johnson295189b2012-06-20 16:38:30 -070014611 EXIT();
14612 return 0;
14613}
14614
14615/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053014616 * FUNCTION: hdd_isConnectionInProgress
14617 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014618 *
14619 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014620v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
14621 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014622{
14623 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14624 hdd_station_ctx_t *pHddStaCtx = NULL;
14625 hdd_adapter_t *pAdapter = NULL;
14626 VOS_STATUS status = 0;
14627 v_U8_t staId = 0;
14628 v_U8_t *staMac = NULL;
14629
14630 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14631
14632 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14633 {
14634 pAdapter = pAdapterNode->pAdapter;
14635
14636 if( pAdapter )
14637 {
14638 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014639 "%s: Adapter with device mode %s (%d) exists",
14640 __func__, hdd_device_modetoString(pAdapter->device_mode),
14641 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014642 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053014643 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14644 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
14645 (eConnectionState_Connecting ==
14646 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14647 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014648 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014649 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053014650 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014651 if (session_id && reason)
14652 {
14653 *session_id = pAdapter->sessionId;
14654 *reason = eHDD_CONNECTION_IN_PROGRESS;
14655 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014656 return VOS_TRUE;
14657 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014658 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053014659 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014660 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014661 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014662 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014663 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014664 if (session_id && reason)
14665 {
14666 *session_id = pAdapter->sessionId;
14667 *reason = eHDD_REASSOC_IN_PROGRESS;
14668 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014669 return VOS_TRUE;
14670 }
14671 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014672 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14673 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014674 {
14675 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14676 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014677 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014678 {
14679 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014680 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014681 "%s: client " MAC_ADDRESS_STR
14682 " is in the middle of WPS/EAPOL exchange.", __func__,
14683 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014684 if (session_id && reason)
14685 {
14686 *session_id = pAdapter->sessionId;
14687 *reason = eHDD_EAPOL_IN_PROGRESS;
14688 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014689 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014690 }
14691 }
14692 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
14693 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
14694 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014695 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14696 ptSapContext pSapCtx = NULL;
14697 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14698 if(pSapCtx == NULL){
14699 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14700 FL("psapCtx is NULL"));
14701 return VOS_FALSE;
14702 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014703 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
14704 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014705 if ((pSapCtx->aStaInfo[staId].isUsed) &&
14706 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014707 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014708 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014709
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014710 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014711 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
14712 "middle of WPS/EAPOL exchange.", __func__,
14713 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014714 if (session_id && reason)
14715 {
14716 *session_id = pAdapter->sessionId;
14717 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
14718 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014719 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014720 }
14721 }
14722 }
14723 }
14724 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14725 pAdapterNode = pNext;
14726 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014727 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014728}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014729
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014730/**
14731 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
14732 * to the Scan request
14733 * @scanRequest: Pointer to the csr scan request
14734 * @request: Pointer to the scan request from supplicant
14735 *
14736 * Return: None
14737 */
14738#ifdef CFG80211_SCAN_BSSID
14739static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14740 struct cfg80211_scan_request *request)
14741{
14742 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
14743}
14744#else
14745static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14746 struct cfg80211_scan_request *request)
14747{
14748}
14749#endif
14750
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014751/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014752 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070014753 * this scan respond to scan trigger and update cfg80211 scan database
14754 * later, scan dump command can be used to recieve scan results
14755 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014756int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014757#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14758 struct net_device *dev,
14759#endif
14760 struct cfg80211_scan_request *request)
14761{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014762 hdd_adapter_t *pAdapter = NULL;
14763 hdd_context_t *pHddCtx = NULL;
14764 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014765 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014766 tCsrScanRequest scanRequest;
14767 tANI_U8 *channelList = NULL, i;
14768 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014769 int status;
14770 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014771 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014772 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053014773 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014774 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014775 v_U8_t curr_session_id;
14776 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070014777
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014778#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
14779 struct net_device *dev = NULL;
14780 if (NULL == request)
14781 {
14782 hddLog(VOS_TRACE_LEVEL_ERROR,
14783 "%s: scan req param null", __func__);
14784 return -EINVAL;
14785 }
14786 dev = request->wdev->netdev;
14787#endif
14788
14789 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
14790 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
14791 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14792
Jeff Johnson295189b2012-06-20 16:38:30 -070014793 ENTER();
14794
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014795 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
14796 __func__, hdd_device_modetoString(pAdapter->device_mode),
14797 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014798
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014799 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014800 if (0 != status)
14801 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014802 return status;
14803 }
14804
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014805 if (NULL == pwextBuf)
14806 {
14807 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
14808 __func__);
14809 return -EIO;
14810 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014811 cfg_param = pHddCtx->cfg_ini;
14812 pScanInfo = &pHddCtx->scan_info;
14813
Jeff Johnson295189b2012-06-20 16:38:30 -070014814#ifdef WLAN_BTAMP_FEATURE
14815 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014816 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070014817 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080014818 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014819 "%s: No scanning when AMP is on", __func__);
14820 return -EOPNOTSUPP;
14821 }
14822#endif
14823 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014824 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014825 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014826 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014827 "%s: Not scanning on device_mode = %s (%d)",
14828 __func__, hdd_device_modetoString(pAdapter->device_mode),
14829 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014830 return -EOPNOTSUPP;
14831 }
14832
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053014833 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
14834 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
14835 return -EOPNOTSUPP;
14836 }
14837
Jeff Johnson295189b2012-06-20 16:38:30 -070014838 if (TRUE == pScanInfo->mScanPending)
14839 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053014840 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
14841 {
14842 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
14843 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014844 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070014845 }
14846
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053014847 // Don't allow scan if PNO scan is going on.
14848 if (pHddCtx->isPnoEnable)
14849 {
14850 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14851 FL("pno scan in progress"));
14852 return -EBUSY;
14853 }
14854
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014855 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070014856 //Channel and action frame is pending
14857 //Otherwise Cancel Remain On Channel and allow Scan
14858 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014859 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070014860 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053014861 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070014862 return -EBUSY;
14863 }
14864
Jeff Johnson295189b2012-06-20 16:38:30 -070014865 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
14866 {
14867 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080014868 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014869 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014870 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014871 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
14872 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014873 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014874 "%s: MAX TM Level Scan not allowed", __func__);
14875 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014876 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070014877 }
14878 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
14879
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014880 /* Check if scan is allowed at this point of time.
14881 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053014882 if (TRUE == pHddCtx->btCoexModeSet)
14883 {
14884 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14885 FL("BTCoex Mode operation in progress"));
14886 return -EBUSY;
14887 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014888 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014889 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014890
14891 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
14892 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
14893 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014894 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
14895 pHddCtx->last_scan_reject_reason != curr_reason ||
14896 !pHddCtx->last_scan_reject_timestamp)
14897 {
14898 pHddCtx->last_scan_reject_session_id = curr_session_id;
14899 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053014900 pHddCtx->last_scan_reject_timestamp =
14901 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014902 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053014903 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053014904 else
14905 {
14906 pHddCtx->scan_reject_cnt++;
14907
Abhishek Singhe4b12562017-06-20 16:53:39 +053014908 if ((pHddCtx->scan_reject_cnt >=
14909 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053014910 vos_system_time_after(jiffies_to_msecs(jiffies),
14911 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014912 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014913 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
14914 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
14915 vos_system_time_after(jiffies_to_msecs(jiffies),
14916 pHddCtx->last_scan_reject_timestamp));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014917 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014918 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014919 if (pHddCtx->cfg_ini->enableFatalEvent)
14920 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
14921 WLAN_LOG_INDICATOR_HOST_DRIVER,
14922 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
14923 FALSE, FALSE);
14924 else
14925 {
14926 hddLog(LOGE, FL("Triggering SSR"));
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +053014927 vos_wlanRestart(VOS_SCAN_REQ_EXPIRED);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014928 }
14929 }
14930 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014931 return -EBUSY;
14932 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014933 pHddCtx->last_scan_reject_timestamp = 0;
14934 pHddCtx->last_scan_reject_session_id = 0xFF;
14935 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014936 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014937
Jeff Johnson295189b2012-06-20 16:38:30 -070014938 vos_mem_zero( &scanRequest, sizeof(scanRequest));
14939
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014940 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
14941 * Becasue of this, driver is assuming that this is not wildcard scan and so
14942 * is not aging out the scan results.
14943 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053014944 if ((request->ssids) && (request->n_ssids == 1) &&
14945 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014946 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014947 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014948
14949 if ((request->ssids) && (0 < request->n_ssids))
14950 {
14951 tCsrSSIDInfo *SsidInfo;
14952 int j;
14953 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
14954 /* Allocate num_ssid tCsrSSIDInfo structure */
14955 SsidInfo = scanRequest.SSIDs.SSIDList =
14956 ( tCsrSSIDInfo *)vos_mem_malloc(
14957 request->n_ssids*sizeof(tCsrSSIDInfo));
14958
14959 if(NULL == scanRequest.SSIDs.SSIDList)
14960 {
14961 hddLog(VOS_TRACE_LEVEL_ERROR,
14962 "%s: memory alloc failed SSIDInfo buffer", __func__);
14963 return -ENOMEM;
14964 }
14965
14966 /* copy all the ssid's and their length */
14967 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
14968 {
14969 /* get the ssid length */
14970 SsidInfo->SSID.length = request->ssids[j].ssid_len;
14971 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
14972 SsidInfo->SSID.length);
14973 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
14974 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
14975 j, SsidInfo->SSID.ssId);
14976 }
14977 /* set the scan type to active */
14978 scanRequest.scanType = eSIR_ACTIVE_SCAN;
14979 }
14980 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014981 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014982 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14983 TRACE_CODE_HDD_CFG80211_SCAN,
14984 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070014985 /* set the scan type to active */
14986 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070014987 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014988 else
14989 {
14990 /*Set the scan type to default type, in this case it is ACTIVE*/
14991 scanRequest.scanType = pScanInfo->scan_mode;
14992 }
14993 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
14994 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070014995
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014996 csr_scan_request_assign_bssid(&scanRequest, request);
14997
Jeff Johnson295189b2012-06-20 16:38:30 -070014998 /* set BSSType to default type */
14999 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
15000
15001 /*TODO: scan the requested channels only*/
15002
15003 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015004 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070015005 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015006 hddLog(VOS_TRACE_LEVEL_WARN,
15007 "No of Scan Channels exceeded limit: %d", request->n_channels);
15008 request->n_channels = MAX_CHANNEL;
15009 }
15010
15011 hddLog(VOS_TRACE_LEVEL_INFO,
15012 "No of Scan Channels: %d", request->n_channels);
15013
15014
15015 if( request->n_channels )
15016 {
15017 char chList [(request->n_channels*5)+1];
15018 int len;
15019 channelList = vos_mem_malloc( request->n_channels );
15020 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053015021 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015022 hddLog(VOS_TRACE_LEVEL_ERROR,
15023 "%s: memory alloc failed channelList", __func__);
15024 status = -ENOMEM;
15025 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053015026 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015027
15028 for( i = 0, len = 0; i < request->n_channels ; i++ )
15029 {
15030 channelList[i] = request->channels[i]->hw_value;
15031 len += snprintf(chList+len, 5, "%d ", channelList[i]);
15032 }
15033
Nirav Shah20ac06f2013-12-12 18:14:06 +053015034 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015035 "Channel-List: %s ", chList);
15036 }
c_hpothu53512302014-04-15 18:49:53 +053015037
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015038 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
15039 scanRequest.ChannelInfo.ChannelList = channelList;
15040
15041 /* set requestType to full scan */
15042 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
15043
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015044 /* if there is back to back scan happening in driver with in
15045 * nDeferScanTimeInterval interval driver should defer new scan request
15046 * and should provide last cached scan results instead of new channel list.
15047 * This rule is not applicable if scan is p2p scan.
15048 * This condition will work only in case when last request no of channels
15049 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053015050 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053015051 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015052 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015053
Sushant Kaushik86592172015-04-27 16:35:03 +053015054 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
15055 /* if wps ie is NULL , then only defer scan */
15056 if ( pWpsIe == NULL &&
15057 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053015058 {
15059 if ( pScanInfo->last_scan_timestamp !=0 &&
15060 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
15061 {
15062 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
15063 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
15064 vos_mem_compare(pScanInfo->last_scan_channelList,
15065 channelList, pScanInfo->last_scan_numChannels))
15066 {
15067 hddLog(VOS_TRACE_LEVEL_WARN,
15068 " New and old station scan time differ is less then %u",
15069 pHddCtx->cfg_ini->nDeferScanTimeInterval);
15070
15071 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015072 pAdapter);
15073
Agarwal Ashish57e84372014-12-05 18:26:53 +053015074 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015075 "Return old cached scan as all channels and no of channels are same");
15076
Agarwal Ashish57e84372014-12-05 18:26:53 +053015077 if (0 > ret)
15078 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015079
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015080 hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015081
15082 status = eHAL_STATUS_SUCCESS;
15083 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053015084 }
15085 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015086 }
15087
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015088 /* Flush the scan results(only p2p beacons) for STA scan and P2P
15089 * search (Flush on both full scan and social scan but not on single
15090 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
15091 */
15092
15093 /* Supplicant does single channel scan after 8-way handshake
15094 * and in that case driver shoudnt flush scan results. If
15095 * driver flushes the scan results here and unfortunately if
15096 * the AP doesnt respond to our probe req then association
15097 * fails which is not desired
15098 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015099 if ((request->n_ssids == 1)
15100 && (request->ssids != NULL)
15101 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
15102 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015103
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015104 if( is_p2p_scan ||
15105 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015106 {
15107 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
15108 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
15109 pAdapter->sessionId );
15110 }
15111
15112 if( request->ie_len )
15113 {
15114 /* save this for future association (join requires this) */
15115 /*TODO: Array needs to be converted to dynamic allocation,
15116 * as multiple ie.s can be sent in cfg80211_scan_request structure
15117 * CR 597966
15118 */
15119 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
15120 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
15121 pScanInfo->scanAddIE.length = request->ie_len;
15122
15123 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15124 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15125 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015126 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015127 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070015128 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015129 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
15130 memcpy( pwextBuf->roamProfile.addIEScan,
15131 request->ie, request->ie_len);
15132 }
15133 else
15134 {
15135 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
15136 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070015137 }
15138
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015139 }
15140 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
15141 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
15142
15143 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
15144 request->ie_len);
15145 if (pP2pIe != NULL)
15146 {
15147#ifdef WLAN_FEATURE_P2P_DEBUG
15148 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
15149 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
15150 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053015151 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015152 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
15153 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15154 "Go nego completed to Connection is started");
15155 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15156 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053015157 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015158 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
15159 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015160 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015161 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
15162 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15163 "Disconnected state to Connection is started");
15164 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15165 "for 4way Handshake");
15166 }
15167#endif
15168
15169 /* no_cck will be set during p2p find to disable 11b rates */
15170 if(TRUE == request->no_cck)
15171 {
15172 hddLog(VOS_TRACE_LEVEL_INFO,
15173 "%s: This is a P2P Search", __func__);
15174 scanRequest.p2pSearch = 1;
15175
15176 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053015177 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015178 /* set requestType to P2P Discovery */
15179 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
15180 }
15181
15182 /*
15183 Skip Dfs Channel in case of P2P Search
15184 if it is set in ini file
15185 */
15186 if(cfg_param->skipDfsChnlInP2pSearch)
15187 {
15188 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015189 }
15190 else
15191 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015192 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015193 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015194
Agarwal Ashish4f616132013-12-30 23:32:50 +053015195 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015196 }
15197 }
15198
15199 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
15200
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015201#ifdef FEATURE_WLAN_TDLS
15202 /* if tdls disagree scan right now, return immediately.
15203 tdls will schedule the scan when scan is allowed. (return SUCCESS)
15204 or will reject the scan if any TDLS is in progress. (return -EBUSY)
15205 */
15206 status = wlan_hdd_tdls_scan_callback (pAdapter,
15207 wiphy,
15208#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15209 dev,
15210#endif
15211 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015212 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015213 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053015214 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015215 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
15216 "scan rejected %d", __func__, status);
15217 else
15218 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
15219 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015220 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053015221 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015222 }
15223#endif
15224
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015225 /* acquire the wakelock to avoid the apps suspend during the scan. To
15226 * address the following issues.
15227 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
15228 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
15229 * for long time, this result in apps running at full power for long time.
15230 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
15231 * be stuck in full power because of resume BMPS
15232 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015233 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015234
Nirav Shah20ac06f2013-12-12 18:14:06 +053015235 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
15236 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015237 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
15238 scanRequest.requestType, scanRequest.scanType,
15239 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053015240 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
15241
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015242 if (pHddCtx->spoofMacAddr.isEnabled &&
15243 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053015244 {
15245 hddLog(VOS_TRACE_LEVEL_INFO,
15246 "%s: MAC Spoofing enabled for current scan", __func__);
15247 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15248 * to fill TxBds for probe request during current scan
15249 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015250 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053015251 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015252
15253 if(status != VOS_STATUS_SUCCESS)
15254 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015255 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015256 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053015257#ifdef FEATURE_WLAN_TDLS
15258 wlan_hdd_tdls_scan_done_callback(pAdapter);
15259#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015260 goto free_mem;
15261 }
Siddharth Bhal76972212014-10-15 16:22:51 +053015262 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053015263 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070015264 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015265 pAdapter->sessionId, &scanRequest, &scanId,
15266 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070015267
Jeff Johnson295189b2012-06-20 16:38:30 -070015268 if (eHAL_STATUS_SUCCESS != status)
15269 {
15270 hddLog(VOS_TRACE_LEVEL_ERROR,
15271 "%s: sme_ScanRequest returned error %d", __func__, status);
15272 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015273 if(eHAL_STATUS_RESOURCES == status)
15274 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015275 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
15276 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015277 status = -EBUSY;
15278 } else {
15279 status = -EIO;
15280 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015281 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015282
15283#ifdef FEATURE_WLAN_TDLS
15284 wlan_hdd_tdls_scan_done_callback(pAdapter);
15285#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015286 goto free_mem;
15287 }
15288
15289 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015290 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070015291 pAdapter->request = request;
15292 pScanInfo->scanId = scanId;
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015293 pScanInfo->no_cck = request->no_cck;
15294 pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
15295 for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
15296 pHddCtx->scan_info.last_scan_channelList[i] =
15297 request->channels[i]->hw_value;
15298 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015299
15300 complete(&pScanInfo->scan_req_completion_event);
15301
15302free_mem:
15303 if( scanRequest.SSIDs.SSIDList )
15304 {
15305 vos_mem_free(scanRequest.SSIDs.SSIDList);
15306 }
15307
15308 if( channelList )
15309 vos_mem_free( channelList );
15310
15311 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015312 return status;
15313}
15314
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015315int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
15316#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15317 struct net_device *dev,
15318#endif
15319 struct cfg80211_scan_request *request)
15320{
15321 int ret;
15322
15323 vos_ssr_protect(__func__);
15324 ret = __wlan_hdd_cfg80211_scan(wiphy,
15325#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15326 dev,
15327#endif
15328 request);
15329 vos_ssr_unprotect(__func__);
15330
15331 return ret;
15332}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015333
15334void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
15335{
15336 v_U8_t iniDot11Mode =
15337 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
15338 eHddDot11Mode hddDot11Mode = iniDot11Mode;
15339
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015340 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
15341 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015342 switch ( iniDot11Mode )
15343 {
15344 case eHDD_DOT11_MODE_AUTO:
15345 case eHDD_DOT11_MODE_11ac:
15346 case eHDD_DOT11_MODE_11ac_ONLY:
15347#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053015348 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
15349 sme_IsFeatureSupportedByFW(DOT11AC) )
15350 hddDot11Mode = eHDD_DOT11_MODE_11ac;
15351 else
15352 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015353#else
15354 hddDot11Mode = eHDD_DOT11_MODE_11n;
15355#endif
15356 break;
15357 case eHDD_DOT11_MODE_11n:
15358 case eHDD_DOT11_MODE_11n_ONLY:
15359 hddDot11Mode = eHDD_DOT11_MODE_11n;
15360 break;
15361 default:
15362 hddDot11Mode = iniDot11Mode;
15363 break;
15364 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015365#ifdef WLAN_FEATURE_AP_HT40_24G
15366 if (operationChannel > SIR_11B_CHANNEL_END)
15367#endif
15368 {
15369 /* This call decides required channel bonding mode */
15370 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015371 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053015372 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015373 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015374}
15375
Jeff Johnson295189b2012-06-20 16:38:30 -070015376/*
15377 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015378 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015379 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015380int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053015381 const u8 *ssid, size_t ssid_len, const u8 *bssid,
15382 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070015383{
15384 int status = 0;
15385 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080015386 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015387 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015388 v_U32_t roamId;
15389 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070015390 eCsrAuthType RSNAuthType;
15391
15392 ENTER();
15393
15394 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015395 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015396 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015397
15398 status = wlan_hdd_validate_context(pHddCtx);
15399 if (status)
15400 {
Yue Mae36e3552014-03-05 17:06:20 -080015401 return status;
15402 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015403
Jeff Johnson295189b2012-06-20 16:38:30 -070015404 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
15405 {
15406 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
15407 return -EINVAL;
15408 }
15409
Nitesh Shah9b066282017-06-06 18:05:52 +053015410 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
15411
Jeff Johnson295189b2012-06-20 16:38:30 -070015412 pRoamProfile = &pWextState->roamProfile;
15413
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015414 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070015415 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015416 hdd_station_ctx_t *pHddStaCtx;
15417 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053015418 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015419
Siddharth Bhalda0d1622015-04-24 15:47:49 +053015420 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
15421
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015422 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070015423 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
15424 {
15425 /*QoS not enabled in cfg file*/
15426 pRoamProfile->uapsd_mask = 0;
15427 }
15428 else
15429 {
15430 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015431 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070015432 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
15433 }
15434
15435 pRoamProfile->SSIDs.numOfSSIDs = 1;
15436 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
15437 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015438 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070015439 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
15440 ssid, ssid_len);
15441
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015442 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
15443 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
15444
Jeff Johnson295189b2012-06-20 16:38:30 -070015445 if (bssid)
15446 {
15447 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015448 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015449 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015450 /* Save BSSID in seperate variable as well, as RoamProfile
15451 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070015452 case of join failure we should send valid BSSID to supplicant
15453 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015454 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015455 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015456
Jeff Johnson295189b2012-06-20 16:38:30 -070015457 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015458 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070015459 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015460 /* Store bssid_hint to use in the scan filter. */
15461 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15462 WNI_CFG_BSSID_LEN);
15463 /*
15464 * Save BSSID in seperate variable as well, as RoamProfile
15465 * BSSID is getting zeroed out in the association process. And in
15466 * case of join failure we should send valid BSSID to supplicant
15467 */
15468 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15469 WNI_CFG_BSSID_LEN);
15470 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15471 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015472 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015473
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015474
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015475 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15476 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015477 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15478 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015479 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015480 /*set gen ie*/
15481 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15482 /*set auth*/
15483 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15484 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015485#ifdef FEATURE_WLAN_WAPI
15486 if (pAdapter->wapi_info.nWapiMode)
15487 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015488 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015489 switch (pAdapter->wapi_info.wapiAuthMode)
15490 {
15491 case WAPI_AUTH_MODE_PSK:
15492 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015493 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015494 pAdapter->wapi_info.wapiAuthMode);
15495 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15496 break;
15497 }
15498 case WAPI_AUTH_MODE_CERT:
15499 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015500 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015501 pAdapter->wapi_info.wapiAuthMode);
15502 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15503 break;
15504 }
15505 } // End of switch
15506 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15507 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15508 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015509 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015510 pRoamProfile->AuthType.numEntries = 1;
15511 pRoamProfile->EncryptionType.numEntries = 1;
15512 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15513 pRoamProfile->mcEncryptionType.numEntries = 1;
15514 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15515 }
15516 }
15517#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015518#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015519 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015520 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15521 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
15522 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015523 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
15524 sizeof (tSirGtkOffloadParams));
15525 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015526 }
15527#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015528 pRoamProfile->csrPersona = pAdapter->device_mode;
15529
Jeff Johnson32d95a32012-09-10 13:15:23 -070015530 if( operatingChannel )
15531 {
15532 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
15533 pRoamProfile->ChannelInfo.numOfChannels = 1;
15534 }
Chet Lanctot186b5732013-03-18 10:26:30 -070015535 else
15536 {
15537 pRoamProfile->ChannelInfo.ChannelList = NULL;
15538 pRoamProfile->ChannelInfo.numOfChannels = 0;
15539 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015540 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
15541 {
15542 hdd_select_cbmode(pAdapter,operatingChannel);
15543 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015544
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015545 /*
15546 * Change conn_state to connecting before sme_RoamConnect(),
15547 * because sme_RoamConnect() has a direct path to call
15548 * hdd_smeRoamCallback(), which will change the conn_state
15549 * If direct path, conn_state will be accordingly changed
15550 * to NotConnected or Associated by either
15551 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
15552 * in sme_RoamCallback()
15553 * if sme_RomConnect is to be queued,
15554 * Connecting state will remain until it is completed.
15555 * If connection state is not changed,
15556 * connection state will remain in eConnectionState_NotConnected state.
15557 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
15558 * if conn state is eConnectionState_NotConnected.
15559 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
15560 * informed of connect result indication which is an issue.
15561 */
15562
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015563 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15564 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053015565 {
15566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015567 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015568 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
15569 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053015570 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015571 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015572 pAdapter->sessionId, pRoamProfile, &roamId);
15573
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015574 if ((eHAL_STATUS_SUCCESS != status) &&
15575 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15576 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015577
15578 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015579 hddLog(VOS_TRACE_LEVEL_ERROR,
15580 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
15581 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015582 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015583 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015584 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015585 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015586
15587 pRoamProfile->ChannelInfo.ChannelList = NULL;
15588 pRoamProfile->ChannelInfo.numOfChannels = 0;
15589
Jeff Johnson295189b2012-06-20 16:38:30 -070015590 }
15591 else
15592 {
15593 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
15594 return -EINVAL;
15595 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015596 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015597 return status;
15598}
15599
15600/*
15601 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
15602 * This function is used to set the authentication type (OPEN/SHARED).
15603 *
15604 */
15605static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
15606 enum nl80211_auth_type auth_type)
15607{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015608 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015609 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15610
15611 ENTER();
15612
15613 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015614 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070015615 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015616 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015617 hddLog(VOS_TRACE_LEVEL_INFO,
15618 "%s: set authentication type to AUTOSWITCH", __func__);
15619 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
15620 break;
15621
15622 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015623#ifdef WLAN_FEATURE_VOWIFI_11R
15624 case NL80211_AUTHTYPE_FT:
15625#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015626 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015627 "%s: set authentication type to OPEN", __func__);
15628 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
15629 break;
15630
15631 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015632 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015633 "%s: set authentication type to SHARED", __func__);
15634 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
15635 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015636#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015637 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015638 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015639 "%s: set authentication type to CCKM WPA", __func__);
15640 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
15641 break;
15642#endif
15643
15644
15645 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015646 hddLog(VOS_TRACE_LEVEL_ERROR,
15647 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015648 auth_type);
15649 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
15650 return -EINVAL;
15651 }
15652
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015653 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015654 pHddStaCtx->conn_info.authType;
15655 return 0;
15656}
15657
15658/*
15659 * FUNCTION: wlan_hdd_set_akm_suite
15660 * This function is used to set the key mgmt type(PSK/8021x).
15661 *
15662 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015663static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015664 u32 key_mgmt
15665 )
15666{
15667 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15668 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053015669 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015670#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015671#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015672#endif
15673#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015674#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015675#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015676 /*set key mgmt type*/
15677 switch(key_mgmt)
15678 {
15679 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053015680 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015681#ifdef WLAN_FEATURE_VOWIFI_11R
15682 case WLAN_AKM_SUITE_FT_PSK:
15683#endif
15684 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070015685 __func__);
15686 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
15687 break;
15688
15689 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053015690 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015691#ifdef WLAN_FEATURE_VOWIFI_11R
15692 case WLAN_AKM_SUITE_FT_8021X:
15693#endif
15694 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070015695 __func__);
15696 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15697 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015698#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015699#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
15700#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
15701 case WLAN_AKM_SUITE_CCKM:
15702 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
15703 __func__);
15704 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
15705 break;
15706#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070015707#ifndef WLAN_AKM_SUITE_OSEN
15708#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
15709 case WLAN_AKM_SUITE_OSEN:
15710 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
15711 __func__);
15712 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15713 break;
15714#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015715
15716 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015717 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015718 __func__, key_mgmt);
15719 return -EINVAL;
15720
15721 }
15722 return 0;
15723}
15724
15725/*
15726 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015727 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070015728 * (NONE/WEP40/WEP104/TKIP/CCMP).
15729 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015730static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
15731 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070015732 bool ucast
15733 )
15734{
15735 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015736 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015737 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15738
15739 ENTER();
15740
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015741 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015742 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053015743 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070015744 __func__, cipher);
15745 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15746 }
15747 else
15748 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015749
Jeff Johnson295189b2012-06-20 16:38:30 -070015750 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015751 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015752 {
15753 case IW_AUTH_CIPHER_NONE:
15754 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15755 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015756
Jeff Johnson295189b2012-06-20 16:38:30 -070015757 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015758 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070015759 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015760
Jeff Johnson295189b2012-06-20 16:38:30 -070015761 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015762 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070015763 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015764
Jeff Johnson295189b2012-06-20 16:38:30 -070015765 case WLAN_CIPHER_SUITE_TKIP:
15766 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
15767 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015768
Jeff Johnson295189b2012-06-20 16:38:30 -070015769 case WLAN_CIPHER_SUITE_CCMP:
15770 encryptionType = eCSR_ENCRYPT_TYPE_AES;
15771 break;
15772#ifdef FEATURE_WLAN_WAPI
15773 case WLAN_CIPHER_SUITE_SMS4:
15774 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
15775 break;
15776#endif
15777
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015778#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015779 case WLAN_CIPHER_SUITE_KRK:
15780 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
15781 break;
15782#endif
15783 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015784 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015785 __func__, cipher);
15786 return -EOPNOTSUPP;
15787 }
15788 }
15789
15790 if (ucast)
15791 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015792 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015793 __func__, encryptionType);
15794 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15795 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015796 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015797 encryptionType;
15798 }
15799 else
15800 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015801 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015802 __func__, encryptionType);
15803 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
15804 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
15805 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
15806 }
15807
15808 return 0;
15809}
15810
15811
15812/*
15813 * FUNCTION: wlan_hdd_cfg80211_set_ie
15814 * This function is used to parse WPA/RSN IE's.
15815 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015816int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015817#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15818 const u8 *ie,
15819#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015820 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015821#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015822 size_t ie_len
15823 )
15824{
15825 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015826#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15827 const u8 *genie = ie;
15828#else
Jeff Johnson295189b2012-06-20 16:38:30 -070015829 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015830#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015831 v_U16_t remLen = ie_len;
15832#ifdef FEATURE_WLAN_WAPI
15833 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
15834 u16 *tmp;
15835 v_U16_t akmsuiteCount;
15836 int *akmlist;
15837#endif
15838 ENTER();
15839
15840 /* clear previous assocAddIE */
15841 pWextState->assocAddIE.length = 0;
15842 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015843 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015844
15845 while (remLen >= 2)
15846 {
15847 v_U16_t eLen = 0;
15848 v_U8_t elementId;
15849 elementId = *genie++;
15850 eLen = *genie++;
15851 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015852
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053015853 /* Sanity check on eLen */
15854 if (eLen > remLen) {
15855 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
15856 __func__, eLen, elementId);
15857 VOS_ASSERT(0);
15858 return -EINVAL;
15859 }
15860
Arif Hussain6d2a3322013-11-17 19:50:10 -080015861 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070015862 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015863
15864 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070015865 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015866 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015867 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 -070015868 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015869 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015870 "%s: Invalid WPA IE", __func__);
15871 return -EINVAL;
15872 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015873 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070015874 {
15875 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015876 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015877 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015878
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015879 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015880 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015881 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
15882 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015883 VOS_ASSERT(0);
15884 return -ENOMEM;
15885 }
15886 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15887 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15888 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015889
Jeff Johnson295189b2012-06-20 16:38:30 -070015890 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
15891 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15892 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15893 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015894 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
15895 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053015896 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
15897 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
15898 __func__, eLen);
15899 VOS_ASSERT(0);
15900 return -EINVAL;
15901 }
15902
Jeff Johnson295189b2012-06-20 16:38:30 -070015903 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
15904 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15905 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
15906 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
15907 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
15908 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015909 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053015910 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070015911 {
15912 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015913 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015914 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015915
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015916 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015917 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015918 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15919 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015920 VOS_ASSERT(0);
15921 return -ENOMEM;
15922 }
15923 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15924 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15925 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015926
Jeff Johnson295189b2012-06-20 16:38:30 -070015927 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15928 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15929 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015930#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015931 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
15932 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015933 /*Consider WFD IE, only for P2P Client */
15934 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15935 {
15936 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015937 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015938 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015939
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015940 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015941 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015942 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15943 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015944 VOS_ASSERT(0);
15945 return -ENOMEM;
15946 }
15947 // WFD IE is saved to Additional IE ; it should be accumulated to handle
15948 // WPS IE + P2P IE + WFD IE
15949 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15950 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015951
Jeff Johnson295189b2012-06-20 16:38:30 -070015952 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15953 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15954 }
15955#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015956 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015957 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015958 HS20_OUI_TYPE_SIZE)) )
15959 {
15960 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015961 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015962 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015963
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015964 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015965 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015966 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15967 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015968 VOS_ASSERT(0);
15969 return -ENOMEM;
15970 }
15971 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15972 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015973
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015974 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15975 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15976 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015977 /* Appending OSEN Information Element in Assiciation Request */
15978 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
15979 OSEN_OUI_TYPE_SIZE)) )
15980 {
15981 v_U16_t curAddIELen = pWextState->assocAddIE.length;
15982 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
15983 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015984
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015985 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015986 {
15987 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15988 "Need bigger buffer space");
15989 VOS_ASSERT(0);
15990 return -ENOMEM;
15991 }
15992 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15993 pWextState->assocAddIE.length += eLen + 2;
15994
15995 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
15996 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15997 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15998 }
15999
Abhishek Singh4322e622015-06-10 15:42:54 +053016000 /* Update only for WPA IE */
16001 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
16002 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016003
16004 /* populating as ADDIE in beacon frames */
16005 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016006 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016007 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
16008 {
16009 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16010 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
16011 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16012 {
16013 hddLog(LOGE,
16014 "Coldn't pass "
16015 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
16016 }
16017 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
16018 else
16019 hddLog(LOGE,
16020 "Could not pass on "
16021 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
16022
16023 /* IBSS mode doesn't contain params->proberesp_ies still
16024 beaconIE's need to be populated in probe response frames */
16025 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
16026 {
16027 u16 rem_probe_resp_ie_len = eLen + 2;
16028 u8 probe_rsp_ie_len[3] = {0};
16029 u8 counter = 0;
16030
16031 /* Check Probe Resp Length if it is greater then 255 then
16032 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
16033 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
16034 not able Store More then 255 bytes into One Variable */
16035
16036 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
16037 {
16038 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
16039 {
16040 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
16041 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
16042 }
16043 else
16044 {
16045 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
16046 rem_probe_resp_ie_len = 0;
16047 }
16048 }
16049
16050 rem_probe_resp_ie_len = 0;
16051
16052 if (probe_rsp_ie_len[0] > 0)
16053 {
16054 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16055 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
16056 (tANI_U8*)(genie - 2),
16057 probe_rsp_ie_len[0], NULL,
16058 eANI_BOOLEAN_FALSE)
16059 == eHAL_STATUS_FAILURE)
16060 {
16061 hddLog(LOGE,
16062 "Could not pass"
16063 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
16064 }
16065 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
16066 }
16067
16068 if (probe_rsp_ie_len[1] > 0)
16069 {
16070 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16071 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
16072 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16073 probe_rsp_ie_len[1], NULL,
16074 eANI_BOOLEAN_FALSE)
16075 == eHAL_STATUS_FAILURE)
16076 {
16077 hddLog(LOGE,
16078 "Could not pass"
16079 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
16080 }
16081 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
16082 }
16083
16084 if (probe_rsp_ie_len[2] > 0)
16085 {
16086 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16087 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
16088 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16089 probe_rsp_ie_len[2], NULL,
16090 eANI_BOOLEAN_FALSE)
16091 == eHAL_STATUS_FAILURE)
16092 {
16093 hddLog(LOGE,
16094 "Could not pass"
16095 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
16096 }
16097 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
16098 }
16099
16100 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16101 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
16102 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16103 {
16104 hddLog(LOGE,
16105 "Could not pass"
16106 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
16107 }
16108 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016109 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070016110 break;
16111 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053016112 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16113 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
16114 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
16115 VOS_ASSERT(0);
16116 return -EINVAL;
16117 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016118 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
16119 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16120 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
16121 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
16122 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16123 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016124
Abhishek Singhb16f3562016-01-20 11:08:32 +053016125 /* Appending extended capabilities with Interworking or
16126 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016127 *
16128 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016129 * interworkingService or bsstransition bit is set to 1.
16130 * Driver is only interested in interworkingService and
16131 * bsstransition capability from supplicant.
16132 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016133 * required from supplicat, it needs to be handled while
16134 * sending Assoc Req in LIM.
16135 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016136 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016137 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016138 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016139 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016140 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016141
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016142 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016143 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016144 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16145 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016146 VOS_ASSERT(0);
16147 return -ENOMEM;
16148 }
16149 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16150 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016151
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016152 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16153 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16154 break;
16155 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016156#ifdef FEATURE_WLAN_WAPI
16157 case WLAN_EID_WAPI:
16158 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016159 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016160 pAdapter->wapi_info.nWapiMode);
16161 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016162 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016163 akmsuiteCount = WPA_GET_LE16(tmp);
16164 tmp = tmp + 1;
16165 akmlist = (int *)(tmp);
16166 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16167 {
16168 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16169 }
16170 else
16171 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016172 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016173 VOS_ASSERT(0);
16174 return -EINVAL;
16175 }
16176
16177 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16178 {
16179 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016180 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016181 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016182 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016183 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016184 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016185 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016186 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016187 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
16188 }
16189 break;
16190#endif
16191 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016192 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016193 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016194 /* when Unknown IE is received we should break and continue
16195 * to the next IE in the buffer instead we were returning
16196 * so changing this to break */
16197 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016198 }
16199 genie += eLen;
16200 remLen -= eLen;
16201 }
16202 EXIT();
16203 return 0;
16204}
16205
16206/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016207 * FUNCTION: hdd_isWPAIEPresent
16208 * Parse the received IE to find the WPA IE
16209 *
16210 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016211static bool hdd_isWPAIEPresent(
16212#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16213 const u8 *ie,
16214#else
16215 u8 *ie,
16216#endif
16217 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016218{
16219 v_U8_t eLen = 0;
16220 v_U16_t remLen = ie_len;
16221 v_U8_t elementId = 0;
16222
16223 while (remLen >= 2)
16224 {
16225 elementId = *ie++;
16226 eLen = *ie++;
16227 remLen -= 2;
16228 if (eLen > remLen)
16229 {
16230 hddLog(VOS_TRACE_LEVEL_ERROR,
16231 "%s: IE length is wrong %d", __func__, eLen);
16232 return FALSE;
16233 }
16234 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16235 {
16236 /* OUI - 0x00 0X50 0XF2
16237 WPA Information Element - 0x01
16238 WPA version - 0x01*/
16239 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16240 return TRUE;
16241 }
16242 ie += eLen;
16243 remLen -= eLen;
16244 }
16245 return FALSE;
16246}
16247
16248/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016249 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016250 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016251 * parameters during connect operation.
16252 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016253int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016254 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016255 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016256{
16257 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016258 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016259 ENTER();
16260
16261 /*set wpa version*/
16262 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
16263
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016264 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016265 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053016266 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016267 {
16268 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16269 }
16270 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
16271 {
16272 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16273 }
16274 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016275
16276 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016277 pWextState->wpaVersion);
16278
16279 /*set authentication type*/
16280 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
16281
16282 if (0 > status)
16283 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016284 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016285 "%s: failed to set authentication type ", __func__);
16286 return status;
16287 }
16288
16289 /*set key mgmt type*/
16290 if (req->crypto.n_akm_suites)
16291 {
16292 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
16293 if (0 > status)
16294 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016295 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070016296 __func__);
16297 return status;
16298 }
16299 }
16300
16301 /*set pairwise cipher type*/
16302 if (req->crypto.n_ciphers_pairwise)
16303 {
16304 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
16305 req->crypto.ciphers_pairwise[0], true);
16306 if (0 > status)
16307 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016308 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016309 "%s: failed to set unicast cipher type", __func__);
16310 return status;
16311 }
16312 }
16313 else
16314 {
16315 /*Reset previous cipher suite to none*/
16316 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
16317 if (0 > status)
16318 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016319 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016320 "%s: failed to set unicast cipher type", __func__);
16321 return status;
16322 }
16323 }
16324
16325 /*set group cipher type*/
16326 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
16327 false);
16328
16329 if (0 > status)
16330 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016331 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070016332 __func__);
16333 return status;
16334 }
16335
Chet Lanctot186b5732013-03-18 10:26:30 -070016336#ifdef WLAN_FEATURE_11W
16337 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
16338#endif
16339
Jeff Johnson295189b2012-06-20 16:38:30 -070016340 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
16341 if (req->ie_len)
16342 {
16343 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
16344 if ( 0 > status)
16345 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016346 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016347 __func__);
16348 return status;
16349 }
16350 }
16351
16352 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016353 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016354 {
16355 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
16356 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
16357 )
16358 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016359 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070016360 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
16361 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016362 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016363 __func__);
16364 return -EOPNOTSUPP;
16365 }
16366 else
16367 {
16368 u8 key_len = req->key_len;
16369 u8 key_idx = req->key_idx;
16370
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016371 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016372 && (CSR_MAX_NUM_KEY > key_idx)
16373 )
16374 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016375 hddLog(VOS_TRACE_LEVEL_INFO,
16376 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016377 __func__, key_idx, key_len);
16378 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016379 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070016380 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016381 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016382 (u8)key_len;
16383 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
16384 }
16385 }
16386 }
16387 }
16388
16389 return status;
16390}
16391
16392/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016393 * FUNCTION: wlan_hdd_try_disconnect
16394 * This function is used to disconnect from previous
16395 * connection
16396 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053016397int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016398{
16399 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016400 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016401 hdd_station_ctx_t *pHddStaCtx;
16402 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016403 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016404
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016405 ret = wlan_hdd_validate_context(pHddCtx);
16406 if (0 != ret)
16407 {
16408 return ret;
16409 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016410 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16411
16412 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
16413
16414 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
16415 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053016416 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016417 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
16418 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053016419 /* Indicate disconnect to SME so that in-progress connection or preauth
16420 * can be aborted
16421 */
16422 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
16423 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016424 spin_lock_bh(&pAdapter->lock_for_active_session);
16425 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16426 {
16427 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16428 }
16429 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053016430 hdd_connSetConnectionState(pHddStaCtx,
16431 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016432 /* Issue disconnect to CSR */
16433 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016434 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016435 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016436 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16437 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
16438 hddLog(LOG1,
16439 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
16440 } else if ( 0 != status ) {
16441 hddLog(LOGE,
16442 FL("csrRoamDisconnect failure, returned %d"),
16443 (int)status );
16444 result = -EINVAL;
16445 goto disconnected;
16446 }
16447 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016448 &pAdapter->disconnect_comp_var,
16449 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016450 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
16451 hddLog(LOGE,
16452 "%s: Failed to disconnect, timed out", __func__);
16453 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016454 }
16455 }
16456 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
16457 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016458 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016459 &pAdapter->disconnect_comp_var,
16460 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016461 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016462 {
16463 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016464 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016465 }
16466 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016467disconnected:
16468 hddLog(LOG1,
16469 FL("Set HDD connState to eConnectionState_NotConnected"));
16470 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16471 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016472}
16473
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016474/**
16475 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16476 * @adapter: Pointer to the HDD adapter
16477 * @req: Pointer to the structure cfg_connect_params receieved from user space
16478 *
16479 * This function will start reassociation if bssid hint, channel hint and
16480 * previous bssid parameters are present in the connect request
16481 *
16482 * Return: success if reassociation is happening
16483 * Error code if reassociation is not permitted or not happening
16484 */
16485#ifdef CFG80211_CONNECT_PREV_BSSID
16486static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16487 struct cfg80211_connect_params *req)
16488{
16489 int status = -EPERM;
16490 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
16491 hddLog(VOS_TRACE_LEVEL_INFO,
16492 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
16493 req->channel_hint->hw_value,
16494 MAC_ADDR_ARRAY(req->bssid_hint));
16495 status = hdd_reassoc(adapter, req->bssid_hint,
16496 req->channel_hint->hw_value,
16497 CONNECT_CMD_USERSPACE);
16498 }
16499 return status;
16500}
16501#else
16502static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16503 struct cfg80211_connect_params *req)
16504{
16505 return -EPERM;
16506}
16507#endif
16508
Abhishek Singhe3beee22017-07-31 15:35:40 +053016509/**
16510 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
16511 * connect in HT20 mode
16512 * @hdd_ctx: hdd context
16513 * @adapter: Pointer to the HDD adapter
16514 * @req: Pointer to the structure cfg_connect_params receieved from user space
16515 *
16516 * This function will check if supplicant has indicated to to connect in HT20
16517 * mode. this is currently applicable only for 2.4Ghz mode only.
16518 * if feature is enabled and supplicant indicate HT20 set
16519 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
16520 *
16521 * Return: void
16522 */
16523#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
16524static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16525 hdd_adapter_t *adapter,
16526 struct cfg80211_connect_params *req)
16527{
16528 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16529 tCsrRoamProfile *roam_profile;
16530
16531 roam_profile = &wext_state->roamProfile;
16532 roam_profile->force_24ghz_in_ht20 = false;
16533 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
16534 !(req->ht_capa.cap_info &
16535 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
16536 roam_profile->force_24ghz_in_ht20 = true;
16537
16538 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
16539 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
16540}
16541#else
16542static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16543 hdd_adapter_t *adapter,
16544 struct cfg80211_connect_params *req)
16545{
16546 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16547 tCsrRoamProfile *roam_profile;
16548
16549 roam_profile = &wext_state->roamProfile;
16550 roam_profile->force_24ghz_in_ht20 = false;
16551}
16552#endif
16553
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016554/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053016555 * FUNCTION: __wlan_hdd_cfg80211_connect
16556 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070016557 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016558static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016559 struct net_device *ndev,
16560 struct cfg80211_connect_params *req
16561 )
16562{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016563 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016564 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053016565#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
16566 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016567 const u8 *bssid_hint = req->bssid_hint;
16568#else
16569 const u8 *bssid_hint = NULL;
16570#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016571 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016572 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053016573 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016574
16575 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016576
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016577 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16578 TRACE_CODE_HDD_CFG80211_CONNECT,
16579 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016580 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016581 "%s: device_mode = %s (%d)", __func__,
16582 hdd_device_modetoString(pAdapter->device_mode),
16583 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016584
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016585 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016586 if (!pHddCtx)
16587 {
16588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16589 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053016590 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016591 }
16592
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016593 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016594 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016595 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016596 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016597 }
16598
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053016599 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
16600 return -EINVAL;
16601
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016602 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
16603 if (0 == status)
16604 return status;
16605
Agarwal Ashish51325b52014-06-16 16:50:49 +053016606
Jeff Johnson295189b2012-06-20 16:38:30 -070016607#ifdef WLAN_BTAMP_FEATURE
16608 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016609 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070016610 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016611 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016612 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080016613 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070016614 }
16615#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016616
16617 //If Device Mode is Station Concurrent Sessions Exit BMps
16618 //P2P Mode will be taken care in Open/close adapter
16619 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053016620 (vos_concurrent_open_sessions_running())) {
16621 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
16622 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016623 }
16624
16625 /*Try disconnecting if already in connected state*/
16626 status = wlan_hdd_try_disconnect(pAdapter);
16627 if ( 0 > status)
16628 {
16629 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16630 " connection"));
16631 return -EALREADY;
16632 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053016633 /* Check for max concurrent connections after doing disconnect if any*/
16634 if (vos_max_concurrent_connections_reached()) {
16635 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16636 return -ECONNREFUSED;
16637 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016638
Jeff Johnson295189b2012-06-20 16:38:30 -070016639 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016640 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070016641
16642 if ( 0 > status)
16643 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016644 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070016645 __func__);
16646 return status;
16647 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053016648
16649 if (pHddCtx->spoofMacAddr.isEnabled)
16650 {
16651 hddLog(VOS_TRACE_LEVEL_INFO,
16652 "%s: MAC Spoofing enabled ", __func__);
16653 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
16654 * to fill TxBds for probe request during SSID scan which may happen
16655 * as part of connect command
16656 */
16657 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
16658 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
16659 if (status != VOS_STATUS_SUCCESS)
16660 return -ECONNREFUSED;
16661 }
16662
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016663 if (req->channel)
16664 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070016665 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016666 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053016667
16668 /* Abort if any scan is going on */
16669 status = wlan_hdd_scan_abort(pAdapter);
16670 if (0 != status)
16671 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
16672
Abhishek Singhe3beee22017-07-31 15:35:40 +053016673 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
16674
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016675 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
16676 req->ssid_len, req->bssid,
16677 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016678
Sushant Kaushikd7083982015-03-18 14:33:24 +053016679 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016680 {
16681 //ReEnable BMPS if disabled
16682 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
16683 (NULL != pHddCtx))
16684 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053016685 if (pHddCtx->hdd_wlan_suspended)
16686 {
16687 hdd_set_pwrparams(pHddCtx);
16688 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016689 //ReEnable Bmps and Imps back
16690 hdd_enable_bmps_imps(pHddCtx);
16691 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053016692 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070016693 return status;
16694 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016695 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016696 EXIT();
16697 return status;
16698}
16699
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016700static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
16701 struct net_device *ndev,
16702 struct cfg80211_connect_params *req)
16703{
16704 int ret;
16705 vos_ssr_protect(__func__);
16706 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
16707 vos_ssr_unprotect(__func__);
16708
16709 return ret;
16710}
Jeff Johnson295189b2012-06-20 16:38:30 -070016711
16712/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016713 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070016714 * This function is used to issue a disconnect request to SME
16715 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016716static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016717 struct net_device *dev,
16718 u16 reason
16719 )
16720{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016721 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016722 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016723 tCsrRoamProfile *pRoamProfile;
16724 hdd_station_ctx_t *pHddStaCtx;
16725 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016726#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016727 tANI_U8 staIdx;
16728#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016729
Jeff Johnson295189b2012-06-20 16:38:30 -070016730 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016731
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016732 if (!pAdapter) {
16733 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16734 return -EINVAL;
16735 }
16736
16737 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16738 if (!pHddStaCtx) {
16739 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
16740 return -EINVAL;
16741 }
16742
16743 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16744 status = wlan_hdd_validate_context(pHddCtx);
16745 if (0 != status)
16746 {
16747 return status;
16748 }
16749
16750 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
16751
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016752 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16753 TRACE_CODE_HDD_CFG80211_DISCONNECT,
16754 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016755 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
16756 __func__, hdd_device_modetoString(pAdapter->device_mode),
16757 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016758
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016759 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
16760 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070016761
Jeff Johnson295189b2012-06-20 16:38:30 -070016762 if (NULL != pRoamProfile)
16763 {
16764 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053016765 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
16766 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070016767 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016768 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070016769 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016770 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070016771 switch(reason)
16772 {
16773 case WLAN_REASON_MIC_FAILURE:
16774 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
16775 break;
16776
16777 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
16778 case WLAN_REASON_DISASSOC_AP_BUSY:
16779 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
16780 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
16781 break;
16782
16783 case WLAN_REASON_PREV_AUTH_NOT_VALID:
16784 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053016785 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070016786 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
16787 break;
16788
Jeff Johnson295189b2012-06-20 16:38:30 -070016789 default:
16790 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
16791 break;
16792 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016793 pScanInfo = &pHddCtx->scan_info;
16794 if (pScanInfo->mScanPending)
16795 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016796 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016797 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053016798 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016799 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016800 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053016801 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016802#ifdef FEATURE_WLAN_TDLS
16803 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016804 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016805 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016806 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
16807 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016808 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016809 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016810 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016811 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016812 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016813 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016814 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016815 status = sme_DeleteTdlsPeerSta(
16816 WLAN_HDD_GET_HAL_CTX(pAdapter),
16817 pAdapter->sessionId,
16818 mac);
16819 if (status != eHAL_STATUS_SUCCESS) {
16820 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16821 return -EPERM;
16822 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016823 }
16824 }
16825#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016826
16827 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
16828 reasonCode,
16829 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016830 status = wlan_hdd_disconnect(pAdapter, reasonCode);
16831 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070016832 {
16833 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016834 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016835 __func__, (int)status );
16836 return -EINVAL;
16837 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016838 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053016839 else
16840 {
16841 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
16842 "called while in %d state", __func__,
16843 pHddStaCtx->conn_info.connState);
16844 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016845 }
16846 else
16847 {
16848 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
16849 }
16850
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016851 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016852 return status;
16853}
16854
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016855static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
16856 struct net_device *dev,
16857 u16 reason
16858 )
16859{
16860 int ret;
16861 vos_ssr_protect(__func__);
16862 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
16863 vos_ssr_unprotect(__func__);
16864
16865 return ret;
16866}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016867
Jeff Johnson295189b2012-06-20 16:38:30 -070016868/*
16869 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016870 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016871 * settings in IBSS mode.
16872 */
16873static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016874 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016875 struct cfg80211_ibss_params *params
16876 )
16877{
16878 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016879 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016880 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16881 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016882
Jeff Johnson295189b2012-06-20 16:38:30 -070016883 ENTER();
16884
16885 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070016886 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070016887
16888 if (params->ie_len && ( NULL != params->ie) )
16889 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016890 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16891 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016892 {
16893 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16894 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16895 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016896 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016897 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016898 tDot11fIEWPA dot11WPAIE;
16899 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016900 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016901
Wilson Yang00256342013-10-10 23:13:38 -070016902 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016903 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16904 params->ie_len, DOT11F_EID_WPA);
16905 if ( NULL != ie )
16906 {
16907 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16908 // Unpack the WPA IE
16909 //Skip past the EID byte and length byte - and four byte WiFi OUI
16910 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
16911 &ie[2+4],
16912 ie[1] - 4,
16913 &dot11WPAIE);
16914 /*Extract the multicast cipher, the encType for unicast
16915 cipher for wpa-none is none*/
16916 encryptionType =
16917 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
16918 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016919 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016920
Jeff Johnson295189b2012-06-20 16:38:30 -070016921 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
16922
16923 if (0 > status)
16924 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016925 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016926 __func__);
16927 return status;
16928 }
16929 }
16930
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016931 pWextState->roamProfile.AuthType.authType[0] =
16932 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070016933 eCSR_AUTH_TYPE_OPEN_SYSTEM;
Jeff Johnson295189b2012-06-20 16:38:30 -070016934 if (params->privacy)
16935 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016936 /* Security enabled IBSS, At this time there is no information available
16937 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070016938 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016939 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070016940 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016941 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070016942 *enable privacy bit in beacons */
16943
16944 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
16945 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016946 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
16947 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070016948 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16949 pWextState->roamProfile.EncryptionType.numEntries = 1;
16950 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070016951 return status;
16952}
16953
16954/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016955 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016956 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016957 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016958static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016959 struct net_device *dev,
16960 struct cfg80211_ibss_params *params
16961 )
16962{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016963 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016964 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16965 tCsrRoamProfile *pRoamProfile;
16966 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016967 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16968 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016969 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070016970
16971 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016972
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016973 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16974 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
16975 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016976 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016977 "%s: device_mode = %s (%d)", __func__,
16978 hdd_device_modetoString(pAdapter->device_mode),
16979 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016980
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016981 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016982 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016983 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016984 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016985 }
16986
16987 if (NULL == pWextState)
16988 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016989 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016990 __func__);
16991 return -EIO;
16992 }
16993
Agarwal Ashish51325b52014-06-16 16:50:49 +053016994 if (vos_max_concurrent_connections_reached()) {
16995 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16996 return -ECONNREFUSED;
16997 }
16998
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016999 /*Try disconnecting if already in connected state*/
17000 status = wlan_hdd_try_disconnect(pAdapter);
17001 if ( 0 > status)
17002 {
17003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17004 " IBSS connection"));
17005 return -EALREADY;
17006 }
17007
Jeff Johnson295189b2012-06-20 16:38:30 -070017008 pRoamProfile = &pWextState->roamProfile;
17009
17010 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
17011 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017012 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017013 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017014 return -EINVAL;
17015 }
17016
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017017 /* BSSID is provided by upper layers hence no need to AUTO generate */
17018 if (NULL != params->bssid) {
17019 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17020 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
17021 hddLog (VOS_TRACE_LEVEL_ERROR,
17022 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17023 return -EIO;
17024 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017025 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017026 }
krunal sonie9002db2013-11-25 14:24:17 -080017027 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
17028 {
17029 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17030 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
17031 {
17032 hddLog (VOS_TRACE_LEVEL_ERROR,
17033 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17034 return -EIO;
17035 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017036
17037 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080017038 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017039 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080017040 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017041
Jeff Johnson295189b2012-06-20 16:38:30 -070017042 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070017043 if (NULL !=
17044#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17045 params->chandef.chan)
17046#else
17047 params->channel)
17048#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017049 {
17050 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017051 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17052 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
17053 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17054 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017055
17056 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017057 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070017058 ieee80211_frequency_to_channel(
17059#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17060 params->chandef.chan->center_freq);
17061#else
17062 params->channel->center_freq);
17063#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017064
17065 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17066 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070017067 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017068 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
17069 __func__);
17070 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070017071 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017072
17073 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017074 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017075 if (channelNum == validChan[indx])
17076 {
17077 break;
17078 }
17079 }
17080 if (indx >= numChans)
17081 {
17082 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017083 __func__, channelNum);
17084 return -EINVAL;
17085 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017086 /* Set the Operational Channel */
17087 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
17088 channelNum);
17089 pRoamProfile->ChannelInfo.numOfChannels = 1;
17090 pHddStaCtx->conn_info.operationChannel = channelNum;
17091 pRoamProfile->ChannelInfo.ChannelList =
17092 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070017093 }
17094
17095 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017096 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070017097 if (status < 0)
17098 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017099 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070017100 __func__);
17101 return status;
17102 }
17103
17104 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017105 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053017106 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017107 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017108
17109 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017110 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017111
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017112 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017113 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017114}
17115
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017116static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17117 struct net_device *dev,
17118 struct cfg80211_ibss_params *params
17119 )
17120{
17121 int ret = 0;
17122
17123 vos_ssr_protect(__func__);
17124 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17125 vos_ssr_unprotect(__func__);
17126
17127 return ret;
17128}
17129
Jeff Johnson295189b2012-06-20 16:38:30 -070017130/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017131 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017132 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017133 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017134static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017135 struct net_device *dev
17136 )
17137{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017138 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017139 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17140 tCsrRoamProfile *pRoamProfile;
17141 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017142 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017143 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017144#ifdef WLAN_FEATURE_RMC
17145 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17146#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017147
17148 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017149
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017150 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17151 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17152 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017153 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017154 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017155 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017156 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017157 }
17158
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017159 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17160 hdd_device_modetoString(pAdapter->device_mode),
17161 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017162 if (NULL == pWextState)
17163 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017164 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017165 __func__);
17166 return -EIO;
17167 }
17168
17169 pRoamProfile = &pWextState->roamProfile;
17170
17171 /* Issue disconnect only if interface type is set to IBSS */
17172 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17173 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017174 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017175 __func__);
17176 return -EINVAL;
17177 }
17178
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017179#ifdef WLAN_FEATURE_RMC
17180 /* Clearing add IE of beacon */
17181 if (ccmCfgSetStr(pHddCtx->hHal,
17182 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17183 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17184 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17185 {
17186 hddLog (VOS_TRACE_LEVEL_ERROR,
17187 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17188 return -EINVAL;
17189 }
17190 if (ccmCfgSetInt(pHddCtx->hHal,
17191 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17192 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17193 {
17194 hddLog (VOS_TRACE_LEVEL_ERROR,
17195 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17196 __func__);
17197 return -EINVAL;
17198 }
17199
17200 // Reset WNI_CFG_PROBE_RSP Flags
17201 wlan_hdd_reset_prob_rspies(pAdapter);
17202
17203 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17204 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17205 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17206 {
17207 hddLog (VOS_TRACE_LEVEL_ERROR,
17208 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17209 __func__);
17210 return -EINVAL;
17211 }
17212#endif
17213
Jeff Johnson295189b2012-06-20 16:38:30 -070017214 /* Issue Disconnect request */
17215 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017216 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17217 pAdapter->sessionId,
17218 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17219 if (!HAL_STATUS_SUCCESS(hal_status)) {
17220 hddLog(LOGE,
17221 FL("sme_RoamDisconnect failed hal_status(%d)"),
17222 hal_status);
17223 return -EAGAIN;
17224 }
17225 status = wait_for_completion_timeout(
17226 &pAdapter->disconnect_comp_var,
17227 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17228 if (!status) {
17229 hddLog(LOGE,
17230 FL("wait on disconnect_comp_var failed"));
17231 return -ETIMEDOUT;
17232 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017233
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017234 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017235 return 0;
17236}
17237
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017238static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17239 struct net_device *dev
17240 )
17241{
17242 int ret = 0;
17243
17244 vos_ssr_protect(__func__);
17245 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17246 vos_ssr_unprotect(__func__);
17247
17248 return ret;
17249}
17250
Jeff Johnson295189b2012-06-20 16:38:30 -070017251/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017252 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017253 * This function is used to set the phy parameters
17254 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17255 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017256static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017257 u32 changed)
17258{
17259 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17260 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017261 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017262
17263 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017264
17265 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017266 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17267 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017268
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017269 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017270 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017271 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017272 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017273 }
17274
Jeff Johnson295189b2012-06-20 16:38:30 -070017275 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17276 {
17277 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17278 WNI_CFG_RTS_THRESHOLD_STAMAX :
17279 wiphy->rts_threshold;
17280
17281 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017282 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017283 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017284 hddLog(VOS_TRACE_LEVEL_ERROR,
17285 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017286 __func__, rts_threshold);
17287 return -EINVAL;
17288 }
17289
17290 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17291 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017292 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017293 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017294 hddLog(VOS_TRACE_LEVEL_ERROR,
17295 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017296 __func__, rts_threshold);
17297 return -EIO;
17298 }
17299
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017300 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017301 rts_threshold);
17302 }
17303
17304 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17305 {
17306 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17307 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17308 wiphy->frag_threshold;
17309
17310 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017311 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017312 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017313 hddLog(VOS_TRACE_LEVEL_ERROR,
17314 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017315 frag_threshold);
17316 return -EINVAL;
17317 }
17318
17319 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
17320 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017321 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017322 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017323 hddLog(VOS_TRACE_LEVEL_ERROR,
17324 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017325 __func__, frag_threshold);
17326 return -EIO;
17327 }
17328
17329 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
17330 frag_threshold);
17331 }
17332
17333 if ((changed & WIPHY_PARAM_RETRY_SHORT)
17334 || (changed & WIPHY_PARAM_RETRY_LONG))
17335 {
17336 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
17337 wiphy->retry_short :
17338 wiphy->retry_long;
17339
17340 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17341 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17342 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017343 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017344 __func__, retry_value);
17345 return -EINVAL;
17346 }
17347
17348 if (changed & WIPHY_PARAM_RETRY_SHORT)
17349 {
17350 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17351 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017352 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017353 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017354 hddLog(VOS_TRACE_LEVEL_ERROR,
17355 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017356 __func__, retry_value);
17357 return -EIO;
17358 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017359 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017360 __func__, retry_value);
17361 }
17362 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17363 {
17364 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17365 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017366 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017367 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017368 hddLog(VOS_TRACE_LEVEL_ERROR,
17369 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017370 __func__, retry_value);
17371 return -EIO;
17372 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017373 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017374 __func__, retry_value);
17375 }
17376 }
17377
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017378 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017379 return 0;
17380}
17381
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017382static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17383 u32 changed)
17384{
17385 int ret;
17386
17387 vos_ssr_protect(__func__);
17388 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17389 vos_ssr_unprotect(__func__);
17390
17391 return ret;
17392}
17393
Jeff Johnson295189b2012-06-20 16:38:30 -070017394/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017395 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017396 * This function is used to set the txpower
17397 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017398static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017399#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17400 struct wireless_dev *wdev,
17401#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017402#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017403 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017404#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017405 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017406#endif
17407 int dbm)
17408{
17409 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017410 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017411 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17412 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017413 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017414
17415 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017416
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017417 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17418 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17419 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017420 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017421 if (0 != status)
17422 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017423 return status;
17424 }
17425
17426 hHal = pHddCtx->hHal;
17427
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017428 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17429 dbm, ccmCfgSetCallback,
17430 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017431 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017432 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017433 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17434 return -EIO;
17435 }
17436
17437 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17438 dbm);
17439
17440 switch(type)
17441 {
17442 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17443 /* Fall through */
17444 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17445 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17446 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017447 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17448 __func__);
17449 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017450 }
17451 break;
17452 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017453 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017454 __func__);
17455 return -EOPNOTSUPP;
17456 break;
17457 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017458 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17459 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017460 return -EIO;
17461 }
17462
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017463 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017464 return 0;
17465}
17466
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017467static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17468#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17469 struct wireless_dev *wdev,
17470#endif
17471#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17472 enum tx_power_setting type,
17473#else
17474 enum nl80211_tx_power_setting type,
17475#endif
17476 int dbm)
17477{
17478 int ret;
17479 vos_ssr_protect(__func__);
17480 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17481#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17482 wdev,
17483#endif
17484#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17485 type,
17486#else
17487 type,
17488#endif
17489 dbm);
17490 vos_ssr_unprotect(__func__);
17491
17492 return ret;
17493}
17494
Jeff Johnson295189b2012-06-20 16:38:30 -070017495/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017496 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017497 * This function is used to read the txpower
17498 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017499static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017500#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17501 struct wireless_dev *wdev,
17502#endif
17503 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070017504{
17505
17506 hdd_adapter_t *pAdapter;
17507 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017508 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017509
Jeff Johnsone7245742012-09-05 17:12:55 -070017510 ENTER();
17511
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017512 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017513 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017514 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017515 *dbm = 0;
17516 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017517 }
17518
Jeff Johnson295189b2012-06-20 16:38:30 -070017519 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
17520 if (NULL == pAdapter)
17521 {
17522 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
17523 return -ENOENT;
17524 }
17525
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017526 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17527 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
17528 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070017529 wlan_hdd_get_classAstats(pAdapter);
17530 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
17531
Jeff Johnsone7245742012-09-05 17:12:55 -070017532 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017533 return 0;
17534}
17535
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017536static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
17537#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17538 struct wireless_dev *wdev,
17539#endif
17540 int *dbm)
17541{
17542 int ret;
17543
17544 vos_ssr_protect(__func__);
17545 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
17546#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17547 wdev,
17548#endif
17549 dbm);
17550 vos_ssr_unprotect(__func__);
17551
17552 return ret;
17553}
17554
Dustin Brown8c1d4092017-07-28 18:08:01 +053017555/*
17556 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
17557 * @stats: summary stats to use as a source
17558 * @info: kernel station_info struct to use as a destination
17559 *
17560 * Return: None
17561 */
17562static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
17563 struct station_info *info)
17564{
17565 int i;
17566
17567 info->rx_packets = stats->rx_frm_cnt;
17568 info->tx_packets = 0;
17569 info->tx_retries = 0;
17570 info->tx_failed = 0;
17571
17572 for (i = 0; i < 4; ++i) {
17573 info->tx_packets += stats->tx_frm_cnt[i];
17574 info->tx_retries += stats->multiple_retry_cnt[i];
17575 info->tx_failed += stats->fail_cnt[i];
17576 }
17577
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017578#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
17579 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017580 info->filled |= STATION_INFO_TX_PACKETS |
17581 STATION_INFO_TX_RETRIES |
17582 STATION_INFO_TX_FAILED |
17583 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017584#else
17585 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
17586 BIT(NL80211_STA_INFO_TX_RETRIES) |
17587 BIT(NL80211_STA_INFO_TX_FAILED) |
17588 BIT(NL80211_STA_INFO_RX_PACKETS);
17589#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053017590}
17591
17592/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017593 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
17594 * @adapter: sap adapter pointer
17595 * @staid: station id of the client
17596 * @rssi: rssi value to fill
17597 *
17598 * Return: None
17599 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053017600void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017601wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
17602{
17603 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
17604
17605 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
17606}
17607
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017608#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
17609 !defined(WITH_BACKPORTS)
17610static inline void wlan_hdd_fill_station_info_signal(struct station_info
17611 *sinfo)
17612{
17613 sinfo->filled |= STATION_INFO_SIGNAL;
17614}
17615#else
17616static inline void wlan_hdd_fill_station_info_signal(struct station_info
17617 *sinfo)
17618{
17619 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
17620}
17621#endif
17622
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017623/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053017624 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
17625 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017626 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053017627 * @info: kernel station_info struct to populate
17628 *
17629 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
17630 * support "station dump" and "station get" for SAP vdevs, even though they
17631 * aren't technically stations.
17632 *
17633 * Return: errno
17634 */
17635static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017636wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
17637#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17638 const u8* mac,
17639#else
17640 u8* mac,
17641#endif
17642 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017643{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017644 v_MACADDR_t *peerMacAddr;
17645 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017646 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017647 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017648
17649 status = wlan_hdd_get_station_stats(adapter);
17650 if (!VOS_IS_STATUS_SUCCESS(status)) {
17651 hddLog(VOS_TRACE_LEVEL_ERROR,
17652 "Failed to get SAP stats; status:%d", status);
17653 return 0;
17654 }
17655
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017656 peerMacAddr = (v_MACADDR_t *)mac;
17657 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
17658 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
17659 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
17660
17661 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
17662 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017663 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017664 }
17665
Dustin Brown8c1d4092017-07-28 18:08:01 +053017666 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
17667
17668 return 0;
17669}
17670
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017671static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017672#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17673 const u8* mac,
17674#else
17675 u8* mac,
17676#endif
17677 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070017678{
17679 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
17680 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17681 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053017682 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017683
17684 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
17685 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070017686
17687 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
17688 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
17689 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
17690 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
17691 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
17692 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
17693 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017694 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017695 tANI_U16 myRate;
17696 tANI_U16 currentRate = 0;
17697 tANI_U8 maxSpeedMCS = 0;
17698 tANI_U8 maxMCSIdx = 0;
17699 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053017700 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070017701 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017702 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017703
Leo Chang6f8870f2013-03-26 18:11:36 -070017704#ifdef WLAN_FEATURE_11AC
17705 tANI_U32 vht_mcs_map;
17706 eDataRate11ACMaxMcs vhtMaxMcs;
17707#endif /* WLAN_FEATURE_11AC */
17708
Jeff Johnsone7245742012-09-05 17:12:55 -070017709 ENTER();
17710
Dustin Brown8c1d4092017-07-28 18:08:01 +053017711 status = wlan_hdd_validate_context(pHddCtx);
17712 if (0 != status)
17713 {
17714 return status;
17715 }
17716
17717 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017718 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053017719
Jeff Johnson295189b2012-06-20 16:38:30 -070017720 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17721 (0 == ssidlen))
17722 {
17723 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
17724 " Invalid ssidlen, %d", __func__, ssidlen);
17725 /*To keep GUI happy*/
17726 return 0;
17727 }
17728
Mukul Sharma811205f2014-07-09 21:07:30 +053017729 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17730 {
17731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17732 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053017733 /* return a cached value */
17734 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053017735 return 0;
17736 }
17737
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053017738 wlan_hdd_get_station_stats(pAdapter);
17739 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017740
Kiet Lam3b17fc82013-09-27 05:24:08 +053017741 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017742 wlan_hdd_get_snr(pAdapter, &snr);
17743 pHddStaCtx->conn_info.signal = sinfo->signal;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053017744 pHddStaCtx->cache_conn_info.signal = sinfo->signal;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017745 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053017746 pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017747 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053017748
c_hpothu09f19542014-05-30 21:53:31 +053017749 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053017750 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
17751 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053017752 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053017753 {
17754 rate_flags = pAdapter->maxRateFlags;
17755 }
c_hpothu44ff4e02014-05-08 00:13:57 +053017756
Jeff Johnson295189b2012-06-20 16:38:30 -070017757 //convert to the UI units of 100kbps
17758 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
17759
17760#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070017761 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 -070017762 sinfo->signal,
17763 pCfg->reportMaxLinkSpeed,
17764 myRate,
17765 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017766 (int) pCfg->linkSpeedRssiMid,
17767 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070017768 (int) rate_flags,
17769 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070017770#endif //LINKSPEED_DEBUG_ENABLED
17771
17772 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
17773 {
17774 // we do not want to necessarily report the current speed
17775 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
17776 {
17777 // report the max possible speed
17778 rssidx = 0;
17779 }
17780 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
17781 {
17782 // report the max possible speed with RSSI scaling
17783 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
17784 {
17785 // report the max possible speed
17786 rssidx = 0;
17787 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017788 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070017789 {
17790 // report middle speed
17791 rssidx = 1;
17792 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017793 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
17794 {
17795 // report middle speed
17796 rssidx = 2;
17797 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017798 else
17799 {
17800 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017801 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070017802 }
17803 }
17804 else
17805 {
17806 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
17807 hddLog(VOS_TRACE_LEVEL_ERROR,
17808 "%s: Invalid value for reportMaxLinkSpeed: %u",
17809 __func__, pCfg->reportMaxLinkSpeed);
17810 rssidx = 0;
17811 }
17812
17813 maxRate = 0;
17814
17815 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017816 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
17817 OperationalRates, &ORLeng))
17818 {
17819 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17820 /*To keep GUI happy*/
17821 return 0;
17822 }
17823
Jeff Johnson295189b2012-06-20 16:38:30 -070017824 for (i = 0; i < ORLeng; i++)
17825 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017826 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017827 {
17828 /* Validate Rate Set */
17829 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
17830 {
17831 currentRate = supported_data_rate[j].supported_rate[rssidx];
17832 break;
17833 }
17834 }
17835 /* Update MAX rate */
17836 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17837 }
17838
17839 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017840 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
17841 ExtendedRates, &ERLeng))
17842 {
17843 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17844 /*To keep GUI happy*/
17845 return 0;
17846 }
17847
Jeff Johnson295189b2012-06-20 16:38:30 -070017848 for (i = 0; i < ERLeng; i++)
17849 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017850 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017851 {
17852 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
17853 {
17854 currentRate = supported_data_rate[j].supported_rate[rssidx];
17855 break;
17856 }
17857 }
17858 /* Update MAX rate */
17859 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17860 }
c_hpothu79aab322014-07-14 21:11:01 +053017861
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017862 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053017863 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017864 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053017865 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070017866 {
c_hpothu79aab322014-07-14 21:11:01 +053017867 if (rate_flags & eHAL_TX_RATE_VHT80)
17868 mode = 2;
17869 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
17870 mode = 1;
17871 else
17872 mode = 0;
17873
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017874 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
17875 MCSRates, &MCSLeng))
17876 {
17877 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17878 /*To keep GUI happy*/
17879 return 0;
17880 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017881 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070017882#ifdef WLAN_FEATURE_11AC
17883 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017884 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070017885 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017886 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017887 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070017888 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070017889 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017890 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017891 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017892 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070017893 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017894 maxMCSIdx = 7;
17895 }
17896 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
17897 {
17898 maxMCSIdx = 8;
17899 }
17900 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
17901 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017902 //VHT20 is supporting 0~8
17903 if (rate_flags & eHAL_TX_RATE_VHT20)
17904 maxMCSIdx = 8;
17905 else
17906 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070017907 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017908
c_hpothu79aab322014-07-14 21:11:01 +053017909 if (0 != rssidx)/*check for scaled */
17910 {
17911 //get middle rate MCS index if rssi=1/2
17912 for (i=0; i <= maxMCSIdx; i++)
17913 {
17914 if (sinfo->signal <= rssiMcsTbl[mode][i])
17915 {
17916 maxMCSIdx = i;
17917 break;
17918 }
17919 }
17920 }
17921
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017922 if (rate_flags & eHAL_TX_RATE_VHT80)
17923 {
17924 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
17925 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
17926 }
17927 else if (rate_flags & eHAL_TX_RATE_VHT40)
17928 {
17929 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
17930 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
17931 }
17932 else if (rate_flags & eHAL_TX_RATE_VHT20)
17933 {
17934 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
17935 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
17936 }
17937
Leo Chang6f8870f2013-03-26 18:11:36 -070017938 maxSpeedMCS = 1;
17939 if (currentRate > maxRate)
17940 {
17941 maxRate = currentRate;
17942 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017943
Leo Chang6f8870f2013-03-26 18:11:36 -070017944 }
17945 else
17946#endif /* WLAN_FEATURE_11AC */
17947 {
17948 if (rate_flags & eHAL_TX_RATE_HT40)
17949 {
17950 rateFlag |= 1;
17951 }
17952 if (rate_flags & eHAL_TX_RATE_SGI)
17953 {
17954 rateFlag |= 2;
17955 }
17956
Girish Gowli01abcee2014-07-31 20:18:55 +053017957 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053017958 if (rssidx == 1 || rssidx == 2)
17959 {
17960 //get middle rate MCS index if rssi=1/2
17961 for (i=0; i <= 7; i++)
17962 {
17963 if (sinfo->signal <= rssiMcsTbl[mode][i])
17964 {
17965 temp = i+1;
17966 break;
17967 }
17968 }
17969 }
c_hpothu79aab322014-07-14 21:11:01 +053017970
17971 for (i = 0; i < MCSLeng; i++)
17972 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017973 for (j = 0; j < temp; j++)
17974 {
17975 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
17976 {
17977 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017978 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017979 break;
17980 }
17981 }
17982 if ((j < temp) && (currentRate > maxRate))
17983 {
17984 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070017985 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017986 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017987 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017988 }
17989 }
17990
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017991 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
17992 {
17993 maxRate = myRate;
17994 maxSpeedMCS = 1;
17995 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17996 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017997 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053017998 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070017999 {
18000 maxRate = myRate;
18001 if (rate_flags & eHAL_TX_RATE_LEGACY)
18002 {
18003 maxSpeedMCS = 0;
18004 }
18005 else
18006 {
18007 maxSpeedMCS = 1;
18008 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18009 }
18010 }
18011
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018012 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070018013 {
18014 sinfo->txrate.legacy = maxRate;
18015#ifdef LINKSPEED_DEBUG_ENABLED
18016 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
18017#endif //LINKSPEED_DEBUG_ENABLED
18018 }
18019 else
18020 {
18021 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070018022#ifdef WLAN_FEATURE_11AC
18023 sinfo->txrate.nss = 1;
18024 if (rate_flags & eHAL_TX_RATE_VHT80)
18025 {
18026 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018027#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18028 defined(WITH_BACKPORTS)
18029 sinfo->txrate.bw = RATE_INFO_BW_80;
18030#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018031 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018032#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018033 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018034 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070018035 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018036 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018037#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18038 defined(WITH_BACKPORTS)
18039 sinfo->txrate.bw = RATE_INFO_BW_40;
18040#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018041 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018042#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018043 }
18044 else if (rate_flags & eHAL_TX_RATE_VHT20)
18045 {
18046 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18047 }
18048#endif /* WLAN_FEATURE_11AC */
18049 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
18050 {
18051 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18052 if (rate_flags & eHAL_TX_RATE_HT40)
18053 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018054#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18055 defined(WITH_BACKPORTS)
18056 sinfo->txrate.bw = RATE_INFO_BW_40;
18057#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018058 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018059#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018060 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018061 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018062 if (rate_flags & eHAL_TX_RATE_SGI)
18063 {
18064 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18065 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018066
Jeff Johnson295189b2012-06-20 16:38:30 -070018067#ifdef LINKSPEED_DEBUG_ENABLED
18068 pr_info("Reporting MCS rate %d flags %x\n",
18069 sinfo->txrate.mcs,
18070 sinfo->txrate.flags );
18071#endif //LINKSPEED_DEBUG_ENABLED
18072 }
18073 }
18074 else
18075 {
18076 // report current rate instead of max rate
18077
18078 if (rate_flags & eHAL_TX_RATE_LEGACY)
18079 {
18080 //provide to the UI in units of 100kbps
18081 sinfo->txrate.legacy = myRate;
18082#ifdef LINKSPEED_DEBUG_ENABLED
18083 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
18084#endif //LINKSPEED_DEBUG_ENABLED
18085 }
18086 else
18087 {
18088 //must be MCS
18089 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018090#ifdef WLAN_FEATURE_11AC
18091 sinfo->txrate.nss = 1;
18092 if (rate_flags & eHAL_TX_RATE_VHT80)
18093 {
18094 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18095 }
18096 else
18097#endif /* WLAN_FEATURE_11AC */
18098 {
18099 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18100 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018101 if (rate_flags & eHAL_TX_RATE_SGI)
18102 {
18103 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18104 }
18105 if (rate_flags & eHAL_TX_RATE_HT40)
18106 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018107#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18108 defined(WITH_BACKPORTS)
18109 sinfo->txrate.bw = RATE_INFO_BW_40;
18110#else
Jeff Johnson295189b2012-06-20 16:38:30 -070018111 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018112#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018113 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018114#ifdef WLAN_FEATURE_11AC
18115 else if (rate_flags & eHAL_TX_RATE_VHT80)
18116 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018117#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18118 defined(WITH_BACKPORTS)
18119 sinfo->txrate.bw = RATE_INFO_BW_80;
18120#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018121 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018122#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018123 }
18124#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018125#ifdef LINKSPEED_DEBUG_ENABLED
18126 pr_info("Reporting actual MCS rate %d flags %x\n",
18127 sinfo->txrate.mcs,
18128 sinfo->txrate.flags );
18129#endif //LINKSPEED_DEBUG_ENABLED
18130 }
18131 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018132
18133#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18134 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018135 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018136#else
18137 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18138#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018139
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018140 sinfo->tx_packets =
18141 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18142 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18143 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18144 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18145
18146 sinfo->tx_retries =
18147 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18148 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18149 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18150 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18151
18152 sinfo->tx_failed =
18153 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18154 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18155 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18156 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18157
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018158#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18159 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018160 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018161 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018162 STATION_INFO_TX_PACKETS |
18163 STATION_INFO_TX_RETRIES |
18164 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018165#else
18166 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18167 BIT(NL80211_STA_INFO_TX_PACKETS) |
18168 BIT(NL80211_STA_INFO_TX_RETRIES) |
18169 BIT(NL80211_STA_INFO_TX_FAILED);
18170#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018171
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018172 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018173
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018174 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18175 &sinfo->txrate, sizeof(sinfo->txrate));
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018176 vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate,
18177 &sinfo->txrate, sizeof(sinfo->txrate));
18178
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018179 if (rate_flags & eHAL_TX_RATE_LEGACY)
18180 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18181 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18182 sinfo->rx_packets);
18183 else
18184 hddLog(LOG1,
18185 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18186 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18187 sinfo->tx_packets, sinfo->rx_packets);
18188
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018189 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18190 TRACE_CODE_HDD_CFG80211_GET_STA,
18191 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018192 EXIT();
18193 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018194}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018195#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18196static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18197 const u8* mac, struct station_info *sinfo)
18198#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018199static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18200 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018201#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018202{
18203 int ret;
18204
18205 vos_ssr_protect(__func__);
18206 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18207 vos_ssr_unprotect(__func__);
18208
18209 return ret;
18210}
18211
18212static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018213 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018214{
18215 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018216 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018217 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018218 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018219
Jeff Johnsone7245742012-09-05 17:12:55 -070018220 ENTER();
18221
Jeff Johnson295189b2012-06-20 16:38:30 -070018222 if (NULL == pAdapter)
18223 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018224 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018225 return -ENODEV;
18226 }
18227
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018228 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18229 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18230 pAdapter->sessionId, timeout));
18231
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018232 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018233 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018234 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018235 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018236 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018237 }
18238
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018239 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
18240 (TRUE == pHddCtx->hdd_wlan_suspended) &&
18241 (pHddCtx->cfg_ini->fhostArpOffload) &&
18242 (eConnectionState_Associated ==
18243 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
18244 {
Amar Singhald53568e2013-09-26 11:03:45 -070018245
18246 hddLog(VOS_TRACE_LEVEL_INFO,
18247 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053018248 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018249 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18250 {
18251 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018252 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018253 __func__, vos_status);
18254 }
18255 }
18256
Jeff Johnson295189b2012-06-20 16:38:30 -070018257 /**The get power cmd from the supplicant gets updated by the nl only
18258 *on successful execution of the function call
18259 *we are oppositely mapped w.r.t mode in the driver
18260 **/
18261 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
18262
18263 if (VOS_STATUS_E_FAILURE == vos_status)
18264 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18266 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018267 return -EINVAL;
18268 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018269 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018270 return 0;
18271}
18272
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018273static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
18274 struct net_device *dev, bool mode, int timeout)
18275{
18276 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018277
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018278 vos_ssr_protect(__func__);
18279 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
18280 vos_ssr_unprotect(__func__);
18281
18282 return ret;
18283}
Sushant Kaushik084f6592015-09-10 13:11:56 +053018284
Jeff Johnson295189b2012-06-20 16:38:30 -070018285#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018286static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
18287 struct net_device *netdev,
18288 u8 key_index)
18289{
18290 ENTER();
18291 return 0;
18292}
18293
Jeff Johnson295189b2012-06-20 16:38:30 -070018294static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018295 struct net_device *netdev,
18296 u8 key_index)
18297{
18298 int ret;
18299 vos_ssr_protect(__func__);
18300 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
18301 vos_ssr_unprotect(__func__);
18302 return ret;
18303}
18304#endif //LINUX_VERSION_CODE
18305
18306#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18307static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18308 struct net_device *dev,
18309 struct ieee80211_txq_params *params)
18310{
18311 ENTER();
18312 return 0;
18313}
18314#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18315static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18316 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018317{
Jeff Johnsone7245742012-09-05 17:12:55 -070018318 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070018319 return 0;
18320}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018321#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070018322
18323#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18324static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018325 struct net_device *dev,
18326 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018327{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018328 int ret;
18329
18330 vos_ssr_protect(__func__);
18331 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
18332 vos_ssr_unprotect(__func__);
18333 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018334}
18335#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18336static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
18337 struct ieee80211_txq_params *params)
18338{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018339 int ret;
18340
18341 vos_ssr_protect(__func__);
18342 ret = __wlan_hdd_set_txq_params(wiphy, params);
18343 vos_ssr_unprotect(__func__);
18344 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018345}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018346#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018347
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018348static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018349 struct net_device *dev,
18350 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070018351{
18352 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018353 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018354 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018355 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018356 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018357 v_CONTEXT_t pVosContext = NULL;
18358 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018359
Jeff Johnsone7245742012-09-05 17:12:55 -070018360 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018361
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018362 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070018363 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018364 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018365 return -EINVAL;
18366 }
18367
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018368 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18369 TRACE_CODE_HDD_CFG80211_DEL_STA,
18370 pAdapter->sessionId, pAdapter->device_mode));
18371
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018372 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18373 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018374 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018375 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018376 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018377 }
18378
Jeff Johnson295189b2012-06-20 16:38:30 -070018379 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018380 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018381 )
18382 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018383 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
18384 pSapCtx = VOS_GET_SAP_CB(pVosContext);
18385 if(pSapCtx == NULL){
18386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18387 FL("psapCtx is NULL"));
18388 return -ENOENT;
18389 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053018390 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
18391 {
18392 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
18393 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
18394 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
18395 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018396 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070018397 {
18398 v_U16_t i;
18399 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
18400 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018401 if ((pSapCtx->aStaInfo[i].isUsed) &&
18402 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070018403 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018404 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018405 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018406 ETHER_ADDR_LEN);
18407
Jeff Johnson295189b2012-06-20 16:38:30 -070018408 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018409 "%s: Delete STA with MAC::"
18410 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018411 __func__,
18412 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18413 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018414 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018415 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018416 }
18417 }
18418 }
18419 else
18420 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018421
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018422 vos_status = hdd_softap_GetStaId(pAdapter,
18423 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018424 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18425 {
18426 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018427 "%s: Skip this DEL STA as this is not used::"
18428 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018429 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018430 return -ENOENT;
18431 }
18432
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018433 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018434 {
18435 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018436 "%s: Skip this DEL STA as deauth is in progress::"
18437 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018438 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018439 return -ENOENT;
18440 }
18441
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018442 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018443
Jeff Johnson295189b2012-06-20 16:38:30 -070018444 hddLog(VOS_TRACE_LEVEL_INFO,
18445 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018446 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018447 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018448 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018449
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018450 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018451 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18452 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018453 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018454 hddLog(VOS_TRACE_LEVEL_INFO,
18455 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018456 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018457 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018458 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018459 return -ENOENT;
18460 }
18461
Jeff Johnson295189b2012-06-20 16:38:30 -070018462 }
18463 }
18464
18465 EXIT();
18466
18467 return 0;
18468}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018469
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018470#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018471int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018472 struct net_device *dev,
18473 struct station_del_parameters *param)
18474#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018475#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018476int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018477 struct net_device *dev, const u8 *mac)
18478#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018479int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018480 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018481#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018482#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018483{
18484 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018485 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018486
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018487 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018488
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018489#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018490 if (NULL == param) {
18491 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018492 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018493 return -EINVAL;
18494 }
18495
18496 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
18497 param->subtype, &delStaParams);
18498
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018499#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053018500 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018501 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018502#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018503 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
18504
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018505 vos_ssr_unprotect(__func__);
18506
18507 return ret;
18508}
18509
18510static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018511 struct net_device *dev,
18512#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18513 const u8 *mac,
18514#else
18515 u8 *mac,
18516#endif
18517 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018518{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018519 hdd_adapter_t *pAdapter;
18520 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018521 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018522#ifdef FEATURE_WLAN_TDLS
18523 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018524
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018525 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018526
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018527 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18528 if (NULL == pAdapter)
18529 {
18530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18531 "%s: Adapter is NULL",__func__);
18532 return -EINVAL;
18533 }
18534 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18535 status = wlan_hdd_validate_context(pHddCtx);
18536 if (0 != status)
18537 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018538 return status;
18539 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018540
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018541 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18542 TRACE_CODE_HDD_CFG80211_ADD_STA,
18543 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018544 mask = params->sta_flags_mask;
18545
18546 set = params->sta_flags_set;
18547
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018548 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018549 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
18550 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018551
18552 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
18553 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080018554 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018555 }
18556 }
18557#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018558 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018559 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018560}
18561
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018562#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18563static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18564 struct net_device *dev, const u8 *mac,
18565 struct station_parameters *params)
18566#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018567static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18568 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018569#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018570{
18571 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018572
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018573 vos_ssr_protect(__func__);
18574 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
18575 vos_ssr_unprotect(__func__);
18576
18577 return ret;
18578}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018579#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070018580
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018581static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070018582 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018583{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018584 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18585 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018586 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018587 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018588 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018589 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070018590
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018591 ENTER();
18592
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018593 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018594 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018595 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018596 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018597 return -EINVAL;
18598 }
18599
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018600 if (!pmksa) {
18601 hddLog(LOGE, FL("pmksa is NULL"));
18602 return -EINVAL;
18603 }
18604
18605 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070018606 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018607 pmksa->bssid, pmksa->pmkid);
18608 return -EINVAL;
18609 }
18610
18611 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
18612 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18613
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018614 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18615 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018616 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018617 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018618 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018619 }
18620
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018621 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018622 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18623
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018624 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
18625 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018626
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018627 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018628 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018629 &pmk_id, 1, FALSE);
18630
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018631 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18632 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
18633 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018634
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018635 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018636 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018637}
18638
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018639static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
18640 struct cfg80211_pmksa *pmksa)
18641{
18642 int ret;
18643
18644 vos_ssr_protect(__func__);
18645 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
18646 vos_ssr_unprotect(__func__);
18647
18648 return ret;
18649}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018650
Wilson Yang6507c4e2013-10-01 20:11:19 -070018651
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018652static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070018653 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018654{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018655 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18656 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018657 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018658 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018659
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018660 ENTER();
18661
Wilson Yang6507c4e2013-10-01 20:11:19 -070018662 /* Validate pAdapter */
18663 if (NULL == pAdapter)
18664 {
18665 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
18666 return -EINVAL;
18667 }
18668
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018669 if (!pmksa) {
18670 hddLog(LOGE, FL("pmksa is NULL"));
18671 return -EINVAL;
18672 }
18673
18674 if (!pmksa->bssid) {
18675 hddLog(LOGE, FL("pmksa->bssid is NULL"));
18676 return -EINVAL;
18677 }
18678
Kiet Lam98c46a12014-10-31 15:34:57 -070018679 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
18680 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18681
Wilson Yang6507c4e2013-10-01 20:11:19 -070018682 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18683 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018684 if (0 != status)
18685 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018686 return status;
18687 }
18688
18689 /*Retrieve halHandle*/
18690 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18691
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018692 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18693 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
18694 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018695 /* Delete the PMKID CSR cache */
18696 if (eHAL_STATUS_SUCCESS !=
18697 sme_RoamDelPMKIDfromCache(halHandle,
18698 pAdapter->sessionId, pmksa->bssid, FALSE)) {
18699 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
18700 MAC_ADDR_ARRAY(pmksa->bssid));
18701 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018702 }
18703
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018704 EXIT();
18705 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018706}
18707
Wilson Yang6507c4e2013-10-01 20:11:19 -070018708
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018709static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
18710 struct cfg80211_pmksa *pmksa)
18711{
18712 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018713
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018714 vos_ssr_protect(__func__);
18715 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
18716 vos_ssr_unprotect(__func__);
18717
18718 return ret;
18719
18720}
18721
18722static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018723{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018724 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18725 tHalHandle halHandle;
18726 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018727 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018728
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018729 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070018730
18731 /* Validate pAdapter */
18732 if (NULL == pAdapter)
18733 {
18734 hddLog(VOS_TRACE_LEVEL_ERROR,
18735 "%s: Invalid Adapter" ,__func__);
18736 return -EINVAL;
18737 }
18738
18739 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18740 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018741 if (0 != status)
18742 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018743 return status;
18744 }
18745
18746 /*Retrieve halHandle*/
18747 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18748
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018749 /* Flush the PMKID cache in CSR */
18750 if (eHAL_STATUS_SUCCESS !=
18751 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
18752 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
18753 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018754 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018755 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080018756 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018757}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018758
18759static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
18760{
18761 int ret;
18762
18763 vos_ssr_protect(__func__);
18764 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
18765 vos_ssr_unprotect(__func__);
18766
18767 return ret;
18768}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018769#endif
18770
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018771#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018772static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
18773 struct net_device *dev,
18774 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018775{
18776 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18777 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018778 hdd_context_t *pHddCtx;
18779 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018780
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018781 ENTER();
18782
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018783 if (NULL == pAdapter)
18784 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018785 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018786 return -ENODEV;
18787 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018788 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18789 ret = wlan_hdd_validate_context(pHddCtx);
18790 if (0 != ret)
18791 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018792 return ret;
18793 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018794 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018795 if (NULL == pHddStaCtx)
18796 {
18797 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
18798 return -EINVAL;
18799 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018800
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018801 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18802 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
18803 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018804 // Added for debug on reception of Re-assoc Req.
18805 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
18806 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018807 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018808 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080018809 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018810 }
18811
18812#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080018813 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018814 ftie->ie_len);
18815#endif
18816
18817 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053018818 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
18819 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018820 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018821
18822 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018823 return 0;
18824}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018825
18826static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
18827 struct net_device *dev,
18828 struct cfg80211_update_ft_ies_params *ftie)
18829{
18830 int ret;
18831
18832 vos_ssr_protect(__func__);
18833 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
18834 vos_ssr_unprotect(__func__);
18835
18836 return ret;
18837}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018838#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018839
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018840#ifdef FEATURE_WLAN_SCAN_PNO
18841
18842void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
18843 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
18844{
18845 int ret;
18846 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
18847 hdd_context_t *pHddCtx;
18848
Nirav Shah80830bf2013-12-31 16:35:12 +053018849 ENTER();
18850
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018851 if (NULL == pAdapter)
18852 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018854 "%s: HDD adapter is Null", __func__);
18855 return ;
18856 }
18857
18858 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18859 if (NULL == pHddCtx)
18860 {
18861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18862 "%s: HDD context is Null!!!", __func__);
18863 return ;
18864 }
18865
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018866 spin_lock(&pHddCtx->schedScan_lock);
18867 if (TRUE == pHddCtx->isWiphySuspended)
18868 {
18869 pHddCtx->isSchedScanUpdatePending = TRUE;
18870 spin_unlock(&pHddCtx->schedScan_lock);
18871 hddLog(VOS_TRACE_LEVEL_INFO,
18872 "%s: Update cfg80211 scan database after it resume", __func__);
18873 return ;
18874 }
18875 spin_unlock(&pHddCtx->schedScan_lock);
18876
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018877 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
18878
18879 if (0 > ret)
18880 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053018881 else
18882 {
18883 /* Acquire wakelock to handle the case where APP's tries to suspend
18884 * immediatly after the driver gets connect request(i.e after pno)
18885 * from supplicant, this result in app's is suspending and not able
18886 * to process the connect request to AP */
18887 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
18888 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018889 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018890 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18891 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018892}
18893
18894/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018895 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018896 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018897 */
18898static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
18899{
18900 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
18901 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018902 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018903 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18904 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053018905
18906 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
18907 {
18908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18909 "%s: PNO is allowed only in STA interface", __func__);
18910 return eHAL_STATUS_FAILURE;
18911 }
18912
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018913 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
18914
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018915 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053018916 * active sessions. PNO is allowed only in case when sap session
18917 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018918 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018919 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
18920 {
18921 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018922 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018923
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018924 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
18925 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
18926 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
18927 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053018928 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
18929 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053018930 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018931 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018932 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018933 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018934 }
18935 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
18936 pAdapterNode = pNext;
18937 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018938 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018939}
18940
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018941void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
18942{
18943 hdd_adapter_t *pAdapter = callbackContext;
18944 hdd_context_t *pHddCtx;
18945
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018946 ENTER();
18947
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018948 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
18949 {
18950 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18951 FL("Invalid adapter or adapter has invalid magic"));
18952 return;
18953 }
18954
18955 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18956 if (0 != wlan_hdd_validate_context(pHddCtx))
18957 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018958 return;
18959 }
18960
c_hpothub53c45d2014-08-18 16:53:14 +053018961 if (VOS_STATUS_SUCCESS != status)
18962 {
18963 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018964 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053018965 pHddCtx->isPnoEnable = FALSE;
18966 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018967
18968 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
18969 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018970 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018971}
18972
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018973#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
18974 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
18975/**
18976 * hdd_config_sched_scan_plan() - configures the sched scan plans
18977 * from the framework.
18978 * @pno_req: pointer to PNO scan request
18979 * @request: pointer to scan request from framework
18980 *
18981 * Return: None
18982 */
18983static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
18984 struct cfg80211_sched_scan_request *request,
18985 hdd_context_t *hdd_ctx)
18986{
18987 v_U32_t i = 0;
18988
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018989 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018990 for (i = 0; i < request->n_scan_plans; i++)
18991 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018992 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
18993 request->scan_plans[i].iterations;
18994 pno_req->scanTimers.aTimerValues[i].uTimerValue =
18995 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018996 }
18997}
18998#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018999static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019000 struct cfg80211_sched_scan_request *request,
19001 hdd_context_t *hdd_ctx)
19002{
19003 v_U32_t i, temp_int;
19004 /* Driver gets only one time interval which is hardcoded in
19005 * supplicant for 10000ms. Taking power consumption into account 6
19006 * timers will be used, Timervalue is increased exponentially
19007 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
19008 * timer is configurable through INI param gPNOScanTimerRepeatValue.
19009 * If it is set to 0 only one timer will be used and PNO scan cycle
19010 * will be repeated after each interval specified by supplicant
19011 * till PNO is disabled.
19012 */
19013 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019014 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019015 HDD_PNO_SCAN_TIMERS_SET_ONE;
19016 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019017 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019018 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
19019
19020 temp_int = (request->interval)/1000;
19021 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19022 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
19023 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019024 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019025 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019026 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019027 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019028 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019029 temp_int *= 2;
19030 }
19031 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019032 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019033}
19034#endif
19035
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019036/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019037 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
19038 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019039 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019040static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019041 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19042{
19043 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019044 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019045 hdd_context_t *pHddCtx;
19046 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019047 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053019048 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
19049 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019050 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
19051 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019052 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019053 hdd_config_t *pConfig = NULL;
19054 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019055
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019056 ENTER();
19057
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019058 if (NULL == pAdapter)
19059 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019060 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019061 "%s: HDD adapter is Null", __func__);
19062 return -ENODEV;
19063 }
19064
19065 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019066 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019067
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019068 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019069 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019070 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019071 }
19072
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019073 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019074 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19075 if (NULL == hHal)
19076 {
19077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19078 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019079 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019080 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019081 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19082 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
19083 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019084 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053019085 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019086 {
19087 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19088 "%s: aborting the existing scan is unsuccessfull", __func__);
19089 return -EBUSY;
19090 }
19091
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019092 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019093 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019094 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019095 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019096 return -EBUSY;
19097 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019098
c_hpothu37f21312014-04-09 21:49:54 +053019099 if (TRUE == pHddCtx->isPnoEnable)
19100 {
19101 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19102 FL("already PNO is enabled"));
19103 return -EBUSY;
19104 }
c_hpothu225aa7c2014-10-22 17:45:13 +053019105
19106 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
19107 {
19108 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19109 "%s: abort ROC failed ", __func__);
19110 return -EBUSY;
19111 }
19112
c_hpothu37f21312014-04-09 21:49:54 +053019113 pHddCtx->isPnoEnable = TRUE;
19114
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019115 pnoRequest.enable = 1; /*Enable PNO */
19116 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019117
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019118 if (( !pnoRequest.ucNetworksCount ) ||
19119 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019120 {
19121 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019122 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019123 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019124 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019125 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019126 goto error;
19127 }
19128
19129 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
19130 {
19131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019132 "%s: Incorrect number of channels %d",
19133 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019134 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019135 goto error;
19136 }
19137
19138 /* Framework provides one set of channels(all)
19139 * common for all saved profile */
19140 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
19141 channels_allowed, &num_channels_allowed))
19142 {
19143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19144 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019145 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019146 goto error;
19147 }
19148 /* Checking each channel against allowed channel list */
19149 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053019150 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019151 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019152 char chList [(request->n_channels*5)+1];
19153 int len;
19154 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019155 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019156 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019157 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019158 if (request->channels[i]->hw_value == channels_allowed[indx])
19159 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019160 if ((!pConfig->enableDFSPnoChnlScan) &&
19161 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
19162 {
19163 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19164 "%s : Dropping DFS channel : %d",
19165 __func__,channels_allowed[indx]);
19166 num_ignore_dfs_ch++;
19167 break;
19168 }
19169
Nirav Shah80830bf2013-12-31 16:35:12 +053019170 valid_ch[num_ch++] = request->channels[i]->hw_value;
19171 len += snprintf(chList+len, 5, "%d ",
19172 request->channels[i]->hw_value);
19173 break ;
19174 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019175 }
19176 }
Nirav Shah80830bf2013-12-31 16:35:12 +053019177 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019178
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019179 /*If all channels are DFS and dropped, then ignore the PNO request*/
19180 if (num_ignore_dfs_ch == request->n_channels)
19181 {
19182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19183 "%s : All requested channels are DFS channels", __func__);
19184 ret = -EINVAL;
19185 goto error;
19186 }
19187 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019188
19189 pnoRequest.aNetworks =
19190 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19191 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019192 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019193 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19194 FL("failed to allocate memory aNetworks %u"),
19195 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19196 goto error;
19197 }
19198 vos_mem_zero(pnoRequest.aNetworks,
19199 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19200
19201 /* Filling per profile params */
19202 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
19203 {
19204 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019205 request->match_sets[i].ssid.ssid_len;
19206
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019207 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
19208 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019209 {
19210 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019211 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019212 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019213 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019214 goto error;
19215 }
19216
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019217 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019218 request->match_sets[i].ssid.ssid,
19219 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019220 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19221 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019222 i, pnoRequest.aNetworks[i].ssId.ssId);
19223 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
19224 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
19225 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019226
19227 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019228 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
19229 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019230
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019231 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019232 }
19233
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019234 for (i = 0; i < request->n_ssids; i++)
19235 {
19236 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019237 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019238 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019239 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019240 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019241 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019242 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019243 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019244 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019245 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019246 break;
19247 }
19248 j++;
19249 }
19250 }
19251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19252 "Number of hidden networks being Configured = %d",
19253 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080019255 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019256
19257 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19258 if (pnoRequest.p24GProbeTemplate == NULL)
19259 {
19260 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19261 FL("failed to allocate memory p24GProbeTemplate %u"),
19262 SIR_PNO_MAX_PB_REQ_SIZE);
19263 goto error;
19264 }
19265
19266 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19267 if (pnoRequest.p5GProbeTemplate == NULL)
19268 {
19269 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19270 FL("failed to allocate memory p5GProbeTemplate %u"),
19271 SIR_PNO_MAX_PB_REQ_SIZE);
19272 goto error;
19273 }
19274
19275 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19276 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19277
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053019278 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
19279 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019280 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019281 pnoRequest.us24GProbeTemplateLen = request->ie_len;
19282 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
19283 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019284
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019285 pnoRequest.us5GProbeTemplateLen = request->ie_len;
19286 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
19287 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019288 }
19289
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019290 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053019291
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019292 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019293
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019294 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019295 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19296 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019297 pAdapter->pno_req_status = 0;
19298
Nirav Shah80830bf2013-12-31 16:35:12 +053019299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19300 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019301 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
19302 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053019303
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019304 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019305 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019306 hdd_cfg80211_sched_scan_done_callback, pAdapter);
19307 if (eHAL_STATUS_SUCCESS != status)
19308 {
19309 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019310 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019311 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019312 goto error;
19313 }
19314
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019315 ret = wait_for_completion_timeout(
19316 &pAdapter->pno_comp_var,
19317 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19318 if (0 >= ret)
19319 {
19320 // Did not receive the response for PNO enable in time.
19321 // Assuming the PNO enable was success.
19322 // Returning error from here, because we timeout, results
19323 // in side effect of Wifi (Wifi Setting) not to work.
19324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19325 FL("Timed out waiting for PNO to be Enabled"));
19326 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019327 }
19328
19329 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053019330 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019331
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019332error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19334 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053019335 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019336 if (pnoRequest.aNetworks)
19337 vos_mem_free(pnoRequest.aNetworks);
19338 if (pnoRequest.p24GProbeTemplate)
19339 vos_mem_free(pnoRequest.p24GProbeTemplate);
19340 if (pnoRequest.p5GProbeTemplate)
19341 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019342
19343 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019344 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019345}
19346
19347/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019348 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
19349 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019350 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019351static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
19352 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19353{
19354 int ret;
19355
19356 vos_ssr_protect(__func__);
19357 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
19358 vos_ssr_unprotect(__func__);
19359
19360 return ret;
19361}
19362
19363/*
19364 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
19365 * Function to disable PNO
19366 */
19367static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019368 struct net_device *dev)
19369{
19370 eHalStatus status = eHAL_STATUS_FAILURE;
19371 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19372 hdd_context_t *pHddCtx;
19373 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019374 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019375 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019376
19377 ENTER();
19378
19379 if (NULL == pAdapter)
19380 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019382 "%s: HDD adapter is Null", __func__);
19383 return -ENODEV;
19384 }
19385
19386 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019387
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019388 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019389 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019390 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019391 "%s: HDD context is Null", __func__);
19392 return -ENODEV;
19393 }
19394
19395 /* The return 0 is intentional when isLogpInProgress and
19396 * isLoadUnloadInProgress. We did observe a crash due to a return of
19397 * failure in sched_scan_stop , especially for a case where the unload
19398 * of the happens at the same time. The function __cfg80211_stop_sched_scan
19399 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
19400 * success. If it returns a failure , then its next invocation due to the
19401 * clean up of the second interface will have the dev pointer corresponding
19402 * to the first one leading to a crash.
19403 */
19404 if (pHddCtx->isLogpInProgress)
19405 {
19406 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19407 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019408 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019409 return ret;
19410 }
19411
Mihir Shete18156292014-03-11 15:38:30 +053019412 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019413 {
19414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19415 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19416 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019417 }
19418
19419 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19420 if (NULL == hHal)
19421 {
19422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19423 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019424 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019425 }
19426
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019427 pnoRequest.enable = 0; /* Disable PNO */
19428 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019429
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019430 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19431 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19432 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019433
19434 INIT_COMPLETION(pAdapter->pno_comp_var);
19435 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19436 pnoRequest.callbackContext = pAdapter;
19437 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019438 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019439 pAdapter->sessionId,
19440 NULL, pAdapter);
19441 if (eHAL_STATUS_SUCCESS != status)
19442 {
19443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19444 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019445 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019446 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019447 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019448 ret = wait_for_completion_timeout(
19449 &pAdapter->pno_comp_var,
19450 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19451 if (0 >= ret)
19452 {
19453 // Did not receive the response for PNO disable in time.
19454 // Assuming the PNO disable was success.
19455 // Returning error from here, because we timeout, results
19456 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019458 FL("Timed out waiting for PNO to be disabled"));
19459 ret = 0;
19460 }
19461
19462 ret = pAdapter->pno_req_status;
19463 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019464
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019465error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019467 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019468
19469 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019470 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019471}
19472
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019473/*
19474 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19475 * NL interface to disable PNO
19476 */
19477static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19478 struct net_device *dev)
19479{
19480 int ret;
19481
19482 vos_ssr_protect(__func__);
19483 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19484 vos_ssr_unprotect(__func__);
19485
19486 return ret;
19487}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019488#endif /*FEATURE_WLAN_SCAN_PNO*/
19489
19490
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019491#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019492#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019493static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19494 struct net_device *dev,
19495 u8 *peer, u8 action_code,
19496 u8 dialog_token,
19497 u16 status_code, u32 peer_capability,
19498 const u8 *buf, size_t len)
19499#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019500#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
19501 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019502static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19503 struct net_device *dev,
19504 const u8 *peer, u8 action_code,
19505 u8 dialog_token, u16 status_code,
19506 u32 peer_capability, bool initiator,
19507 const u8 *buf, size_t len)
19508#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19509static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19510 struct net_device *dev,
19511 const u8 *peer, u8 action_code,
19512 u8 dialog_token, u16 status_code,
19513 u32 peer_capability, const u8 *buf,
19514 size_t len)
19515#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19516static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19517 struct net_device *dev,
19518 u8 *peer, u8 action_code,
19519 u8 dialog_token,
19520 u16 status_code, u32 peer_capability,
19521 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019522#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019523static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19524 struct net_device *dev,
19525 u8 *peer, u8 action_code,
19526 u8 dialog_token,
19527 u16 status_code, const u8 *buf,
19528 size_t len)
19529#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019530#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019531{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019532 hdd_adapter_t *pAdapter;
19533 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019534 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070019535 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080019536 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070019537 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019538 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019539 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019540#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019541 u32 peer_capability = 0;
19542#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019543 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019544 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019545 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019546
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019547 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19548 if (NULL == pAdapter)
19549 {
19550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19551 "%s: Adapter is NULL",__func__);
19552 return -EINVAL;
19553 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019554 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19555 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
19556 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019557
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019558 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019559 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019560 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019562 "Invalid arguments");
19563 return -EINVAL;
19564 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019565
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019566 if (pHddCtx->isLogpInProgress)
19567 {
19568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19569 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053019570 wlan_hdd_tdls_set_link_status(pAdapter,
19571 peer,
19572 eTDLS_LINK_IDLE,
19573 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019574 return -EBUSY;
19575 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019576
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019577 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
19578 {
19579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19580 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19581 return -EAGAIN;
19582 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019583
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019584 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
19585 if (!pHddTdlsCtx) {
19586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19587 "%s: pHddTdlsCtx not valid.", __func__);
19588 }
19589
Hoonki Lee27511902013-03-14 18:19:06 -070019590 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019591 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019593 "%s: TDLS mode is disabled OR not enabled in FW."
19594 MAC_ADDRESS_STR " action %d declined.",
19595 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019596 return -ENOTSUPP;
19597 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019598
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019599 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19600
19601 if( NULL == pHddStaCtx )
19602 {
19603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19604 "%s: HDD station context NULL ",__func__);
19605 return -EINVAL;
19606 }
19607
19608 /* STA should be connected and authenticated
19609 * before sending any TDLS frames
19610 */
19611 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
19612 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
19613 {
19614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19615 "STA is not connected or unauthenticated. "
19616 "connState %u, uIsAuthenticated %u",
19617 pHddStaCtx->conn_info.connState,
19618 pHddStaCtx->conn_info.uIsAuthenticated);
19619 return -EAGAIN;
19620 }
19621
Hoonki Lee27511902013-03-14 18:19:06 -070019622 /* other than teardown frame, other mgmt frames are not sent if disabled */
19623 if (SIR_MAC_TDLS_TEARDOWN != action_code)
19624 {
19625 /* if tdls_mode is disabled to respond to peer's request */
19626 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
19627 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019629 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019630 " TDLS mode is disabled. action %d declined.",
19631 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070019632
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019633 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070019634 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053019635
19636 if (vos_max_concurrent_connections_reached())
19637 {
19638 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
19639 return -EINVAL;
19640 }
Hoonki Lee27511902013-03-14 18:19:06 -070019641 }
19642
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019643 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
19644 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053019645 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019646 {
19647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019648 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019649 " TDLS setup is ongoing. action %d declined.",
19650 __func__, MAC_ADDR_ARRAY(peer), action_code);
19651 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019652 }
19653 }
19654
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019655 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
19656 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080019657 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019658 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19659 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019660 {
19661 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
19662 we return error code at 'add_station()'. Hence we have this
19663 check again in addtion to add_station().
19664 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019665 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019666 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019667 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19668 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019669 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
19670 __func__, MAC_ADDR_ARRAY(peer), action_code,
19671 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053019672 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080019673 }
19674 else
19675 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019676 /* maximum reached. tweak to send error code to peer and return
19677 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019678 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19680 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019681 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
19682 __func__, MAC_ADDR_ARRAY(peer), status_code,
19683 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070019684 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019685 /* fall through to send setup resp with failure status
19686 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019687 }
19688 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019689 else
19690 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019691 mutex_lock(&pHddCtx->tdls_lock);
19692 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019693 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019694 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019695 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019697 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
19698 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019699 return -EPERM;
19700 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019701 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019702 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019703 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019704
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019706 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019707 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
19708 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019709
Hoonki Leea34dd892013-02-05 22:56:02 -080019710 /*Except teardown responder will not be used so just make 0*/
19711 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019712 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080019713 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019714
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019715 mutex_lock(&pHddCtx->tdls_lock);
19716 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019717
19718 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
19719 responder = pTdlsPeer->is_responder;
19720 else
Hoonki Leea34dd892013-02-05 22:56:02 -080019721 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019722 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019723 "%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 -070019724 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
19725 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019726 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019727 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080019728 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019729 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019730 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019731
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019732 /* Discard TDLS setup if peer is removed by user app */
19733 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
19734 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19735 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
19736 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
19737
19738 mutex_lock(&pHddCtx->tdls_lock);
19739 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19740 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
19741 mutex_unlock(&pHddCtx->tdls_lock);
19742 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
19743 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
19744 MAC_ADDR_ARRAY(peer), action_code);
19745 return -EINVAL;
19746 }
19747 mutex_unlock(&pHddCtx->tdls_lock);
19748 }
19749
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019750 /* For explicit trigger of DIS_REQ come out of BMPS for
19751 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070019752 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053019753 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019754 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
19755 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070019756 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019757 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019759 "%s: Sending frame action_code %u.Disable BMPS", __func__,
19760 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019761 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
19762 if (status != VOS_STATUS_SUCCESS) {
19763 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019764 } else {
19765 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019766 }
Hoonki Lee14621352013-04-16 17:51:19 -070019767 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019768 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019769 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019770 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
19771 }
19772 }
Hoonki Lee14621352013-04-16 17:51:19 -070019773 }
19774
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019775 /* make sure doesn't call send_mgmt() while it is pending */
19776 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
19777 {
19778 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080019779 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019780 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019781 ret = -EBUSY;
19782 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019783 }
19784
19785 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019786 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
19787
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019788 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
19789 pAdapter->sessionId, peer, action_code, dialog_token,
19790 status_code, peer_capability, (tANI_U8 *)buf, len,
19791 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019792
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019793 if (VOS_STATUS_SUCCESS != status)
19794 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19796 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019797 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019798 ret = -EINVAL;
19799 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019800 }
19801
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019802 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19803 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
19804 WAIT_TIME_TDLS_MGMT);
19805
Hoonki Leed37cbb32013-04-20 00:31:14 -070019806 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
19807 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
19808
19809 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019810 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070019811 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070019812 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070019813 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019814 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080019815
19816 if (pHddCtx->isLogpInProgress)
19817 {
19818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19819 "%s: LOGP in Progress. Ignore!!!", __func__);
19820 return -EAGAIN;
19821 }
Abhishek Singh837adf22015-10-01 17:37:37 +053019822 if (rc <= 0)
19823 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
19824 WLAN_LOG_INDICATOR_HOST_DRIVER,
19825 WLAN_LOG_REASON_HDD_TIME_OUT,
19826 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080019827
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019828 ret = -EINVAL;
19829 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019830 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019831 else
19832 {
19833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19834 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
19835 __func__, rc, pAdapter->mgmtTxCompletionStatus);
19836 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019837
Gopichand Nakkala05922802013-03-14 12:23:19 -070019838 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070019839 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019840 ret = max_sta_failed;
19841 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070019842 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019843
Hoonki Leea34dd892013-02-05 22:56:02 -080019844 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
19845 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019846 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019847 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
19848 }
Hoonki Leea34dd892013-02-05 22:56:02 -080019849 }
19850 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
19851 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019852 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019853 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
19854 }
Hoonki Leea34dd892013-02-05 22:56:02 -080019855 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019856
19857 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019858
19859tx_failed:
19860 /* add_station will be called before sending TDLS_SETUP_REQ and
19861 * TDLS_SETUP_RSP and as part of add_station driver will enable
19862 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
19863 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
19864 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
19865 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
19866 */
19867
19868 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19869 (SIR_MAC_TDLS_SETUP_RSP == action_code))
19870 wlan_hdd_tdls_check_bmps(pAdapter);
19871 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019872}
19873
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019874#if TDLS_MGMT_VERSION2
19875static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19876 u8 *peer, u8 action_code, u8 dialog_token,
19877 u16 status_code, u32 peer_capability,
19878 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019879#else /* TDLS_MGMT_VERSION2 */
19880#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19881static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19882 struct net_device *dev,
19883 const u8 *peer, u8 action_code,
19884 u8 dialog_token, u16 status_code,
19885 u32 peer_capability, bool initiator,
19886 const u8 *buf, size_t len)
19887#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19888static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19889 struct net_device *dev,
19890 const u8 *peer, u8 action_code,
19891 u8 dialog_token, u16 status_code,
19892 u32 peer_capability, const u8 *buf,
19893 size_t len)
19894#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19895static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19896 struct net_device *dev,
19897 u8 *peer, u8 action_code,
19898 u8 dialog_token,
19899 u16 status_code, u32 peer_capability,
19900 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019901#else
19902static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19903 u8 *peer, u8 action_code, u8 dialog_token,
19904 u16 status_code, const u8 *buf, size_t len)
19905#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019906#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019907{
19908 int ret;
19909
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019910 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019911#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019912 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19913 dialog_token, status_code,
19914 peer_capability, buf, len);
19915#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019916#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
19917 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019918 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19919 dialog_token, status_code,
19920 peer_capability, initiator,
19921 buf, len);
19922#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19923 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19924 dialog_token, status_code,
19925 peer_capability, buf, len);
19926#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19927 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19928 dialog_token, status_code,
19929 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019930#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019931 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19932 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019933#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019934#endif
19935 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019936
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019937 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019938}
Atul Mittal115287b2014-07-08 13:26:33 +053019939
19940int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019941#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19942 const u8 *peer,
19943#else
Atul Mittal115287b2014-07-08 13:26:33 +053019944 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019945#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019946 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053019947 cfg80211_exttdls_callback callback)
19948{
19949
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019950 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053019951 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019952 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053019953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19954 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
19955 __func__, MAC_ADDR_ARRAY(peer));
19956
19957 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19958 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19959
19960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019961 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19962 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19963 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019964 return -ENOTSUPP;
19965 }
19966
19967 /* To cater the requirement of establishing the TDLS link
19968 * irrespective of the data traffic , get an entry of TDLS peer.
19969 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019970 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019971 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
19972 if (pTdlsPeer == NULL) {
19973 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19974 "%s: peer " MAC_ADDRESS_STR " not existing",
19975 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019976 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019977 return -EINVAL;
19978 }
19979
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019980 /* check FW TDLS Off Channel capability */
19981 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019982 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019983 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019984 {
19985 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
19986 pTdlsPeer->peerParams.global_operating_class =
19987 tdls_peer_params->global_operating_class;
19988 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
19989 pTdlsPeer->peerParams.min_bandwidth_kbps =
19990 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019991 /* check configured channel is valid, non dfs and
19992 * not current operating channel */
19993 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
19994 tdls_peer_params->channel)) &&
19995 (pHddStaCtx) &&
19996 (tdls_peer_params->channel !=
19997 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019998 {
19999 pTdlsPeer->isOffChannelConfigured = TRUE;
20000 }
20001 else
20002 {
20003 pTdlsPeer->isOffChannelConfigured = FALSE;
20004 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20005 "%s: Configured Tdls Off Channel is not valid", __func__);
20006
20007 }
20008 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020009 "%s: tdls_off_channel %d isOffChannelConfigured %d "
20010 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020011 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020012 pTdlsPeer->isOffChannelConfigured,
20013 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020014 }
20015 else
20016 {
20017 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020018 "%s: TDLS off channel FW capability %d, "
20019 "host capab %d or Invalid TDLS Peer Params", __func__,
20020 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
20021 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020022 }
20023
Atul Mittal115287b2014-07-08 13:26:33 +053020024 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
20025
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020026 mutex_unlock(&pHddCtx->tdls_lock);
20027
Atul Mittal115287b2014-07-08 13:26:33 +053020028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20029 " %s TDLS Add Force Peer Failed",
20030 __func__);
20031 return -EINVAL;
20032 }
20033 /*EXT TDLS*/
20034
20035 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020036 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20038 " %s TDLS set callback Failed",
20039 __func__);
20040 return -EINVAL;
20041 }
20042
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020043 mutex_unlock(&pHddCtx->tdls_lock);
20044
Atul Mittal115287b2014-07-08 13:26:33 +053020045 return(0);
20046
20047}
20048
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020049int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
20050#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20051 const u8 *peer
20052#else
20053 u8 *peer
20054#endif
20055)
Atul Mittal115287b2014-07-08 13:26:33 +053020056{
20057
20058 hddTdlsPeer_t *pTdlsPeer;
20059 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020060
Atul Mittal115287b2014-07-08 13:26:33 +053020061 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20062 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
20063 __func__, MAC_ADDR_ARRAY(peer));
20064
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020065 if (0 != wlan_hdd_validate_context(pHddCtx)) {
20066 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
20067 return -EINVAL;
20068 }
20069
Atul Mittal115287b2014-07-08 13:26:33 +053020070 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20071 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20072
20073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020074 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20075 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20076 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020077 return -ENOTSUPP;
20078 }
20079
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020080 mutex_lock(&pHddCtx->tdls_lock);
20081 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053020082
20083 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020084 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020085 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020086 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053020087 __func__, MAC_ADDR_ARRAY(peer));
20088 return -EINVAL;
20089 }
20090 else {
20091 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
20092 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020093 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
20094 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020095 /* if channel switch is configured, reset
20096 the channel for this peer */
20097 if (TRUE == pTdlsPeer->isOffChannelConfigured)
20098 {
20099 pTdlsPeer->peerParams.channel = 0;
20100 pTdlsPeer->isOffChannelConfigured = FALSE;
20101 }
Atul Mittal115287b2014-07-08 13:26:33 +053020102 }
20103
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020104 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020105 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020106 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053020107 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020108 }
Atul Mittal115287b2014-07-08 13:26:33 +053020109
20110 /*EXT TDLS*/
20111
20112 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020113 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020114 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20115 " %s TDLS set callback Failed",
20116 __func__);
20117 return -EINVAL;
20118 }
Atul Mittal115287b2014-07-08 13:26:33 +053020119
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020120 mutex_unlock(&pHddCtx->tdls_lock);
20121
20122 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053020123}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020124static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020125#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20126 const u8 *peer,
20127#else
20128 u8 *peer,
20129#endif
20130 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020131{
20132 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20133 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020134 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020135 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020136
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020137 ENTER();
20138
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020139 if (!pAdapter) {
20140 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
20141 return -EINVAL;
20142 }
20143
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020144 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20145 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
20146 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020147 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020148 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070020150 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020151 return -EINVAL;
20152 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020153
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020154 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020155 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020156 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020157 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020158 }
20159
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020160
20161 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020162 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020163 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020165 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
20166 "Cannot process TDLS commands",
20167 pHddCtx->cfg_ini->fEnableTDLSSupport,
20168 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020169 return -ENOTSUPP;
20170 }
20171
20172 switch (oper) {
20173 case NL80211_TDLS_ENABLE_LINK:
20174 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020175 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020176 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053020177 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
20178 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053020179 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020180 tANI_U16 numCurrTdlsPeers = 0;
20181 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020182 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020183 tSirMacAddr peerMac;
20184 int channel;
20185 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020186
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20188 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
20189 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020190
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020191 mutex_lock(&pHddCtx->tdls_lock);
20192 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020193 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053020194 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020195 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020196 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20197 " (oper %d) not exsting. ignored",
20198 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20199 return -EINVAL;
20200 }
20201
20202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20203 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20204 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20205 "NL80211_TDLS_ENABLE_LINK");
20206
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020207 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
20208 {
20209 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
20210 MAC_ADDRESS_STR " failed",
20211 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020212 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020213 return -EINVAL;
20214 }
20215
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020216 /* before starting tdls connection, set tdls
20217 * off channel established status to default value */
20218 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020219
20220 mutex_unlock(&pHddCtx->tdls_lock);
20221
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053020222 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020223 /* TDLS Off Channel, Disable tdls channel switch,
20224 when there are more than one tdls link */
20225 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053020226 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020227 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020228 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020229 /* get connected peer and send disable tdls off chan */
20230 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020231 if ((connPeer) &&
20232 (connPeer->isOffChannelSupported == TRUE) &&
20233 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020234 {
20235 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20236 "%s: More then one peer connected, Disable "
20237 "TDLS channel switch", __func__);
20238
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020239 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020240 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
20241 channel = connPeer->peerParams.channel;
20242
20243 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020244
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020245 ret = sme_SendTdlsChanSwitchReq(
20246 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020247 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020248 peerMac,
20249 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020250 TDLS_OFF_CHANNEL_BW_OFFSET,
20251 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020252 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020253 hddLog(VOS_TRACE_LEVEL_ERROR,
20254 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020255 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020256 }
20257 else
20258 {
20259 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20260 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020261 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020262 "isOffChannelConfigured %d",
20263 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020264 (connPeer ? (connPeer->isOffChannelSupported)
20265 : -1),
20266 (connPeer ? (connPeer->isOffChannelConfigured)
20267 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020268 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020269 }
20270 }
20271
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020272 mutex_lock(&pHddCtx->tdls_lock);
20273 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20274 if ( NULL == pTdlsPeer ) {
20275 mutex_unlock(&pHddCtx->tdls_lock);
20276 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20277 "%s: " MAC_ADDRESS_STR
20278 " (oper %d) peer got freed in other context. ignored",
20279 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20280 return -EINVAL;
20281 }
20282 peer_status = pTdlsPeer->link_status;
20283 mutex_unlock(&pHddCtx->tdls_lock);
20284
20285 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020286 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020287 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053020288
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020289 if (0 != wlan_hdd_tdls_get_link_establish_params(
20290 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020291 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020292 return -EINVAL;
20293 }
20294 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020295
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020296 ret = sme_SendTdlsLinkEstablishParams(
20297 WLAN_HDD_GET_HAL_CTX(pAdapter),
20298 pAdapter->sessionId, peer,
20299 &tdlsLinkEstablishParams);
20300 if (ret != VOS_STATUS_SUCCESS) {
20301 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
20302 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020303 /* Send TDLS peer UAPSD capabilities to the firmware and
20304 * register with the TL on after the response for this operation
20305 * is received .
20306 */
20307 ret = wait_for_completion_interruptible_timeout(
20308 &pAdapter->tdls_link_establish_req_comp,
20309 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053020310
20311 mutex_lock(&pHddCtx->tdls_lock);
20312 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20313 if ( NULL == pTdlsPeer ) {
20314 mutex_unlock(&pHddCtx->tdls_lock);
20315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20316 "%s %d: " MAC_ADDRESS_STR
20317 " (oper %d) peer got freed in other context. ignored",
20318 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
20319 (int)oper);
20320 return -EINVAL;
20321 }
20322 peer_status = pTdlsPeer->link_status;
20323 mutex_unlock(&pHddCtx->tdls_lock);
20324
20325 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020326 {
20327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020328 FL("Link Establish Request Failed Status %ld"),
20329 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020330 return -EINVAL;
20331 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020332 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020333
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020334 mutex_lock(&pHddCtx->tdls_lock);
20335 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20336 if ( NULL == pTdlsPeer ) {
20337 mutex_unlock(&pHddCtx->tdls_lock);
20338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20339 "%s: " MAC_ADDRESS_STR
20340 " (oper %d) peer got freed in other context. ignored",
20341 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20342 return -EINVAL;
20343 }
20344
Atul Mittal115287b2014-07-08 13:26:33 +053020345 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20346 eTDLS_LINK_CONNECTED,
20347 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020348 staDesc.ucSTAId = pTdlsPeer->staId;
20349 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053020350
20351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20352 "%s: tdlsLinkEstablishParams of peer "
20353 MAC_ADDRESS_STR "uapsdQueues: %d"
20354 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
20355 "isResponder: %d peerstaId: %d",
20356 __func__,
20357 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
20358 tdlsLinkEstablishParams.uapsdQueues,
20359 tdlsLinkEstablishParams.qos,
20360 tdlsLinkEstablishParams.maxSp,
20361 tdlsLinkEstablishParams.isBufSta,
20362 tdlsLinkEstablishParams.isOffChannelSupported,
20363 tdlsLinkEstablishParams.isResponder,
20364 pTdlsPeer->staId);
20365
20366 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20367 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
20368 __func__,
20369 staDesc.ucSTAId,
20370 staDesc.ucQosEnabled);
20371
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020372 ret = WLANTL_UpdateTdlsSTAClient(
20373 pHddCtx->pvosContext,
20374 &staDesc);
20375 if (ret != VOS_STATUS_SUCCESS) {
20376 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
20377 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053020378
Gopichand Nakkala471708b2013-06-04 20:03:01 +053020379 /* Mark TDLS client Authenticated .*/
20380 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
20381 pTdlsPeer->staId,
20382 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020383 if (VOS_STATUS_SUCCESS == status)
20384 {
Hoonki Lee14621352013-04-16 17:51:19 -070020385 if (pTdlsPeer->is_responder == 0)
20386 {
20387 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020388 tdlsConnInfo_t *tdlsInfo;
20389
20390 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
20391
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020392 if (!vos_timer_is_initialized(
20393 &pTdlsPeer->initiatorWaitTimeoutTimer))
20394 {
20395 /* Initialize initiator wait callback */
20396 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020397 &pTdlsPeer->initiatorWaitTimeoutTimer,
20398 VOS_TIMER_TYPE_SW,
20399 wlan_hdd_tdls_initiator_wait_cb,
20400 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020401 }
Hoonki Lee14621352013-04-16 17:51:19 -070020402 wlan_hdd_tdls_timer_restart(pAdapter,
20403 &pTdlsPeer->initiatorWaitTimeoutTimer,
20404 WAIT_TIME_TDLS_INITIATOR);
20405 /* suspend initiator TX until it receives direct packet from the
20406 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020407 ret = WLANTL_SuspendDataTx(
20408 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20409 &staId, NULL);
20410 if (ret != VOS_STATUS_SUCCESS) {
20411 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20412 }
Hoonki Lee14621352013-04-16 17:51:19 -070020413 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020414
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020415 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020416 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020417 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020418 suppChannelLen =
20419 tdlsLinkEstablishParams.supportedChannelsLen;
20420
20421 if ((suppChannelLen > 0) &&
20422 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20423 {
20424 tANI_U8 suppPeerChannel = 0;
20425 int i = 0;
20426 for (i = 0U; i < suppChannelLen; i++)
20427 {
20428 suppPeerChannel =
20429 tdlsLinkEstablishParams.supportedChannels[i];
20430
20431 pTdlsPeer->isOffChannelSupported = FALSE;
20432 if (suppPeerChannel ==
20433 pTdlsPeer->peerParams.channel)
20434 {
20435 pTdlsPeer->isOffChannelSupported = TRUE;
20436 break;
20437 }
20438 }
20439 }
20440 else
20441 {
20442 pTdlsPeer->isOffChannelSupported = FALSE;
20443 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020444 }
20445 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20446 "%s: TDLS channel switch request for channel "
20447 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020448 "%d isOffChannelSupported %d", __func__,
20449 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020450 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020451 suppChannelLen,
20452 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020453
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020454 /* TDLS Off Channel, Enable tdls channel switch,
20455 when their is only one tdls link and it supports */
20456 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20457 if ((numCurrTdlsPeers == 1) &&
20458 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20459 (TRUE == pTdlsPeer->isOffChannelConfigured))
20460 {
20461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20462 "%s: Send TDLS channel switch request for channel %d",
20463 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020464
20465 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020466 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20467 channel = pTdlsPeer->peerParams.channel;
20468
20469 mutex_unlock(&pHddCtx->tdls_lock);
20470
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020471 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20472 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020473 peerMac,
20474 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020475 TDLS_OFF_CHANNEL_BW_OFFSET,
20476 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020477 if (ret != VOS_STATUS_SUCCESS) {
20478 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20479 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020480 }
20481 else
20482 {
20483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20484 "%s: TDLS channel switch request not sent"
20485 " numCurrTdlsPeers %d "
20486 "isOffChannelSupported %d "
20487 "isOffChannelConfigured %d",
20488 __func__, numCurrTdlsPeers,
20489 pTdlsPeer->isOffChannelSupported,
20490 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020491 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020492 }
20493
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020494 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020495 else
20496 mutex_unlock(&pHddCtx->tdls_lock);
20497
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020498 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020499
20500 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020501 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
20502 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020503 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020504 int ac;
20505 uint8 ucAc[4] = { WLANTL_AC_VO,
20506 WLANTL_AC_VI,
20507 WLANTL_AC_BK,
20508 WLANTL_AC_BE };
20509 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
20510 for(ac=0; ac < 4; ac++)
20511 {
20512 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20513 pTdlsPeer->staId, ucAc[ac],
20514 tlTid[ac], tlTid[ac], 0, 0,
20515 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020516 if (status != VOS_STATUS_SUCCESS) {
20517 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
20518 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020519 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020520 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020521 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020522
Bhargav Shah66896792015-10-01 18:17:37 +053020523 /* stop TCP delack timer if TDLS is enable */
20524 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20525 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053020526 hdd_wlan_tdls_enable_link_event(peer,
20527 pTdlsPeer->isOffChannelSupported,
20528 pTdlsPeer->isOffChannelConfigured,
20529 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020530 }
20531 break;
20532 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080020533 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020534 tANI_U16 numCurrTdlsPeers = 0;
20535 hddTdlsPeer_t *connPeer = NULL;
20536
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20538 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
20539 __func__, MAC_ADDR_ARRAY(peer));
20540
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020541 mutex_lock(&pHddCtx->tdls_lock);
20542 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020543
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020544
Sunil Dutt41de4e22013-11-14 18:09:02 +053020545 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020546 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020547 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20548 " (oper %d) not exsting. ignored",
20549 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20550 return -EINVAL;
20551 }
20552
20553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20554 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20555 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20556 "NL80211_TDLS_DISABLE_LINK");
20557
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020558 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080020559 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020560 long status;
20561
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020562 /* set tdls off channel status to false for this peer */
20563 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053020564 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20565 eTDLS_LINK_TEARING,
20566 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
20567 eTDLS_LINK_UNSPECIFIED:
20568 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020569 mutex_unlock(&pHddCtx->tdls_lock);
20570
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020571 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
20572
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020573 status = sme_DeleteTdlsPeerSta(
20574 WLAN_HDD_GET_HAL_CTX(pAdapter),
20575 pAdapter->sessionId, peer );
20576 if (status != VOS_STATUS_SUCCESS) {
20577 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
20578 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020579
20580 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
20581 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020582
20583 mutex_lock(&pHddCtx->tdls_lock);
20584 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20585 if ( NULL == pTdlsPeer ) {
20586 mutex_unlock(&pHddCtx->tdls_lock);
20587 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20588 " peer was freed in other context",
20589 __func__, MAC_ADDR_ARRAY(peer));
20590 return -EINVAL;
20591 }
20592
Atul Mittal271a7652014-09-12 13:18:22 +053020593 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053020594 eTDLS_LINK_IDLE,
20595 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020596 mutex_unlock(&pHddCtx->tdls_lock);
20597
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020598 if (status <= 0)
20599 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20601 "%s: Del station failed status %ld",
20602 __func__, status);
20603 return -EPERM;
20604 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020605
20606 /* TDLS Off Channel, Enable tdls channel switch,
20607 when their is only one tdls link and it supports */
20608 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20609 if (numCurrTdlsPeers == 1)
20610 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020611 tSirMacAddr peerMac;
20612 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020613
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020614 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020615 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020616
20617 if (connPeer == NULL) {
20618 mutex_unlock(&pHddCtx->tdls_lock);
20619 hddLog(VOS_TRACE_LEVEL_ERROR,
20620 "%s connPeer is NULL", __func__);
20621 return -EINVAL;
20622 }
20623
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020624 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
20625 channel = connPeer->peerParams.channel;
20626
20627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20628 "%s: TDLS channel switch "
20629 "isOffChannelSupported %d "
20630 "isOffChannelConfigured %d "
20631 "isOffChannelEstablished %d",
20632 __func__,
20633 (connPeer ? connPeer->isOffChannelSupported : -1),
20634 (connPeer ? connPeer->isOffChannelConfigured : -1),
20635 (connPeer ? connPeer->isOffChannelEstablished : -1));
20636
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020637 if ((connPeer) &&
20638 (connPeer->isOffChannelSupported == TRUE) &&
20639 (connPeer->isOffChannelConfigured == TRUE))
20640 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020641 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020642 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020643 status = sme_SendTdlsChanSwitchReq(
20644 WLAN_HDD_GET_HAL_CTX(pAdapter),
20645 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020646 peerMac,
20647 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020648 TDLS_OFF_CHANNEL_BW_OFFSET,
20649 TDLS_CHANNEL_SWITCH_ENABLE);
20650 if (status != VOS_STATUS_SUCCESS) {
20651 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
20652 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020653 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020654 else
20655 mutex_unlock(&pHddCtx->tdls_lock);
20656 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020657 else
20658 {
20659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20660 "%s: TDLS channel switch request not sent "
20661 "numCurrTdlsPeers %d ",
20662 __func__, numCurrTdlsPeers);
20663 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020664 }
20665 else
20666 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020667 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20669 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080020670 }
Bhargav Shah66896792015-10-01 18:17:37 +053020671 if (numCurrTdlsPeers == 0) {
20672 /* start TCP delack timer if TDLS is disable */
20673 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20674 hdd_manage_delack_timer(pHddCtx);
20675 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020676 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020677 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020678 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020679 {
Atul Mittal115287b2014-07-08 13:26:33 +053020680 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020681
Atul Mittal115287b2014-07-08 13:26:33 +053020682 if (0 != status)
20683 {
20684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020685 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053020686 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020687 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053020688 break;
20689 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020690 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020691 {
Atul Mittal115287b2014-07-08 13:26:33 +053020692 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
20693 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020694 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053020695 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020696
Atul Mittal115287b2014-07-08 13:26:33 +053020697 if (0 != status)
20698 {
20699 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020700 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053020701 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053020702 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053020703 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020704 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020705 case NL80211_TDLS_DISCOVERY_REQ:
20706 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020707 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020708 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020709 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020710 return -ENOTSUPP;
20711 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020712 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20713 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020714 return -ENOTSUPP;
20715 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020716
20717 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020718 return 0;
20719}
Chilam NG571c65a2013-01-19 12:27:36 +053020720
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020721static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020722#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20723 const u8 *peer,
20724#else
20725 u8 *peer,
20726#endif
20727 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020728{
20729 int ret;
20730
20731 vos_ssr_protect(__func__);
20732 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
20733 vos_ssr_unprotect(__func__);
20734
20735 return ret;
20736}
20737
Chilam NG571c65a2013-01-19 12:27:36 +053020738int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
20739 struct net_device *dev, u8 *peer)
20740{
Arif Hussaina7c8e412013-11-20 11:06:42 -080020741 hddLog(VOS_TRACE_LEVEL_INFO,
20742 "tdls send discover req: "MAC_ADDRESS_STR,
20743 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020744#if TDLS_MGMT_VERSION2
20745 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20746 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20747#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020748#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20749 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20750 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
20751#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20752 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20753 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20754#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20755 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20756 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20757#else
Chilam NG571c65a2013-01-19 12:27:36 +053020758 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20759 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020760#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020761#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053020762}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020763#endif
20764
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020765#ifdef WLAN_FEATURE_GTK_OFFLOAD
20766/*
20767 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
20768 * Callback rountine called upon receiving response for
20769 * get offload info
20770 */
20771void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
20772 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
20773{
20774
20775 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020776 tANI_U8 tempReplayCounter[8];
20777 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020778
20779 ENTER();
20780
20781 if (NULL == pAdapter)
20782 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053020783 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020784 "%s: HDD adapter is Null", __func__);
20785 return ;
20786 }
20787
20788 if (NULL == pGtkOffloadGetInfoRsp)
20789 {
20790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20791 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
20792 return ;
20793 }
20794
20795 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
20796 {
20797 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20798 "%s: wlan Failed to get replay counter value",
20799 __func__);
20800 return ;
20801 }
20802
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020803 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20804 /* Update replay counter */
20805 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
20806 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
20807
20808 {
20809 /* changing from little to big endian since supplicant
20810 * works on big endian format
20811 */
20812 int i;
20813 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
20814
20815 for (i = 0; i < 8; i++)
20816 {
20817 tempReplayCounter[7-i] = (tANI_U8)p[i];
20818 }
20819 }
20820
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020821 /* Update replay counter to NL */
20822 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020823 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020824}
20825
20826/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020827 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020828 * This function is used to offload GTK rekeying job to the firmware.
20829 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020830int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020831 struct cfg80211_gtk_rekey_data *data)
20832{
20833 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20834 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
20835 hdd_station_ctx_t *pHddStaCtx;
20836 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020837 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020838 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020839 eHalStatus status = eHAL_STATUS_FAILURE;
20840
20841 ENTER();
20842
20843 if (NULL == pAdapter)
20844 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020846 "%s: HDD adapter is Null", __func__);
20847 return -ENODEV;
20848 }
20849
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020850 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20851 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
20852 pAdapter->sessionId, pAdapter->device_mode));
20853
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020854 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020855 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020856 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020857 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020858 }
20859
20860 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20861 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
20862 if (NULL == hHal)
20863 {
20864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20865 "%s: HAL context is Null!!!", __func__);
20866 return -EAGAIN;
20867 }
20868
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020869 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
20870 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
20871 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
20872 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020873 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020874 {
20875 /* changing from big to little endian since driver
20876 * works on little endian format
20877 */
20878 tANI_U8 *p =
20879 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
20880 int i;
20881
20882 for (i = 0; i < 8; i++)
20883 {
20884 p[7-i] = data->replay_ctr[i];
20885 }
20886 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020887
20888 if (TRUE == pHddCtx->hdd_wlan_suspended)
20889 {
20890 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020891 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
20892 sizeof (tSirGtkOffloadParams));
20893 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020894 pAdapter->sessionId);
20895
20896 if (eHAL_STATUS_SUCCESS != status)
20897 {
20898 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20899 "%s: sme_SetGTKOffload failed, returned %d",
20900 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020901
20902 /* Need to clear any trace of key value in the memory.
20903 * Thus zero out the memory even though it is local
20904 * variable.
20905 */
20906 vos_mem_zero(&hddGtkOffloadReqParams,
20907 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020908 return status;
20909 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020910 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20911 "%s: sme_SetGTKOffload successfull", __func__);
20912 }
20913 else
20914 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020915 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20916 "%s: wlan not suspended GTKOffload request is stored",
20917 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020918 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020919
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020920 /* Need to clear any trace of key value in the memory.
20921 * Thus zero out the memory even though it is local
20922 * variable.
20923 */
20924 vos_mem_zero(&hddGtkOffloadReqParams,
20925 sizeof(hddGtkOffloadReqParams));
20926
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020927 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020928 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020929}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020930
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020931int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
20932 struct cfg80211_gtk_rekey_data *data)
20933{
20934 int ret;
20935
20936 vos_ssr_protect(__func__);
20937 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
20938 vos_ssr_unprotect(__func__);
20939
20940 return ret;
20941}
20942#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020943/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020944 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020945 * This function is used to set access control policy
20946 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020947static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20948 struct net_device *dev,
20949 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020950{
20951 int i;
20952 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20953 hdd_hostapd_state_t *pHostapdState;
20954 tsap_Config_t *pConfig;
20955 v_CONTEXT_t pVosContext = NULL;
20956 hdd_context_t *pHddCtx;
20957 int status;
20958
20959 ENTER();
20960
20961 if (NULL == pAdapter)
20962 {
20963 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20964 "%s: HDD adapter is Null", __func__);
20965 return -ENODEV;
20966 }
20967
20968 if (NULL == params)
20969 {
20970 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20971 "%s: params is Null", __func__);
20972 return -EINVAL;
20973 }
20974
20975 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20976 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020977 if (0 != status)
20978 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020979 return status;
20980 }
20981
20982 pVosContext = pHddCtx->pvosContext;
20983 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
20984
20985 if (NULL == pHostapdState)
20986 {
20987 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20988 "%s: pHostapdState is Null", __func__);
20989 return -EINVAL;
20990 }
20991
20992 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
20993 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020994 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20995 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
20996 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020997
20998 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
20999 {
21000 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
21001
21002 /* default value */
21003 pConfig->num_accept_mac = 0;
21004 pConfig->num_deny_mac = 0;
21005
21006 /**
21007 * access control policy
21008 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
21009 * listed in hostapd.deny file.
21010 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
21011 * listed in hostapd.accept file.
21012 */
21013 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
21014 {
21015 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
21016 }
21017 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
21018 {
21019 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
21020 }
21021 else
21022 {
21023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21024 "%s:Acl Policy : %d is not supported",
21025 __func__, params->acl_policy);
21026 return -ENOTSUPP;
21027 }
21028
21029 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
21030 {
21031 pConfig->num_accept_mac = params->n_acl_entries;
21032 for (i = 0; i < params->n_acl_entries; i++)
21033 {
21034 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21035 "** Add ACL MAC entry %i in WhiletList :"
21036 MAC_ADDRESS_STR, i,
21037 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21038
21039 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
21040 sizeof(qcmacaddr));
21041 }
21042 }
21043 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
21044 {
21045 pConfig->num_deny_mac = params->n_acl_entries;
21046 for (i = 0; i < params->n_acl_entries; i++)
21047 {
21048 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21049 "** Add ACL MAC entry %i in BlackList :"
21050 MAC_ADDRESS_STR, i,
21051 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21052
21053 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
21054 sizeof(qcmacaddr));
21055 }
21056 }
21057
21058 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
21059 {
21060 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21061 "%s: SAP Set Mac Acl fail", __func__);
21062 return -EINVAL;
21063 }
21064 }
21065 else
21066 {
21067 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053021068 "%s: Invalid device_mode = %s (%d)",
21069 __func__, hdd_device_modetoString(pAdapter->device_mode),
21070 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021071 return -EINVAL;
21072 }
21073
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021074 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021075 return 0;
21076}
21077
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021078static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21079 struct net_device *dev,
21080 const struct cfg80211_acl_data *params)
21081{
21082 int ret;
21083 vos_ssr_protect(__func__);
21084 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
21085 vos_ssr_unprotect(__func__);
21086
21087 return ret;
21088}
21089
Leo Chang9056f462013-08-01 19:21:11 -070021090#ifdef WLAN_NL80211_TESTMODE
21091#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070021092void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070021093(
21094 void *pAdapter,
21095 void *indCont
21096)
21097{
Leo Changd9df8aa2013-09-26 13:32:26 -070021098 tSirLPHBInd *lphbInd;
21099 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053021100 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070021101
21102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021103 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070021104
c_hpothu73f35e62014-04-18 13:40:08 +053021105 if (pAdapter == NULL)
21106 {
21107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21108 "%s: pAdapter is NULL\n",__func__);
21109 return;
21110 }
21111
Leo Chang9056f462013-08-01 19:21:11 -070021112 if (NULL == indCont)
21113 {
21114 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021115 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070021116 return;
21117 }
21118
c_hpothu73f35e62014-04-18 13:40:08 +053021119 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070021120 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070021121 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053021122 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070021123 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070021124 GFP_ATOMIC);
21125 if (!skb)
21126 {
21127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21128 "LPHB timeout, NL buffer alloc fail");
21129 return;
21130 }
21131
Leo Changac3ba772013-10-07 09:47:04 -070021132 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070021133 {
21134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21135 "WLAN_HDD_TM_ATTR_CMD put fail");
21136 goto nla_put_failure;
21137 }
Leo Changac3ba772013-10-07 09:47:04 -070021138 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070021139 {
21140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21141 "WLAN_HDD_TM_ATTR_TYPE put fail");
21142 goto nla_put_failure;
21143 }
Leo Changac3ba772013-10-07 09:47:04 -070021144 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070021145 sizeof(tSirLPHBInd), lphbInd))
21146 {
21147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21148 "WLAN_HDD_TM_ATTR_DATA put fail");
21149 goto nla_put_failure;
21150 }
Leo Chang9056f462013-08-01 19:21:11 -070021151 cfg80211_testmode_event(skb, GFP_ATOMIC);
21152 return;
21153
21154nla_put_failure:
21155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21156 "NLA Put fail");
21157 kfree_skb(skb);
21158
21159 return;
21160}
21161#endif /* FEATURE_WLAN_LPHB */
21162
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021163static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070021164{
21165 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
21166 int err = 0;
21167#ifdef FEATURE_WLAN_LPHB
21168 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070021169 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021170
21171 ENTER();
21172
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021173 err = wlan_hdd_validate_context(pHddCtx);
21174 if (0 != err)
21175 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021176 return err;
21177 }
Leo Chang9056f462013-08-01 19:21:11 -070021178#endif /* FEATURE_WLAN_LPHB */
21179
21180 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
21181 if (err)
21182 {
21183 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21184 "%s Testmode INV ATTR", __func__);
21185 return err;
21186 }
21187
21188 if (!tb[WLAN_HDD_TM_ATTR_CMD])
21189 {
21190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21191 "%s Testmode INV CMD", __func__);
21192 return -EINVAL;
21193 }
21194
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021195 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21196 TRACE_CODE_HDD_CFG80211_TESTMODE,
21197 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070021198 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
21199 {
21200#ifdef FEATURE_WLAN_LPHB
21201 /* Low Power Heartbeat configuration request */
21202 case WLAN_HDD_TM_CMD_WLAN_HB:
21203 {
21204 int buf_len;
21205 void *buf;
21206 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080021207 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070021208
21209 if (!tb[WLAN_HDD_TM_ATTR_DATA])
21210 {
21211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21212 "%s Testmode INV DATA", __func__);
21213 return -EINVAL;
21214 }
21215
21216 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
21217 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080021218
Manjeet Singh3c577442017-02-10 19:03:38 +053021219 if (buf_len > sizeof(*hb_params)) {
21220 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
21221 buf_len);
21222 return -ERANGE;
21223 }
21224
Amar Singhal05852702014-02-04 14:40:00 -080021225 hb_params_temp =(tSirLPHBReq *)buf;
21226 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
21227 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
21228 return -EINVAL;
21229
Leo Chang9056f462013-08-01 19:21:11 -070021230 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
21231 if (NULL == hb_params)
21232 {
21233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21234 "%s Request Buffer Alloc Fail", __func__);
21235 return -EINVAL;
21236 }
21237
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053021238 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070021239 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070021240 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
21241 hb_params,
21242 wlan_hdd_cfg80211_lphb_ind_handler);
21243 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070021244 {
Leo Changd9df8aa2013-09-26 13:32:26 -070021245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21246 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070021247 vos_mem_free(hb_params);
21248 }
Leo Chang9056f462013-08-01 19:21:11 -070021249 return 0;
21250 }
21251#endif /* FEATURE_WLAN_LPHB */
21252 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21254 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070021255 return -EOPNOTSUPP;
21256 }
21257
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021258 EXIT();
21259 return err;
Leo Chang9056f462013-08-01 19:21:11 -070021260}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021261
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053021262static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
21263#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
21264 struct wireless_dev *wdev,
21265#endif
21266 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021267{
21268 int ret;
21269
21270 vos_ssr_protect(__func__);
21271 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
21272 vos_ssr_unprotect(__func__);
21273
21274 return ret;
21275}
Leo Chang9056f462013-08-01 19:21:11 -070021276#endif /* CONFIG_NL80211_TESTMODE */
21277
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021278extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021279static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021280 struct net_device *dev,
21281 int idx, struct survey_info *survey)
21282{
21283 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21284 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053021285 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021286 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053021287 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021288 v_S7_t snr,rssi;
21289 int status, i, j, filled = 0;
21290
21291 ENTER();
21292
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021293 if (NULL == pAdapter)
21294 {
21295 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21296 "%s: HDD adapter is Null", __func__);
21297 return -ENODEV;
21298 }
21299
21300 if (NULL == wiphy)
21301 {
21302 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21303 "%s: wiphy is Null", __func__);
21304 return -ENODEV;
21305 }
21306
21307 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21308 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021309 if (0 != status)
21310 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021311 return status;
21312 }
21313
Mihir Sheted9072e02013-08-21 17:02:29 +053021314 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21315
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021316 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053021317 0 != pAdapter->survey_idx ||
21318 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021319 {
21320 /* The survey dump ops when implemented completely is expected to
21321 * return a survey of all channels and the ops is called by the
21322 * kernel with incremental values of the argument 'idx' till it
21323 * returns -ENONET. But we can only support the survey for the
21324 * operating channel for now. survey_idx is used to track
21325 * that the ops is called only once and then return -ENONET for
21326 * the next iteration
21327 */
21328 pAdapter->survey_idx = 0;
21329 return -ENONET;
21330 }
21331
Mukul Sharma9d5233b2015-06-11 20:28:20 +053021332 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
21333 {
21334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21335 "%s: Roaming in progress, hence return ", __func__);
21336 return -ENONET;
21337 }
21338
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021339 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
21340
21341 wlan_hdd_get_snr(pAdapter, &snr);
21342 wlan_hdd_get_rssi(pAdapter, &rssi);
21343
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021344 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21345 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
21346 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021347 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
21348 hdd_wlan_get_freq(channel, &freq);
21349
21350
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053021351 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021352 {
21353 if (NULL == wiphy->bands[i])
21354 {
21355 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
21356 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
21357 continue;
21358 }
21359
21360 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
21361 {
21362 struct ieee80211_supported_band *band = wiphy->bands[i];
21363
21364 if (band->channels[j].center_freq == (v_U16_t)freq)
21365 {
21366 survey->channel = &band->channels[j];
21367 /* The Rx BDs contain SNR values in dB for the received frames
21368 * while the supplicant expects noise. So we calculate and
21369 * return the value of noise (dBm)
21370 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
21371 */
21372 survey->noise = rssi - snr;
21373 survey->filled = SURVEY_INFO_NOISE_DBM;
21374 filled = 1;
21375 }
21376 }
21377 }
21378
21379 if (filled)
21380 pAdapter->survey_idx = 1;
21381 else
21382 {
21383 pAdapter->survey_idx = 0;
21384 return -ENONET;
21385 }
21386
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021387 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021388 return 0;
21389}
21390
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021391static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
21392 struct net_device *dev,
21393 int idx, struct survey_info *survey)
21394{
21395 int ret;
21396
21397 vos_ssr_protect(__func__);
21398 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
21399 vos_ssr_unprotect(__func__);
21400
21401 return ret;
21402}
21403
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021404/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021405 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021406 * this is called when cfg80211 driver resume
21407 * driver updates latest sched_scan scan result(if any) to cfg80211 database
21408 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021409int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021410{
21411 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21412 hdd_adapter_t *pAdapter;
21413 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21414 VOS_STATUS status = VOS_STATUS_SUCCESS;
21415
21416 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021417
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021418 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021419 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021420 return 0;
21421 }
21422
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021423 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21424 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021425
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021426 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021427 {
21428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21429 "%s: Resume SoftAP", __func__);
21430 hdd_set_wlan_suspend_mode(false);
21431 }
21432
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021433 spin_lock(&pHddCtx->schedScan_lock);
21434 pHddCtx->isWiphySuspended = FALSE;
21435 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21436 {
21437 spin_unlock(&pHddCtx->schedScan_lock);
21438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21439 "%s: Return resume is not due to PNO indication", __func__);
21440 return 0;
21441 }
21442 // Reset flag to avoid updatating cfg80211 data old results again
21443 pHddCtx->isSchedScanUpdatePending = FALSE;
21444 spin_unlock(&pHddCtx->schedScan_lock);
21445
21446 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21447
21448 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21449 {
21450 pAdapter = pAdapterNode->pAdapter;
21451 if ( (NULL != pAdapter) &&
21452 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21453 {
21454 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021455 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021456 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21457 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021458 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021459 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021460 {
21461 /* Acquire wakelock to handle the case where APP's tries to
21462 * suspend immediately after updating the scan results. Whis
21463 * results in app's is in suspended state and not able to
21464 * process the connect request to AP
21465 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021466 hdd_prevent_suspend_timeout(2000,
21467 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021468 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021469 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021470
21471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21472 "%s : cfg80211 scan result database updated", __func__);
21473
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021474 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021475 return 0;
21476
21477 }
21478 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21479 pAdapterNode = pNext;
21480 }
21481
21482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21483 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021484 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021485 return 0;
21486}
21487
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021488int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21489{
21490 int ret;
21491
21492 vos_ssr_protect(__func__);
21493 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
21494 vos_ssr_unprotect(__func__);
21495
21496 return ret;
21497}
21498
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021499/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021500 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021501 * this is called when cfg80211 driver suspends
21502 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021503int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021504 struct cfg80211_wowlan *wow)
21505{
21506 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021507 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021508
21509 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021510
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021511 ret = wlan_hdd_validate_context(pHddCtx);
21512 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021513 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021514 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021515 }
21516
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021517 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021518 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21519 "%s: Suspend SoftAP", __func__);
21520 hdd_set_wlan_suspend_mode(true);
21521 }
21522
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021523
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021524 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21525 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
21526 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021527 pHddCtx->isWiphySuspended = TRUE;
21528
21529 EXIT();
21530
21531 return 0;
21532}
21533
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021534int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
21535 struct cfg80211_wowlan *wow)
21536{
21537 int ret;
21538
21539 vos_ssr_protect(__func__);
21540 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
21541 vos_ssr_unprotect(__func__);
21542
21543 return ret;
21544}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021545
21546#ifdef FEATURE_OEM_DATA_SUPPORT
21547static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021548 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021549{
21550 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21551
21552 ENTER();
21553
21554 if (wlan_hdd_validate_context(pHddCtx)) {
21555 return;
21556 }
21557 if (!pMsg)
21558 {
21559 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
21560 return;
21561 }
21562
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021563 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021564
21565 EXIT();
21566 return;
21567
21568}
21569
21570void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021571 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021572{
21573 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21574
21575 ENTER();
21576
21577 if (wlan_hdd_validate_context(pHddCtx)) {
21578 return;
21579 }
21580
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021581 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021582
21583 switch(evType) {
21584 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021585 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021586 break;
21587 default:
21588 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
21589 break;
21590 }
21591 EXIT();
21592}
21593#endif
21594
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021595#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21596 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021597/**
21598 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
21599 * @wiphy: Pointer to wiphy
21600 * @wdev: Pointer to wireless device structure
21601 *
21602 * This function is used to abort an ongoing scan
21603 *
21604 * Return: None
21605 */
21606static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21607 struct wireless_dev *wdev)
21608{
21609 struct net_device *dev = wdev->netdev;
21610 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21611 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
21612 int ret;
21613
21614 ENTER();
21615
21616 if (NULL == adapter) {
21617 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
21618 return;
21619 }
21620
21621 ret = wlan_hdd_validate_context(hdd_ctx);
21622 if (0 != ret)
21623 return;
21624
21625 wlan_hdd_scan_abort(adapter);
21626
21627 return;
21628}
21629
21630/**
21631 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
21632 * @wiphy: Pointer to wiphy
21633 * @wdev: Pointer to wireless device structure
21634 *
21635 * Return: None
21636 */
21637void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21638 struct wireless_dev *wdev)
21639{
21640 vos_ssr_protect(__func__);
21641 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
21642 vos_ssr_unprotect(__func__);
21643
21644 return;
21645}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021646#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021647
Abhishek Singh936c6932017-11-07 17:28:23 +053021648#ifdef CHANNEL_SWITCH_SUPPORTED
21649/**
21650 * __wlan_hdd_cfg80211_channel_switch()- function to switch
21651 * channel in SAP/GO
21652 * @wiphy: wiphy pointer
21653 * @dev: dev pointer.
21654 * @csa_params: Change channel params
21655 *
21656 * This function is called to switch channel in SAP/GO
21657 *
21658 * Return: 0 if success else return non zero
21659 */
21660static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21661 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21662{
21663 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21664 hdd_context_t *hdd_ctx;
21665 uint8_t channel;
21666 int ret;
21667 v_CONTEXT_t vos_ctx;
21668
21669 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
21670
21671 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
21672 ret = wlan_hdd_validate_context(hdd_ctx);
21673 if (ret)
21674 return ret;
21675
21676 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
21677 if (!vos_ctx) {
21678 hddLog(LOGE, FL("Vos ctx is null"));
21679 return -EINVAL;
21680 }
21681
21682 if ((WLAN_HDD_SOFTAP != adapter->device_mode) &&
21683 (WLAN_HDD_P2P_GO != adapter->device_mode))
21684 return -ENOTSUPP;
21685
21686 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053021687 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053021688
21689 return ret;
21690}
21691
21692/**
21693 * wlan_hdd_cfg80211_channel_switch()- function to switch
21694 * channel in SAP/GO
21695 * @wiphy: wiphy pointer
21696 * @dev: dev pointer.
21697 * @csa_params: Change channel params
21698 *
21699 * This function is called to switch channel in SAP/GO
21700 *
21701 * Return: 0 if success else return non zero
21702 */
21703static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21704 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21705{
21706 int ret;
21707
21708 vos_ssr_protect(__func__);
21709 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
21710 vos_ssr_unprotect(__func__);
21711
21712 return ret;
21713}
21714#endif
21715
Jeff Johnson295189b2012-06-20 16:38:30 -070021716/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053021717static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070021718{
21719 .add_virtual_intf = wlan_hdd_add_virtual_intf,
21720 .del_virtual_intf = wlan_hdd_del_virtual_intf,
21721 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
21722 .change_station = wlan_hdd_change_station,
21723#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
21724 .add_beacon = wlan_hdd_cfg80211_add_beacon,
21725 .del_beacon = wlan_hdd_cfg80211_del_beacon,
21726 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021727#else
21728 .start_ap = wlan_hdd_cfg80211_start_ap,
21729 .change_beacon = wlan_hdd_cfg80211_change_beacon,
21730 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070021731#endif
21732 .change_bss = wlan_hdd_cfg80211_change_bss,
21733 .add_key = wlan_hdd_cfg80211_add_key,
21734 .get_key = wlan_hdd_cfg80211_get_key,
21735 .del_key = wlan_hdd_cfg80211_del_key,
21736 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021737#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070021738 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021739#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021740 .scan = wlan_hdd_cfg80211_scan,
21741 .connect = wlan_hdd_cfg80211_connect,
21742 .disconnect = wlan_hdd_cfg80211_disconnect,
21743 .join_ibss = wlan_hdd_cfg80211_join_ibss,
21744 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
21745 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
21746 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
21747 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070021748 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
21749 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053021750 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070021751#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
21752 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
21753 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
21754 .set_txq_params = wlan_hdd_set_txq_params,
21755#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021756 .get_station = wlan_hdd_cfg80211_get_station,
21757 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
21758 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021759 .add_station = wlan_hdd_cfg80211_add_station,
21760#ifdef FEATURE_WLAN_LFR
21761 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
21762 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
21763 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
21764#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070021765#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
21766 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
21767#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021768#ifdef FEATURE_WLAN_TDLS
21769 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
21770 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
21771#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021772#ifdef WLAN_FEATURE_GTK_OFFLOAD
21773 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
21774#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053021775#ifdef FEATURE_WLAN_SCAN_PNO
21776 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
21777 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
21778#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021779 .resume = wlan_hdd_cfg80211_resume_wlan,
21780 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021781 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070021782#ifdef WLAN_NL80211_TESTMODE
21783 .testmode_cmd = wlan_hdd_cfg80211_testmode,
21784#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021785 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021786#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21787 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021788 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021789#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053021790#ifdef CHANNEL_SWITCH_SUPPORTED
21791 .channel_switch = wlan_hdd_cfg80211_channel_switch,
21792#endif
21793
Jeff Johnson295189b2012-06-20 16:38:30 -070021794};
21795