blob: 10e21420a962d6b54153054ecc4bee0f3811747f [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05302 * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053066#include <linux/etherdevice.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067#include <wlan_hdd_includes.h>
68#include <net/arp.h>
69#include <net/cfg80211.h>
70#include <linux/wireless.h>
71#include <wlan_hdd_wowl.h>
72#include <aniGlobal.h>
73#include "ccmApi.h"
74#include "sirParams.h"
75#include "dot11f.h"
76#include "wlan_hdd_assoc.h"
77#include "wlan_hdd_wext.h"
78#include "sme_Api.h"
79#include "wlan_hdd_p2p.h"
80#include "wlan_hdd_cfg80211.h"
81#include "wlan_hdd_hostapd.h"
82#include "sapInternal.h"
83#include "wlan_hdd_softap_tx_rx.h"
84#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053085#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053086#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053087#include "wlan_hdd_trace.h"
88#include "vos_types.h"
89#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070090#ifdef WLAN_BTAMP_FEATURE
91#include "bap_hdd_misc.h"
92#endif
93#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080094#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053095#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053096#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053097#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070098#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053099#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +0530100#include "wlan_logging_sock_svc.h"
Agrawal Ashishcfe83282016-09-29 13:03:45 +0530101#include "wlan_hdd_misc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530102
Jeff Johnson295189b2012-06-20 16:38:30 -0700103
104#define g_mode_rates_size (12)
105#define a_mode_rates_size (8)
106#define FREQ_BASE_80211G (2407)
107#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700108#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530109#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800111 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700112
113#define HDD2GHZCHAN(freq, chan, flag) { \
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530114 .band = HDD_NL80211_BAND_2GHZ, \
Jeff Johnson295189b2012-06-20 16:38:30 -0700115 .center_freq = (freq), \
116 .hw_value = (chan),\
117 .flags = (flag), \
118 .max_antenna_gain = 0 ,\
119 .max_power = 30, \
120}
121
122#define HDD5GHZCHAN(freq, chan, flag) { \
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530123 .band = HDD_NL80211_BAND_5GHZ, \
Jeff Johnson295189b2012-06-20 16:38:30 -0700124 .center_freq = (freq), \
125 .hw_value = (chan),\
126 .flags = (flag), \
127 .max_antenna_gain = 0 ,\
128 .max_power = 30, \
129}
130
131#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
132{\
133 .bitrate = rate, \
134 .hw_value = rate_id, \
135 .flags = flag, \
136}
137
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530138#ifdef WLAN_FEATURE_VOWIFI_11R
139#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
140#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
141#endif
142
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530143#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530144#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530145
Sunil Duttc69bccb2014-05-26 21:30:20 +0530146#ifdef WLAN_FEATURE_LINK_LAYER_STATS
147/*
148 * Used to allocate the size of 4096 for the link layer stats.
149 * The size of 4096 is considered assuming that all data per
150 * respective event fit with in the limit.Please take a call
151 * on the limit based on the data requirements on link layer
152 * statistics.
153 */
154#define LL_STATS_EVENT_BUF_SIZE 4096
155#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530156#ifdef WLAN_FEATURE_EXTSCAN
157/*
158 * Used to allocate the size of 4096 for the EXTScan NL data.
159 * The size of 4096 is considered assuming that all data per
160 * respective event fit with in the limit.Please take a call
161 * on the limit based on the data requirements.
162 */
163
164#define EXTSCAN_EVENT_BUF_SIZE 4096
165#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
166#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530167
Atul Mittal115287b2014-07-08 13:26:33 +0530168/*EXT TDLS*/
169/*
170 * Used to allocate the size of 4096 for the TDLS.
171 * The size of 4096 is considered assuming that all data per
172 * respective event fit with in the limit.Please take a call
173 * on the limit based on the data requirements on link layer
174 * statistics.
175 */
176#define EXTTDLS_EVENT_BUF_SIZE 4096
177
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530178/*
179 * Values for Mac spoofing feature
180 *
181 */
182#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
183#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
184#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530185#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
186
Anurag Chouhan343af7e2016-12-16 13:11:19 +0530187/*
188 * max_sched_scan_plans defined to 10
189 */
190#define MAX_SCHED_SCAN_PLANS 10
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530191
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530192static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700193{
194 WLAN_CIPHER_SUITE_WEP40,
195 WLAN_CIPHER_SUITE_WEP104,
196 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800197#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700198#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
199 WLAN_CIPHER_SUITE_KRK,
200 WLAN_CIPHER_SUITE_CCMP,
201#else
202 WLAN_CIPHER_SUITE_CCMP,
203#endif
204#ifdef FEATURE_WLAN_WAPI
205 WLAN_CIPHER_SUITE_SMS4,
206#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700207#ifdef WLAN_FEATURE_11W
208 WLAN_CIPHER_SUITE_AES_CMAC,
209#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700210};
211
Agrawal Ashish97dec502015-11-26 20:20:58 +0530212const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530213{
Jeff Johnson295189b2012-06-20 16:38:30 -0700214 HDD2GHZCHAN(2412, 1, 0) ,
215 HDD2GHZCHAN(2417, 2, 0) ,
216 HDD2GHZCHAN(2422, 3, 0) ,
217 HDD2GHZCHAN(2427, 4, 0) ,
218 HDD2GHZCHAN(2432, 5, 0) ,
219 HDD2GHZCHAN(2437, 6, 0) ,
220 HDD2GHZCHAN(2442, 7, 0) ,
221 HDD2GHZCHAN(2447, 8, 0) ,
222 HDD2GHZCHAN(2452, 9, 0) ,
223 HDD2GHZCHAN(2457, 10, 0) ,
224 HDD2GHZCHAN(2462, 11, 0) ,
225 HDD2GHZCHAN(2467, 12, 0) ,
226 HDD2GHZCHAN(2472, 13, 0) ,
227 HDD2GHZCHAN(2484, 14, 0) ,
228};
229
Agrawal Ashish97dec502015-11-26 20:20:58 +0530230const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700231{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700232 HDD5GHZCHAN(4920, 240, 0) ,
233 HDD5GHZCHAN(4940, 244, 0) ,
234 HDD5GHZCHAN(4960, 248, 0) ,
235 HDD5GHZCHAN(4980, 252, 0) ,
236 HDD5GHZCHAN(5040, 208, 0) ,
237 HDD5GHZCHAN(5060, 212, 0) ,
238 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 HDD5GHZCHAN(5180, 36, 0) ,
240 HDD5GHZCHAN(5200, 40, 0) ,
241 HDD5GHZCHAN(5220, 44, 0) ,
242 HDD5GHZCHAN(5240, 48, 0) ,
243 HDD5GHZCHAN(5260, 52, 0) ,
244 HDD5GHZCHAN(5280, 56, 0) ,
245 HDD5GHZCHAN(5300, 60, 0) ,
246 HDD5GHZCHAN(5320, 64, 0) ,
247 HDD5GHZCHAN(5500,100, 0) ,
248 HDD5GHZCHAN(5520,104, 0) ,
249 HDD5GHZCHAN(5540,108, 0) ,
250 HDD5GHZCHAN(5560,112, 0) ,
251 HDD5GHZCHAN(5580,116, 0) ,
252 HDD5GHZCHAN(5600,120, 0) ,
253 HDD5GHZCHAN(5620,124, 0) ,
254 HDD5GHZCHAN(5640,128, 0) ,
255 HDD5GHZCHAN(5660,132, 0) ,
256 HDD5GHZCHAN(5680,136, 0) ,
257 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800258#ifdef FEATURE_WLAN_CH144
259 HDD5GHZCHAN(5720,144, 0) ,
260#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 HDD5GHZCHAN(5745,149, 0) ,
262 HDD5GHZCHAN(5765,153, 0) ,
263 HDD5GHZCHAN(5785,157, 0) ,
264 HDD5GHZCHAN(5805,161, 0) ,
265 HDD5GHZCHAN(5825,165, 0) ,
266};
267
268static struct ieee80211_rate g_mode_rates[] =
269{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530270 HDD_G_MODE_RATETAB(10, 0x1, 0),
271 HDD_G_MODE_RATETAB(20, 0x2, 0),
272 HDD_G_MODE_RATETAB(55, 0x4, 0),
273 HDD_G_MODE_RATETAB(110, 0x8, 0),
274 HDD_G_MODE_RATETAB(60, 0x10, 0),
275 HDD_G_MODE_RATETAB(90, 0x20, 0),
276 HDD_G_MODE_RATETAB(120, 0x40, 0),
277 HDD_G_MODE_RATETAB(180, 0x80, 0),
278 HDD_G_MODE_RATETAB(240, 0x100, 0),
279 HDD_G_MODE_RATETAB(360, 0x200, 0),
280 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530282};
Jeff Johnson295189b2012-06-20 16:38:30 -0700283
284static struct ieee80211_rate a_mode_rates[] =
285{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530286 HDD_G_MODE_RATETAB(60, 0x10, 0),
287 HDD_G_MODE_RATETAB(90, 0x20, 0),
288 HDD_G_MODE_RATETAB(120, 0x40, 0),
289 HDD_G_MODE_RATETAB(180, 0x80, 0),
290 HDD_G_MODE_RATETAB(240, 0x100, 0),
291 HDD_G_MODE_RATETAB(360, 0x200, 0),
292 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 HDD_G_MODE_RATETAB(540, 0x800, 0),
294};
295
296static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
297{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530298 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700299 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530300 .band = HDD_NL80211_BAND_2GHZ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700301 .bitrates = g_mode_rates,
302 .n_bitrates = g_mode_rates_size,
303 .ht_cap.ht_supported = 1,
304 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
305 | IEEE80211_HT_CAP_GRN_FLD
306 | IEEE80211_HT_CAP_DSSSCCK40
307 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
308 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
309 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
310 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
311 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
312 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
313};
314
Jeff Johnson295189b2012-06-20 16:38:30 -0700315static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
316{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530317 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700318 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530319 .band = HDD_NL80211_BAND_5GHZ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700320 .bitrates = a_mode_rates,
321 .n_bitrates = a_mode_rates_size,
322 .ht_cap.ht_supported = 1,
323 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
324 | IEEE80211_HT_CAP_GRN_FLD
325 | IEEE80211_HT_CAP_DSSSCCK40
326 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
327 | IEEE80211_HT_CAP_SGI_40
328 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
329 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
330 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
331 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
332 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
333 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
334};
335
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530336/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700337 TX/RX direction for each kind of interface */
338static const struct ieee80211_txrx_stypes
339wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
340 [NL80211_IFTYPE_STATION] = {
341 .tx = 0xffff,
342 .rx = BIT(SIR_MAC_MGMT_ACTION) |
343 BIT(SIR_MAC_MGMT_PROBE_REQ),
344 },
345 [NL80211_IFTYPE_AP] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
348 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
349 BIT(SIR_MAC_MGMT_PROBE_REQ) |
350 BIT(SIR_MAC_MGMT_DISASSOC) |
351 BIT(SIR_MAC_MGMT_AUTH) |
352 BIT(SIR_MAC_MGMT_DEAUTH) |
353 BIT(SIR_MAC_MGMT_ACTION),
354 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700355 [NL80211_IFTYPE_ADHOC] = {
356 .tx = 0xffff,
357 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
358 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
359 BIT(SIR_MAC_MGMT_PROBE_REQ) |
360 BIT(SIR_MAC_MGMT_DISASSOC) |
361 BIT(SIR_MAC_MGMT_AUTH) |
362 BIT(SIR_MAC_MGMT_DEAUTH) |
363 BIT(SIR_MAC_MGMT_ACTION),
364 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700365 [NL80211_IFTYPE_P2P_CLIENT] = {
366 .tx = 0xffff,
367 .rx = BIT(SIR_MAC_MGMT_ACTION) |
368 BIT(SIR_MAC_MGMT_PROBE_REQ),
369 },
370 [NL80211_IFTYPE_P2P_GO] = {
371 /* This is also same as for SoftAP */
372 .tx = 0xffff,
373 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
374 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
375 BIT(SIR_MAC_MGMT_PROBE_REQ) |
376 BIT(SIR_MAC_MGMT_DISASSOC) |
377 BIT(SIR_MAC_MGMT_AUTH) |
378 BIT(SIR_MAC_MGMT_DEAUTH) |
379 BIT(SIR_MAC_MGMT_ACTION),
380 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700381};
382
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800383#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800384static const struct ieee80211_iface_limit
385wlan_hdd_iface_limit[] = {
386 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800387 /* max = 3 ; Our driver create two interfaces during driver init
388 * wlan0 and p2p0 interfaces. p2p0 is considered as station
389 * interface until a group is formed. In JB architecture, once the
390 * group is formed, interface type of p2p0 is changed to P2P GO or
391 * Client.
392 * When supplicant remove the group, it first issue a set interface
393 * cmd to change the mode back to Station. In JB this works fine as
394 * we advertize two station type interface during driver init.
395 * Some vendors create separate interface for P2P GO/Client,
396 * after group formation(Third one). But while group remove
397 * supplicant first tries to change the mode(3rd interface) to STATION
398 * But as we advertized only two sta type interfaces nl80211 was
399 * returning error for the third one which was leading to failure in
400 * delete interface. Ideally while removing the group, supplicant
401 * should not try to change the 3rd interface mode to Station type.
402 * Till we get a fix in wpa_supplicant, we advertize max STA
403 * interface type to 3
404 */
405 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800406 .types = BIT(NL80211_IFTYPE_STATION),
407 },
408 {
409 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700410 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 },
412 {
413 .max = 1,
414 .types = BIT(NL80211_IFTYPE_P2P_GO) |
415 BIT(NL80211_IFTYPE_P2P_CLIENT),
416 },
417};
418
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530419/* interface limits for sta + monitor SCC */
420static const struct ieee80211_iface_limit
421wlan_hdd_iface_sta_mon_limit[] = {
422 {
423 .max = 1,
424 .types = BIT(NL80211_IFTYPE_STATION),
425 },
426 {
427 .max = 1, /* Monitor interface */
428 .types = BIT(NL80211_IFTYPE_MONITOR),
429 },
430};
431
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800432/* By default, only single channel concurrency is allowed */
433static struct ieee80211_iface_combination
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530434wlan_hdd_iface_combination[] = {
435 {
436 .limits = wlan_hdd_iface_limit,
437 .num_different_channels = 1,
438 /*
439 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
440 * and p2p0 interfaces during driver init
441 * Some vendors create separate interface for P2P operations.
442 * wlan0: STA interface
443 * p2p0: P2P Device interface, action frames goes
444 * through this interface.
445 * p2p-xx: P2P interface, After GO negotiation this interface is
446 * created for p2p operations(GO/CLIENT interface).
447 */
448 .max_interfaces = WLAN_MAX_INTERFACES,
449 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
450 .beacon_int_infra_match = false,
451 },
452 {
453 .limits = wlan_hdd_iface_sta_mon_limit,
454 .num_different_channels = 1,
455 .max_interfaces = WLAN_STA_AND_MON_INTERFACES,
456 .n_limits = ARRAY_SIZE(wlan_hdd_iface_sta_mon_limit),
457 .beacon_int_infra_match = false,
458 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800459};
460#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800461
Nachiket Kukade5b2e7332018-04-06 14:40:22 +0530462#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
463static const struct wiphy_wowlan_support wowlan_support_cfg80211_init = {
Nachiket Kukade1e1b90e2018-05-10 15:26:13 +0530464 .flags = WIPHY_WOWLAN_ANY |
465 WIPHY_WOWLAN_MAGIC_PKT,
Nachiket Kukade5b2e7332018-04-06 14:40:22 +0530466 .n_patterns = WOWL_MAX_PTRNS_ALLOWED,
467 .pattern_min_len = 1,
468 .pattern_max_len = WOWL_PTRN_MAX_SIZE,
469};
470#endif
471
Jeff Johnson295189b2012-06-20 16:38:30 -0700472static struct cfg80211_ops wlan_hdd_cfg80211_ops;
473
474/* Data rate 100KBPS based on IE Index */
475struct index_data_rate_type
476{
477 v_U8_t beacon_rate_index;
478 v_U16_t supported_rate[4];
479};
480
481/* 11B, 11G Rate table include Basic rate and Extended rate
482 The IDX field is the rate index
483 The HI field is the rate when RSSI is strong or being ignored
484 (in this case we report actual rate)
485 The MID field is the rate when RSSI is moderate
486 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
487 The LO field is the rate when RSSI is low
488 (in this case we don't report rates, actual current rate used)
489 */
490static const struct
491{
492 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700493 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700494} supported_data_rate[] =
495{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700496/* IDX HI HM LM LO (RSSI-based index */
497 {2, { 10, 10, 10, 0}},
498 {4, { 20, 20, 10, 0}},
499 {11, { 55, 20, 10, 0}},
500 {12, { 60, 55, 20, 0}},
501 {18, { 90, 55, 20, 0}},
502 {22, {110, 55, 20, 0}},
503 {24, {120, 90, 60, 0}},
504 {36, {180, 120, 60, 0}},
505 {44, {220, 180, 60, 0}},
506 {48, {240, 180, 90, 0}},
507 {66, {330, 180, 90, 0}},
508 {72, {360, 240, 90, 0}},
509 {96, {480, 240, 120, 0}},
510 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700511};
512
513/* MCS Based rate table */
514static struct index_data_rate_type supported_mcs_rate[] =
515{
516/* MCS L20 L40 S20 S40 */
517 {0, {65, 135, 72, 150}},
518 {1, {130, 270, 144, 300}},
519 {2, {195, 405, 217, 450}},
520 {3, {260, 540, 289, 600}},
521 {4, {390, 810, 433, 900}},
522 {5, {520, 1080, 578, 1200}},
523 {6, {585, 1215, 650, 1350}},
524 {7, {650, 1350, 722, 1500}}
525};
526
Leo Chang6f8870f2013-03-26 18:11:36 -0700527#ifdef WLAN_FEATURE_11AC
528
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530529#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700530
531struct index_vht_data_rate_type
532{
533 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530534 v_U16_t supported_VHT80_rate[2];
535 v_U16_t supported_VHT40_rate[2];
536 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700537};
538
539typedef enum
540{
541 DATA_RATE_11AC_MAX_MCS_7,
542 DATA_RATE_11AC_MAX_MCS_8,
543 DATA_RATE_11AC_MAX_MCS_9,
544 DATA_RATE_11AC_MAX_MCS_NA
545} eDataRate11ACMaxMcs;
546
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530547/* SSID broadcast type */
548typedef enum eSSIDBcastType
549{
550 eBCAST_UNKNOWN = 0,
551 eBCAST_NORMAL = 1,
552 eBCAST_HIDDEN = 2,
553} tSSIDBcastType;
554
Leo Chang6f8870f2013-03-26 18:11:36 -0700555/* MCS Based VHT rate table */
556static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
557{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530558/* MCS L80 S80 L40 S40 L20 S40*/
559 {0, {293, 325}, {135, 150}, {65, 72}},
560 {1, {585, 650}, {270, 300}, {130, 144}},
561 {2, {878, 975}, {405, 450}, {195, 217}},
562 {3, {1170, 1300}, {540, 600}, {260, 289}},
563 {4, {1755, 1950}, {810, 900}, {390, 433}},
564 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
565 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
566 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
567 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
568 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700569};
570#endif /* WLAN_FEATURE_11AC */
571
c_hpothu79aab322014-07-14 21:11:01 +0530572/*array index points to MCS and array value points respective rssi*/
573static int rssiMcsTbl[][10] =
574{
575/*MCS 0 1 2 3 4 5 6 7 8 9*/
576 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
577 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
578 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
579};
580
Jeff Johnson295189b2012-06-20 16:38:30 -0700581extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530582#ifdef FEATURE_WLAN_SCAN_PNO
583static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
584#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700585
Leo Chang9056f462013-08-01 19:21:11 -0700586#ifdef WLAN_NL80211_TESTMODE
587enum wlan_hdd_tm_attr
588{
589 WLAN_HDD_TM_ATTR_INVALID = 0,
590 WLAN_HDD_TM_ATTR_CMD = 1,
591 WLAN_HDD_TM_ATTR_DATA = 2,
592 WLAN_HDD_TM_ATTR_TYPE = 3,
593 /* keep last */
594 WLAN_HDD_TM_ATTR_AFTER_LAST,
595 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
596};
597
598enum wlan_hdd_tm_cmd
599{
600 WLAN_HDD_TM_CMD_WLAN_HB = 1,
601};
602
603#define WLAN_HDD_TM_DATA_MAX_LEN 5000
604
605static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
606{
607 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
608 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
609 .len = WLAN_HDD_TM_DATA_MAX_LEN },
610};
611#endif /* WLAN_NL80211_TESTMODE */
612
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800613#ifdef FEATURE_WLAN_CH_AVOID
614/*
615 * FUNCTION: wlan_hdd_send_avoid_freq_event
616 * This is called when wlan driver needs to send vendor specific
617 * avoid frequency range event to userspace
618 */
619int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
620 tHddAvoidFreqList *pAvoidFreqList)
621{
622 struct sk_buff *vendor_event;
623
624 ENTER();
625
626 if (!pHddCtx)
627 {
628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
629 "%s: HDD context is null", __func__);
630 return -1;
631 }
632
633 if (!pAvoidFreqList)
634 {
635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
636 "%s: pAvoidFreqList is null", __func__);
637 return -1;
638 }
639
640 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530641#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
642 NULL,
643#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800644 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530645 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800646 GFP_KERNEL);
647 if (!vendor_event)
648 {
649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
650 "%s: cfg80211_vendor_event_alloc failed", __func__);
651 return -1;
652 }
653
654 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
655 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
656
657 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
658
659 EXIT();
660 return 0;
661}
662#endif /* FEATURE_WLAN_CH_AVOID */
663
Srinivas Dasari030bad32015-02-18 23:23:54 +0530664/*
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +0530665 * define short names for the global vendor params
666 * used by QCA_NL80211_VENDOR_SUBCMD_HANG
667 */
668#define HANG_REASON_INDEX QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX
669
670/**
671 * hdd_convert_hang_reason() - Convert cds recovery reason to vendor specific
672 * hang reason
673 * @reason: cds recovery reason
674 *
675 * Return: Vendor specific reason code
676 */
677static enum qca_wlan_vendor_hang_reason
678hdd_convert_hang_reason(enum vos_hang_reason reason)
679{
680 unsigned int ret_val;
681
682 switch (reason) {
683 case VOS_GET_MSG_BUFF_FAILURE:
684 ret_val = QCA_WLAN_HANG_GET_MSG_BUFF_FAILURE;
685 break;
686 case VOS_ACTIVE_LIST_TIMEOUT:
687 ret_val = QCA_WLAN_HANG_ACTIVE_LIST_TIMEOUT;
688 break;
689 case VOS_SCAN_REQ_EXPIRED:
690 ret_val = QCA_WLAN_HANG_SCAN_REQ_EXPIRED;
691 break;
692 case VOS_TRANSMISSIONS_TIMEOUT:
693 ret_val = QCA_WLAN_HANG_TRANSMISSIONS_TIMEOUT;
694 break;
695 case VOS_DXE_FAILURE:
696 ret_val = QCA_WLAN_HANG_DXE_FAILURE;
697 break;
698 case VOS_WDI_FAILURE:
699 ret_val = QCA_WLAN_HANG_WDI_FAILURE;
700 break;
701 case VOS_REASON_UNSPECIFIED:
702 default:
703 ret_val = QCA_WLAN_HANG_REASON_UNSPECIFIED;
704 }
705 return ret_val;
706}
707
708/**
709 * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace
710 * @hdd_ctx: Pointer to hdd context
711 * @reason: cds recovery reason
712 *
713 * Return: 0 on success or failure reason
714 */
715int wlan_hdd_send_hang_reason_event(hdd_context_t *hdd_ctx,
716 enum vos_hang_reason reason)
717{
718 struct sk_buff *vendor_event;
719 enum qca_wlan_vendor_hang_reason hang_reason;
720
721 ENTER();
722
723 if (!hdd_ctx) {
724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
725 "HDD context is null");
726 return -EINVAL;
727 }
728
729 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
730#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
731 NULL,
732#endif
733 sizeof(unsigned int),
734 HANG_REASON_INDEX,
735 GFP_KERNEL);
736 if (!vendor_event) {
737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
738 "cfg80211_vendor_event_alloc failed");
739 return -ENOMEM;
740 }
741
742 hang_reason = hdd_convert_hang_reason(reason);
743
744 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_HANG_REASON,
745 (unsigned int) hang_reason)) {
746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
747 "QCA_WLAN_VENDOR_ATTR_HANG_REASON put fail");
748 kfree_skb(vendor_event);
749 return -EINVAL;
750 }
751
752 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
753
754 EXIT();
755 return 0;
756}
757#undef HANG_REASON_INDEX
758
759/*
Srinivas Dasari030bad32015-02-18 23:23:54 +0530760 * FUNCTION: __wlan_hdd_cfg80211_nan_request
761 * This is called when wlan driver needs to send vendor specific
762 * nan request event.
763 */
764static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
765 struct wireless_dev *wdev,
766 const void *data, int data_len)
767{
768 tNanRequestReq nan_req;
769 VOS_STATUS status;
770 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530771 struct net_device *dev = wdev->netdev;
772 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
773 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530774 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
775
776 if (0 == data_len)
777 {
778 hddLog(VOS_TRACE_LEVEL_ERROR,
779 FL("NAN - Invalid Request, length = 0"));
780 return ret_val;
781 }
782
783 if (NULL == data)
784 {
785 hddLog(VOS_TRACE_LEVEL_ERROR,
786 FL("NAN - Invalid Request, data is NULL"));
787 return ret_val;
788 }
789
790 status = wlan_hdd_validate_context(pHddCtx);
791 if (0 != status)
792 {
793 hddLog(VOS_TRACE_LEVEL_ERROR,
794 FL("HDD context is not valid"));
795 return -EINVAL;
796 }
797
798 hddLog(LOG1, FL("Received NAN command"));
799 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
800 (tANI_U8 *)data, data_len);
801
802 /* check the NAN Capability */
803 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
804 {
805 hddLog(VOS_TRACE_LEVEL_ERROR,
806 FL("NAN is not supported by Firmware"));
807 return -EINVAL;
808 }
809
810 nan_req.request_data_len = data_len;
811 nan_req.request_data = data;
812
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530813 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530814 if (VOS_STATUS_SUCCESS == status)
815 {
816 ret_val = 0;
817 }
818 return ret_val;
819}
820
821/*
822 * FUNCTION: wlan_hdd_cfg80211_nan_request
823 * Wrapper to protect the nan vendor command from ssr
824 */
825static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
826 struct wireless_dev *wdev,
827 const void *data, int data_len)
828{
829 int ret;
830
831 vos_ssr_protect(__func__);
832 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
833 vos_ssr_unprotect(__func__);
834
835 return ret;
836}
837
838/*
839 * FUNCTION: wlan_hdd_cfg80211_nan_callback
840 * This is a callback function and it gets called
841 * when we need to report nan response event to
842 * upper layers.
843 */
844static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
845{
846 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
847 struct sk_buff *vendor_event;
848 int status;
849 tSirNanEvent *data;
850
851 ENTER();
852 if (NULL == msg)
853 {
854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
855 FL(" msg received here is null"));
856 return;
857 }
858 data = msg;
859
860 status = wlan_hdd_validate_context(pHddCtx);
861
862 if (0 != status)
863 {
864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
865 FL("HDD context is not valid"));
866 return;
867 }
868
869 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530870#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
871 NULL,
872#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530873 data->event_data_len +
874 NLMSG_HDRLEN,
875 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
876 GFP_KERNEL);
877
878 if (!vendor_event)
879 {
880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
881 FL("cfg80211_vendor_event_alloc failed"));
882 return;
883 }
884 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
885 data->event_data_len, data->event_data))
886 {
887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
888 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
889 kfree_skb(vendor_event);
890 return;
891 }
892 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
893 EXIT();
894}
895
896/*
897 * FUNCTION: wlan_hdd_cfg80211_nan_init
898 * This function is called to register the callback to sme layer
899 */
900inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
901{
902 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
903}
904
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530905/*
906 * define short names for the global vendor params
907 * used by __wlan_hdd_cfg80211_get_station_cmd()
908 */
909#define STATION_INVALID \
910 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
911#define STATION_INFO \
912 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
913#define STATION_ASSOC_FAIL_REASON \
914 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +0530915#define STATION_REMOTE \
916 QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530917#define STATION_MAX \
918 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
919
920static const struct nla_policy
921hdd_get_station_policy[STATION_MAX + 1] = {
922 [STATION_INFO] = {.type = NLA_FLAG},
923 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
924};
925
926/**
927 * hdd_get_station_assoc_fail() - Handle get station assoc fail
928 * @hdd_ctx: HDD context within host driver
929 * @wdev: wireless device
930 *
931 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
932 * Validate cmd attributes and send the station info to upper layers.
933 *
934 * Return: Success(0) or reason code for failure
935 */
936static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
937 hdd_adapter_t *adapter)
938{
939 struct sk_buff *skb = NULL;
940 uint32_t nl_buf_len;
941 hdd_station_ctx_t *hdd_sta_ctx;
942
943 nl_buf_len = NLMSG_HDRLEN;
944 nl_buf_len += sizeof(uint32_t);
945 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
946
947 if (!skb) {
948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
949 return -ENOMEM;
950 }
951
952 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
953
954 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
955 hdd_sta_ctx->conn_info.assoc_status_code)) {
956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
957 goto fail;
958 }
959 return cfg80211_vendor_cmd_reply(skb);
960fail:
961 if (skb)
962 kfree_skb(skb);
963 return -EINVAL;
964}
965
966/**
967 * hdd_map_auth_type() - transform auth type specific to
968 * vendor command
969 * @auth_type: csr auth type
970 *
971 * Return: Success(0) or reason code for failure
972 */
973static int hdd_convert_auth_type(uint32_t auth_type)
974{
975 uint32_t ret_val;
976
977 switch (auth_type) {
978 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
979 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
980 break;
981 case eCSR_AUTH_TYPE_SHARED_KEY:
982 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
983 break;
984 case eCSR_AUTH_TYPE_WPA:
985 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
986 break;
987 case eCSR_AUTH_TYPE_WPA_PSK:
988 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
989 break;
990 case eCSR_AUTH_TYPE_AUTOSWITCH:
991 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
992 break;
993 case eCSR_AUTH_TYPE_WPA_NONE:
994 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
995 break;
996 case eCSR_AUTH_TYPE_RSN:
997 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
998 break;
999 case eCSR_AUTH_TYPE_RSN_PSK:
1000 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
1001 break;
1002 case eCSR_AUTH_TYPE_FT_RSN:
1003 ret_val = QCA_WLAN_AUTH_TYPE_FT;
1004 break;
1005 case eCSR_AUTH_TYPE_FT_RSN_PSK:
1006 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
1007 break;
1008 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
1009 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
1010 break;
1011 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
1012 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
1013 break;
1014#ifdef FEATURE_WLAN_ESE
1015 case eCSR_AUTH_TYPE_CCKM_WPA:
1016 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
1017 break;
1018 case eCSR_AUTH_TYPE_CCKM_RSN:
1019 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
1020 break;
1021#endif
1022 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
1023 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
1024 break;
1025 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
1026 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
1027 break;
1028 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
1029 case eCSR_AUTH_TYPE_FAILED:
1030 case eCSR_AUTH_TYPE_NONE:
1031 default:
1032 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
1033 break;
1034 }
1035 return ret_val;
1036}
1037
1038/**
1039 * hdd_map_dot_11_mode() - transform dot11mode type specific to
1040 * vendor command
1041 * @dot11mode: dot11mode
1042 *
1043 * Return: Success(0) or reason code for failure
1044 */
1045static int hdd_convert_dot11mode(uint32_t dot11mode)
1046{
1047 uint32_t ret_val;
1048
1049 switch (dot11mode) {
1050 case eCSR_CFG_DOT11_MODE_11A:
1051 ret_val = QCA_WLAN_802_11_MODE_11A;
1052 break;
1053 case eCSR_CFG_DOT11_MODE_11B:
1054 ret_val = QCA_WLAN_802_11_MODE_11B;
1055 break;
1056 case eCSR_CFG_DOT11_MODE_11G:
1057 ret_val = QCA_WLAN_802_11_MODE_11G;
1058 break;
1059 case eCSR_CFG_DOT11_MODE_11N:
1060 ret_val = QCA_WLAN_802_11_MODE_11N;
1061 break;
1062 case eCSR_CFG_DOT11_MODE_11AC:
1063 ret_val = QCA_WLAN_802_11_MODE_11AC;
1064 break;
1065 case eCSR_CFG_DOT11_MODE_AUTO:
1066 case eCSR_CFG_DOT11_MODE_ABG:
1067 default:
1068 ret_val = QCA_WLAN_802_11_MODE_INVALID;
1069 }
1070 return ret_val;
1071}
1072
1073/**
1074 * hdd_add_tx_bitrate() - add tx bitrate attribute
1075 * @skb: pointer to sk buff
1076 * @hdd_sta_ctx: pointer to hdd station context
1077 * @idx: attribute index
1078 *
1079 * Return: Success(0) or reason code for failure
1080 */
1081static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
1082 hdd_station_ctx_t *hdd_sta_ctx,
1083 int idx)
1084{
1085 struct nlattr *nla_attr;
1086 uint32_t bitrate, bitrate_compat;
1087
1088 nla_attr = nla_nest_start(skb, idx);
1089 if (!nla_attr)
1090 goto fail;
1091 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301092 bitrate = cfg80211_calculate_bitrate(
1093 &hdd_sta_ctx->cache_conn_info.txrate);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301094
1095 /* report 16-bit bitrate only if we can */
1096 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
1097 if (bitrate > 0 &&
1098 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
1099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1100 goto fail;
1101 }
1102 if (bitrate_compat > 0 &&
1103 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
1104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1105 goto fail;
1106 }
1107 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301108 hdd_sta_ctx->cache_conn_info.txrate.nss)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1110 goto fail;
1111 }
1112 nla_nest_end(skb, nla_attr);
1113 return 0;
1114fail:
1115 return -EINVAL;
1116}
1117
1118/**
1119 * hdd_add_sta_info() - add station info attribute
1120 * @skb: pointer to sk buff
1121 * @hdd_sta_ctx: pointer to hdd station context
1122 * @idx: attribute index
1123 *
1124 * Return: Success(0) or reason code for failure
1125 */
1126static int32_t hdd_add_sta_info(struct sk_buff *skb,
1127 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1128{
1129 struct nlattr *nla_attr;
1130
1131 nla_attr = nla_nest_start(skb, idx);
1132 if (!nla_attr)
1133 goto fail;
1134 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301135 (hdd_sta_ctx->cache_conn_info.signal + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301136 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1137 goto fail;
1138 }
1139 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1140 goto fail;
1141 nla_nest_end(skb, nla_attr);
1142 return 0;
1143fail:
1144 return -EINVAL;
1145}
1146
1147/**
1148 * hdd_add_survey_info() - add survey info attribute
1149 * @skb: pointer to sk buff
1150 * @hdd_sta_ctx: pointer to hdd station context
1151 * @idx: attribute index
1152 *
1153 * Return: Success(0) or reason code for failure
1154 */
1155static int32_t hdd_add_survey_info(struct sk_buff *skb,
1156 hdd_station_ctx_t *hdd_sta_ctx,
1157 int idx)
1158{
1159 struct nlattr *nla_attr;
1160
1161 nla_attr = nla_nest_start(skb, idx);
1162 if (!nla_attr)
1163 goto fail;
1164 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301165 hdd_sta_ctx->cache_conn_info.freq) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301166 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301167 (hdd_sta_ctx->cache_conn_info.noise + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1169 goto fail;
1170 }
1171 nla_nest_end(skb, nla_attr);
1172 return 0;
1173fail:
1174 return -EINVAL;
1175}
1176
1177/**
1178 * hdd_add_link_standard_info() - add link info attribute
1179 * @skb: pointer to sk buff
1180 * @hdd_sta_ctx: pointer to hdd station context
1181 * @idx: attribute index
1182 *
1183 * Return: Success(0) or reason code for failure
1184 */
1185static int32_t
1186hdd_add_link_standard_info(struct sk_buff *skb,
1187 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1188{
1189 struct nlattr *nla_attr;
1190
1191 nla_attr = nla_nest_start(skb, idx);
1192 if (!nla_attr)
1193 goto fail;
1194 if (nla_put(skb,
1195 NL80211_ATTR_SSID,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301196 hdd_sta_ctx->cache_conn_info.SSID.SSID.length,
1197 hdd_sta_ctx->cache_conn_info.SSID.SSID.ssId)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1199 goto fail;
1200 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301201 if (nla_put(skb, NL80211_ATTR_MAC, VOS_MAC_ADDR_SIZE,
1202 hdd_sta_ctx->cache_conn_info.bssId))
1203 goto fail;
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301204 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1205 goto fail;
1206 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1207 goto fail;
1208 nla_nest_end(skb, nla_attr);
1209 return 0;
1210fail:
1211 return -EINVAL;
1212}
1213
1214/**
1215 * hdd_add_ap_standard_info() - add ap info attribute
1216 * @skb: pointer to sk buff
1217 * @hdd_sta_ctx: pointer to hdd station context
1218 * @idx: attribute index
1219 *
1220 * Return: Success(0) or reason code for failure
1221 */
1222static int32_t
1223hdd_add_ap_standard_info(struct sk_buff *skb,
1224 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1225{
1226 struct nlattr *nla_attr;
1227
1228 nla_attr = nla_nest_start(skb, idx);
1229 if (!nla_attr)
1230 goto fail;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301231 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301232 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301233 sizeof(hdd_sta_ctx->cache_conn_info.vht_caps),
1234 &hdd_sta_ctx->cache_conn_info.vht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1236 goto fail;
1237 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301238 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301239 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301240 sizeof(hdd_sta_ctx->cache_conn_info.ht_caps),
1241 &hdd_sta_ctx->cache_conn_info.ht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1243 goto fail;
1244 }
1245 nla_nest_end(skb, nla_attr);
1246 return 0;
1247fail:
1248 return -EINVAL;
1249}
1250
1251/**
1252 * hdd_get_station_info() - send BSS information to supplicant
1253 * @hdd_ctx: pointer to hdd context
1254 * @adapter: pointer to adapter
1255 *
1256 * Return: 0 if success else error status
1257 */
1258static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1259 hdd_adapter_t *adapter)
1260{
1261 struct sk_buff *skb = NULL;
1262 uint8_t *tmp_hs20 = NULL;
1263 uint32_t nl_buf_len;
1264 hdd_station_ctx_t *hdd_sta_ctx;
1265
1266 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1267
1268 nl_buf_len = NLMSG_HDRLEN;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301269
1270 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.SSID.SSID.length) +
1271 VOS_MAC_ADDR_SIZE +
1272 sizeof(hdd_sta_ctx->cache_conn_info.freq) +
1273 sizeof(hdd_sta_ctx->cache_conn_info.noise) +
1274 sizeof(hdd_sta_ctx->cache_conn_info.signal) +
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301275 (sizeof(uint32_t) * 2) +
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301276 sizeof(hdd_sta_ctx->cache_conn_info.txrate.nss) +
1277 sizeof(hdd_sta_ctx->cache_conn_info.roam_count) +
1278 sizeof(hdd_sta_ctx->cache_conn_info.authType) +
1279 sizeof(hdd_sta_ctx->cache_conn_info.dot11Mode);
1280 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
1281 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.vht_caps);
1282 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
1283 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_caps);
1284 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) {
1285 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->
1286 cache_conn_info.hs20vendor_ie);
1287 nl_buf_len +=
1288 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie) -
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301289 1);
1290 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301291 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
1292 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_operation);
1293 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
1294 nl_buf_len +=
1295 sizeof(hdd_sta_ctx->cache_conn_info.vht_operation);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301296
1297
1298 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1299 if (!skb) {
1300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1301 __func__, __LINE__);
1302 return -ENOMEM;
1303 }
1304
1305 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1306 LINK_INFO_STANDARD_NL80211_ATTR)) {
1307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1308 goto fail;
1309 }
1310 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1311 AP_INFO_STANDARD_NL80211_ATTR)) {
1312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1313 goto fail;
1314 }
1315 if (nla_put_u32(skb, INFO_ROAM_COUNT,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301316 hdd_sta_ctx->cache_conn_info.roam_count) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301317 nla_put_u32(skb, INFO_AKM,
1318 hdd_convert_auth_type(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301319 hdd_sta_ctx->cache_conn_info.authType)) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301320 nla_put_u32(skb, WLAN802_11_MODE,
1321 hdd_convert_dot11mode(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301322 hdd_sta_ctx->cache_conn_info.dot11Mode))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1324 goto fail;
1325 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301326 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301327 if (nla_put(skb, HT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301328 (sizeof(hdd_sta_ctx->cache_conn_info.ht_operation)),
1329 &hdd_sta_ctx->cache_conn_info.ht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301330 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1331 goto fail;
1332 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301333 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301334 if (nla_put(skb, VHT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301335 (sizeof(hdd_sta_ctx->
1336 cache_conn_info.vht_operation)),
1337 &hdd_sta_ctx->cache_conn_info.vht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1339 goto fail;
1340 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301341 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301342 if (nla_put(skb, AP_INFO_HS20_INDICATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301343 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie)
1344 - 1), tmp_hs20 + 1)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301345 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1346 goto fail;
1347 }
1348
1349 return cfg80211_vendor_cmd_reply(skb);
1350fail:
1351 if (skb)
1352 kfree_skb(skb);
1353 return -EINVAL;
1354}
1355
1356/**
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301357 * hdd_add_survey_info_sap_get_len - get data length used in
1358 * hdd_add_survey_info_sap()
1359 *
1360 * This function calculates the data length used in hdd_add_survey_info_sap()
1361 *
1362 * Return: total data length used in hdd_add_survey_info_sap()
1363 */
1364static uint32_t hdd_add_survey_info_sap_get_len(void)
1365{
1366 return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
1367}
1368
1369/**
1370 * hdd_add_survey_info - add survey info attribute
1371 * @skb: pointer to response skb buffer
1372 * @stainfo: station information
1373 * @idx: attribute type index for nla_next_start()
1374 *
1375 * This function adds survey info attribute to response skb buffer
1376 *
1377 * Return : 0 on success and errno on failure
1378 */
1379static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
1380 struct hdd_cache_sta_info *stainfo,
1381 int idx)
1382{
1383 struct nlattr *nla_attr;
1384
1385 nla_attr = nla_nest_start(skb, idx);
1386 if (!nla_attr)
1387 goto fail;
1388 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1389 stainfo->freq)) {
1390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1391 FL("put fail"));
1392 goto fail;
1393 }
1394 nla_nest_end(skb, nla_attr);
1395 return 0;
1396fail:
1397 return -EINVAL;
1398}
1399
1400/**
1401 * hdd_add_tx_bitrate_sap_get_len - get data length used in
1402 * hdd_add_tx_bitrate_sap()
1403 *
1404 * This function calculates the data length used in hdd_add_tx_bitrate_sap()
1405 *
1406 * Return: total data length used in hdd_add_tx_bitrate_sap()
1407 */
1408static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
1409{
1410 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
1411}
1412
1413/**
1414 * hdd_add_tx_bitrate_sap - add vht nss info attribute
1415 * @skb: pointer to response skb buffer
1416 * @stainfo: station information
1417 * @idx: attribute type index for nla_next_start()
1418 *
1419 * This function adds vht nss attribute to response skb buffer
1420 *
1421 * Return : 0 on success and errno on failure
1422 */
1423static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
1424 struct hdd_cache_sta_info *stainfo,
1425 int idx)
1426{
1427 struct nlattr *nla_attr;
1428
1429 nla_attr = nla_nest_start(skb, idx);
1430 if (!nla_attr)
1431 goto fail;
1432
1433 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1434 stainfo->nss)) {
1435 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1436 FL("put fail"));
1437 goto fail;
1438 }
1439 nla_nest_end(skb, nla_attr);
1440 return 0;
1441fail:
1442 return -EINVAL;
1443}
1444
1445/**
1446 * hdd_add_sta_info_sap_get_len - get data length used in
1447 * hdd_add_sta_info_sap()
1448 *
1449 * This function calculates the data length used in hdd_add_sta_info_sap()
1450 *
1451 * Return: total data length used in hdd_add_sta_info_sap()
1452 */
1453static uint32_t hdd_add_sta_info_sap_get_len(void)
1454{
1455 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
1456 hdd_add_tx_bitrate_sap_get_len());
1457}
1458
1459/**
1460 * hdd_add_sta_info_sap - add sta signal info attribute
1461 * @skb: pointer to response skb buffer
1462 * @rssi: peer rssi value
1463 * @stainfo: station information
1464 * @idx: attribute type index for nla_next_start()
1465 *
1466 * This function adds sta signal attribute to response skb buffer
1467 *
1468 * Return : 0 on success and errno on failure
1469 */
1470static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
1471 struct hdd_cache_sta_info *stainfo, int idx)
1472{
1473 struct nlattr *nla_attr;
1474
1475 nla_attr = nla_nest_start(skb, idx);
1476 if (!nla_attr)
1477 goto fail;
1478
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05301479 /* upperlayer expects positive rssi value */
1480 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, (rssi + 96))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301481 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1482 FL("put fail"));
1483 goto fail;
1484 }
1485 if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE)) {
1486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1487 FL("put fail"));
1488 goto fail;
1489 }
1490
1491 nla_nest_end(skb, nla_attr);
1492 return 0;
1493fail:
1494 return -EINVAL;
1495}
1496
1497/**
1498 * hdd_add_link_standard_info_sap_get_len - get data length used in
1499 * hdd_add_link_standard_info_sap()
1500 *
1501 * This function calculates the data length used in
1502 * hdd_add_link_standard_info_sap()
1503 *
1504 * Return: total data length used in hdd_add_link_standard_info_sap()
1505 */
1506static uint32_t hdd_add_link_standard_info_sap_get_len(void)
1507{
1508 return ((NLA_HDRLEN) +
1509 hdd_add_survey_info_sap_get_len() +
1510 hdd_add_sta_info_sap_get_len() +
1511 (sizeof(uint32_t) + NLA_HDRLEN));
1512}
1513
1514/**
1515 * hdd_add_link_standard_info_sap - add add link info attribut
1516 * @skb: pointer to response skb buffer
1517 * @stainfo: station information
1518 * @idx: attribute type index for nla_next_start()
1519 *
1520 * This function adds link info attribut to response skb buffer
1521 *
1522 * Return : 0 on success and errno on failure
1523 */
1524static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
1525 struct hdd_cache_sta_info *stainfo,
1526 int idx)
1527{
1528 struct nlattr *nla_attr;
1529
1530 nla_attr = nla_nest_start(skb, idx);
1531 if (!nla_attr)
1532 goto fail;
1533 if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
1534 goto fail;
1535 if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
1536 goto fail;
1537
1538 if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
1539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1540 FL("put fail"));
1541 goto fail;
1542 }
1543
1544 nla_nest_end(skb, nla_attr);
1545 return 0;
1546fail:
1547 return -EINVAL;
1548}
1549
1550/**
1551 * hdd_add_ap_standard_info_sap_get_len - get data length used in
1552 * hdd_add_ap_standard_info_sap()
1553 * @stainfo: station information
1554 *
1555 * This function calculates the data length used in
1556 * hdd_add_ap_standard_info_sap()
1557 *
1558 * Return: total data length used in hdd_add_ap_standard_info_sap()
1559 */
1560static uint32_t hdd_add_ap_standard_info_sap_get_len(
1561 struct hdd_cache_sta_info *stainfo)
1562{
1563 uint32_t len;
1564
1565 len = NLA_HDRLEN;
1566 if (stainfo->vht_present)
1567 len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
1568 if (stainfo->ht_present)
1569 len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
1570
1571 return len;
1572}
1573
1574/**
1575 * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
1576 * @skb: pointer to response skb buffer
1577 * @stainfo: station information
1578 * @idx: attribute type index for nla_next_start()
1579 *
1580 * This function adds HT and VHT info attributes to response skb buffer
1581 *
1582 * Return : 0 on success and errno on failure
1583 */
1584static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
1585 struct hdd_cache_sta_info *stainfo,
1586 int idx)
1587{
1588 struct nlattr *nla_attr;
1589
1590 nla_attr = nla_nest_start(skb, idx);
1591 if (!nla_attr)
1592 goto fail;
1593
1594 if (stainfo->vht_present) {
1595 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1596 sizeof(stainfo->vht_caps),
1597 &stainfo->vht_caps)) {
1598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1599 FL("put fail"));
1600 goto fail;
1601 }
1602 }
1603 if (stainfo->ht_present) {
1604 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1605 sizeof(stainfo->ht_caps),
1606 &stainfo->ht_caps)) {
1607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1608 FL("put fail"));
1609 goto fail;
1610 }
1611 }
1612 nla_nest_end(skb, nla_attr);
1613 return 0;
1614fail:
1615 return -EINVAL;
1616}
1617
1618/**
1619 * hdd_decode_ch_width - decode channel band width based
1620 * @ch_width: encoded enum value holding channel band width
1621 *
1622 * This function decodes channel band width from the given encoded enum value.
1623 *
1624 * Returns: decoded channel band width.
1625 */
1626static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
1627{
1628 switch (ch_width) {
1629 case 0:
1630 return 20;
1631 case 1:
1632 return 40;
1633 case 2:
1634 return 80;
1635 default:
1636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1637 "invalid enum: %d", ch_width);
1638 return 20;
1639 }
1640}
1641
1642/**
1643 * hdd_get_cached_station_remote() - get cached(deleted) peer's info
1644 * @hdd_ctx: hdd context
1645 * @adapter: hostapd interface
1646 * @mac_addr: mac address of requested peer
1647 *
1648 * This function collect and indicate the cached(deleted) peer's info
1649 *
1650 * Return: 0 on success, otherwise error value
1651 */
1652static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx,
1653 hdd_adapter_t *adapter,
1654 v_MACADDR_t mac_addr)
1655{
1656 struct hdd_cache_sta_info *stainfo;
1657 struct sk_buff *skb = NULL;
1658 uint32_t nl_buf_len;
1659 uint8_t cw;
1660 ptSapContext sap_ctx;
1661 v_CONTEXT_t vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
1662
1663 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
1664 if(sap_ctx == NULL){
1665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1666 FL("psapCtx is NULL"));
1667 return -ENOENT;
1668 }
1669
1670 stainfo = hdd_get_cache_stainfo(sap_ctx->cache_sta_info,
1671 mac_addr.bytes);
1672 if (!stainfo) {
1673 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1674 "peer " MAC_ADDRESS_STR " not found",
1675 MAC_ADDR_ARRAY(mac_addr.bytes));
1676 return -EINVAL;
1677 }
1678 if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE) {
1679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1680 "peer " MAC_ADDRESS_STR " is in connected state",
1681 MAC_ADDR_ARRAY(mac_addr.bytes));
1682 return -EINVAL;
1683 }
1684
1685
1686 nl_buf_len = NLMSG_HDRLEN + hdd_add_link_standard_info_sap_get_len() +
1687 hdd_add_ap_standard_info_sap_get_len(stainfo) +
1688 (sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
1689 (sizeof(cw) + NLA_HDRLEN) +
1690 (sizeof(stainfo->rx_rate) + NLA_HDRLEN);
1691
1692 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1693 if (!skb) {
1694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "cfg80211_vendor_cmd_alloc_reply_skb failed");
1695 return -ENOMEM;
1696 }
1697
1698 if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
1699 LINK_INFO_STANDARD_NL80211_ATTR)) {
1700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "link standard put fail");
1701 goto fail;
1702 }
1703
1704 if (hdd_add_ap_standard_info_sap(skb, stainfo,
1705 AP_INFO_STANDARD_NL80211_ATTR)) {
1706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ap standard put fail");
1707 goto fail;
1708 }
1709
1710 /* upper layer expects decoded channel BW */
1711 cw = hdd_decode_ch_width(stainfo->ch_width);
1712 if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE, stainfo->dot11_mode) ||
1713 nla_put_u8(skb, REMOTE_CH_WIDTH, cw)) {
1714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "remote ch put fail");
1715 goto fail;
1716 }
Hanumanth Reddy Pothula504fe152018-01-02 20:41:03 +05301717 if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, (stainfo->rx_rate * 100))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "rx rate put fail");
1719 goto fail;
1720 }
1721
1722 vos_mem_zero(stainfo, sizeof(*stainfo));
1723
1724 return cfg80211_vendor_cmd_reply(skb);
1725fail:
1726 if (skb)
1727 kfree_skb(skb);
1728
1729 return -EINVAL;
1730}
1731
1732/**
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301733 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1734 * @wiphy: corestack handler
1735 * @wdev: wireless device
1736 * @data: data
1737 * @data_len: data length
1738 *
1739 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1740 * Validate cmd attributes and send the station info to upper layers.
1741 *
1742 * Return: Success(0) or reason code for failure
1743 */
1744static int32_t
1745__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1746 struct wireless_dev *wdev,
1747 const void *data,
1748 int data_len)
1749{
1750 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1751 struct net_device *dev = wdev->netdev;
1752 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1753 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1754 int32_t status;
1755
1756 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1757 if (VOS_FTM_MODE == hdd_get_conparam()) {
1758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1759 status = -EPERM;
1760 goto out;
1761 }
1762
1763 status = wlan_hdd_validate_context(hdd_ctx);
1764 if (0 != status)
1765 goto out;
1766
1767
1768 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1769 data, data_len, NULL);
1770 if (status) {
1771 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1772 goto out;
1773 }
1774
1775 /* Parse and fetch Command Type*/
1776 if (tb[STATION_INFO]) {
1777 status = hdd_get_station_info(hdd_ctx, adapter);
1778 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1779 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301780 } else if (tb[STATION_REMOTE]) {
1781 v_MACADDR_t mac_addr;
1782
1783 if (adapter->device_mode != WLAN_HDD_SOFTAP &&
1784 adapter->device_mode != WLAN_HDD_P2P_GO) {
1785 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"invalid device_mode:%d",
1786 adapter->device_mode);
1787 status = -EINVAL;
1788 goto out;
1789 }
1790
1791 nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
1792 VOS_MAC_ADDRESS_LEN);
1793
1794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "STATION_REMOTE "MAC_ADDRESS_STR"",
1795 MAC_ADDR_ARRAY(mac_addr.bytes));
1796
1797 status = hdd_get_cached_station_remote(hdd_ctx, adapter,
1798 mac_addr);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301799 } else {
1800 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1801 status = -EINVAL;
1802 goto out;
1803 }
1804 EXIT();
1805out:
1806 return status;
1807}
1808
1809/**
1810 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1811 * @wiphy: corestack handler
1812 * @wdev: wireless device
1813 * @data: data
1814 * @data_len: data length
1815 *
1816 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1817 * Validate cmd attributes and send the station info to upper layers.
1818 *
1819 * Return: Success(0) or reason code for failure
1820 */
1821static int32_t
1822hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1823 struct wireless_dev *wdev,
1824 const void *data,
1825 int data_len)
1826{
1827 int ret;
1828
1829 vos_ssr_protect(__func__);
1830 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1831 vos_ssr_unprotect(__func__);
1832
1833 return ret;
1834}
1835
1836/*
1837 * undef short names defined for get station command
1838 * used by __wlan_hdd_cfg80211_get_station_cmd()
1839 */
1840#undef STATION_INVALID
1841#undef STATION_INFO
1842#undef STATION_ASSOC_FAIL_REASON
1843#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301844
Sunil Duttc69bccb2014-05-26 21:30:20 +05301845#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1846
1847static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1848 struct sk_buff *vendor_event)
1849{
1850 if (nla_put_u8(vendor_event,
1851 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1852 stats->rate.preamble) ||
1853 nla_put_u8(vendor_event,
1854 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1855 stats->rate.nss) ||
1856 nla_put_u8(vendor_event,
1857 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1858 stats->rate.bw) ||
1859 nla_put_u8(vendor_event,
1860 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1861 stats->rate.rateMcsIdx) ||
1862 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1863 stats->rate.bitrate ) ||
1864 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1865 stats->txMpdu ) ||
1866 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1867 stats->rxMpdu ) ||
1868 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1869 stats->mpduLost ) ||
1870 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1871 stats->retries) ||
1872 nla_put_u32(vendor_event,
1873 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1874 stats->retriesShort ) ||
1875 nla_put_u32(vendor_event,
1876 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1877 stats->retriesLong))
1878 {
1879 hddLog(VOS_TRACE_LEVEL_ERROR,
1880 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1881 return FALSE;
1882 }
1883 return TRUE;
1884}
1885
1886static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1887 struct sk_buff *vendor_event)
1888{
1889 u32 i = 0;
1890 struct nlattr *rateInfo;
1891 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1892 stats->type) ||
1893 nla_put(vendor_event,
1894 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1895 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1896 nla_put_u32(vendor_event,
1897 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1898 stats->capabilities) ||
1899 nla_put_u32(vendor_event,
1900 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1901 stats->numRate))
1902 {
1903 hddLog(VOS_TRACE_LEVEL_ERROR,
1904 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1905 goto error;
1906 }
1907
1908 rateInfo = nla_nest_start(vendor_event,
1909 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301910 if(!rateInfo)
1911 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301912 for (i = 0; i < stats->numRate; i++)
1913 {
1914 struct nlattr *rates;
1915 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1916 stats->rateStats +
1917 (i * sizeof(tSirWifiRateStat)));
1918 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301919 if(!rates)
1920 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301921
1922 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1923 {
1924 hddLog(VOS_TRACE_LEVEL_ERROR,
1925 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1926 return FALSE;
1927 }
1928 nla_nest_end(vendor_event, rates);
1929 }
1930 nla_nest_end(vendor_event, rateInfo);
1931
1932 return TRUE;
1933error:
1934 return FALSE;
1935}
1936
1937static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1938 struct sk_buff *vendor_event)
1939{
1940 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1941 stats->ac ) ||
1942 nla_put_u32(vendor_event,
1943 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1944 stats->txMpdu ) ||
1945 nla_put_u32(vendor_event,
1946 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1947 stats->rxMpdu ) ||
1948 nla_put_u32(vendor_event,
1949 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1950 stats->txMcast ) ||
1951 nla_put_u32(vendor_event,
1952 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1953 stats->rxMcast ) ||
1954 nla_put_u32(vendor_event,
1955 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1956 stats->rxAmpdu ) ||
1957 nla_put_u32(vendor_event,
1958 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1959 stats->txAmpdu ) ||
1960 nla_put_u32(vendor_event,
1961 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1962 stats->mpduLost )||
1963 nla_put_u32(vendor_event,
1964 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1965 stats->retries ) ||
1966 nla_put_u32(vendor_event,
1967 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1968 stats->retriesShort ) ||
1969 nla_put_u32(vendor_event,
1970 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1971 stats->retriesLong ) ||
1972 nla_put_u32(vendor_event,
1973 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1974 stats->contentionTimeMin ) ||
1975 nla_put_u32(vendor_event,
1976 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1977 stats->contentionTimeMax ) ||
1978 nla_put_u32(vendor_event,
1979 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1980 stats->contentionTimeAvg ) ||
1981 nla_put_u32(vendor_event,
1982 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1983 stats->contentionNumSamples ))
1984 {
1985 hddLog(VOS_TRACE_LEVEL_ERROR,
1986 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1987 return FALSE;
1988 }
1989 return TRUE;
1990}
1991
1992static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1993 struct sk_buff *vendor_event)
1994{
Dino Myclec8f3f332014-07-21 16:48:27 +05301995 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301996 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1997 nla_put(vendor_event,
1998 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
1999 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
2000 nla_put_u32(vendor_event,
2001 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
2002 stats->state ) ||
2003 nla_put_u32(vendor_event,
2004 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
2005 stats->roaming ) ||
2006 nla_put_u32(vendor_event,
2007 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
2008 stats->capabilities ) ||
2009 nla_put(vendor_event,
2010 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
2011 strlen(stats->ssid), stats->ssid) ||
2012 nla_put(vendor_event,
2013 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
2014 WNI_CFG_BSSID_LEN, stats->bssid) ||
2015 nla_put(vendor_event,
2016 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
2017 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
2018 nla_put(vendor_event,
2019 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
2020 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
2021 )
2022 {
2023 hddLog(VOS_TRACE_LEVEL_ERROR,
2024 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2025 return FALSE;
2026 }
2027 return TRUE;
2028}
2029
Dino Mycle3b9536d2014-07-09 22:05:24 +05302030static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
2031 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302032 struct sk_buff *vendor_event)
2033{
2034 int i = 0;
2035 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302036 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2037 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302038 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302039
Sunil Duttc69bccb2014-05-26 21:30:20 +05302040 if (FALSE == put_wifi_interface_info(
2041 &pWifiIfaceStat->info,
2042 vendor_event))
2043 {
2044 hddLog(VOS_TRACE_LEVEL_ERROR,
2045 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2046 return FALSE;
2047
2048 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05302049 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
2050 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
2051 if (NULL == pWifiIfaceStatTL)
2052 {
2053 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2054 return FALSE;
2055 }
2056
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302057 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
2058 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
2059 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
2060 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
2061
2062 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
2063 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
2064 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
2065 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302066
2067 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
2068 {
2069 if (VOS_STATUS_SUCCESS ==
2070 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2071 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
2072 {
2073 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
2074 * obtained from TL structure
2075 */
2076
2077 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
2078 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302079 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
2080
Srinivas Dasari98947432014-11-07 19:41:24 +05302081 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
2082 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
2083 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
2084 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
2085 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
2086 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
2087 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
2088 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302089
Srinivas Dasari98947432014-11-07 19:41:24 +05302090 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
2091 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
2092 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
2093 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
2094 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
2095 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
2096 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
2097 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302098
Srinivas Dasari98947432014-11-07 19:41:24 +05302099 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
2100 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
2101 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
2102 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
2103 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
2104 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
2105 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
2106 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302107 }
2108 else
2109 {
2110 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
2111 }
2112
Dino Mycle3b9536d2014-07-09 22:05:24 +05302113 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
2114 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
2115 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
2116 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
2117 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
2118 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
2119 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
2120 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
2121 }
2122 else
2123 {
2124 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
2125 }
2126
2127
Sunil Duttc69bccb2014-05-26 21:30:20 +05302128
2129 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302130 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2131 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
2132 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302133 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
2134 pWifiIfaceStat->beaconRx) ||
2135 nla_put_u32(vendor_event,
2136 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
2137 pWifiIfaceStat->mgmtRx) ||
2138 nla_put_u32(vendor_event,
2139 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
2140 pWifiIfaceStat->mgmtActionRx) ||
2141 nla_put_u32(vendor_event,
2142 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
2143 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302144 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302145 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
2146 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302147 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302148 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
2149 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302150 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302151 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
2152 pWifiIfaceStat->rssiAck))
2153 {
2154 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302155 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2156 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302157 return FALSE;
2158 }
2159
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302160#ifdef FEATURE_EXT_LL_STAT
2161 /*
2162 * Ensure when EXT_LL_STAT is supported by both host and fwr,
2163 * then host should send Leaky AP stats to upper layer,
2164 * otherwise no need to send these stats.
2165 */
2166 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
2167 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
2168 )
2169 {
2170 hddLog(VOS_TRACE_LEVEL_INFO,
2171 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
2172 pWifiIfaceStat->leakyApStat.is_leaky_ap,
2173 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
2174 pWifiIfaceStat->leakyApStat.rx_leak_window,
2175 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
2176 if (nla_put_u32(vendor_event,
2177 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
2178 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
2179 nla_put_u32(vendor_event,
2180 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
2181 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
2182 nla_put_u32(vendor_event,
2183 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
2184 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05302185 hdd_wlan_nla_put_u64(vendor_event,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302186 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
2187 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
2188 {
2189 hddLog(VOS_TRACE_LEVEL_ERROR,
2190 FL("EXT_LL_STAT put fail"));
2191 vos_mem_free(pWifiIfaceStatTL);
2192 return FALSE;
2193 }
2194 }
2195#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05302196 wmmInfo = nla_nest_start(vendor_event,
2197 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302198 if(!wmmInfo)
2199 {
2200 vos_mem_free(pWifiIfaceStatTL);
2201 return FALSE;
2202 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302203 for (i = 0; i < WIFI_AC_MAX; i++)
2204 {
2205 struct nlattr *wmmStats;
2206 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302207 if(!wmmStats)
2208 {
2209 vos_mem_free(pWifiIfaceStatTL);
2210 return FALSE;
2211 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302212 if (FALSE == put_wifi_wmm_ac_stat(
2213 &pWifiIfaceStat->AccessclassStats[i],
2214 vendor_event))
2215 {
2216 hddLog(VOS_TRACE_LEVEL_ERROR,
2217 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05302218 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302219 return FALSE;
2220 }
2221
2222 nla_nest_end(vendor_event, wmmStats);
2223 }
2224 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05302225 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302226 return TRUE;
2227}
2228
2229static tSirWifiInterfaceMode
2230 hdd_map_device_to_ll_iface_mode ( int deviceMode )
2231{
2232 switch (deviceMode)
2233 {
2234 case WLAN_HDD_INFRA_STATION:
2235 return WIFI_INTERFACE_STA;
2236 case WLAN_HDD_SOFTAP:
2237 return WIFI_INTERFACE_SOFTAP;
2238 case WLAN_HDD_P2P_CLIENT:
2239 return WIFI_INTERFACE_P2P_CLIENT;
2240 case WLAN_HDD_P2P_GO:
2241 return WIFI_INTERFACE_P2P_GO;
2242 case WLAN_HDD_IBSS:
2243 return WIFI_INTERFACE_IBSS;
2244 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05302245 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302246 }
2247}
2248
2249static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
2250 tpSirWifiInterfaceInfo pInfo)
2251{
2252 v_U8_t *staMac = NULL;
2253 hdd_station_ctx_t *pHddStaCtx;
2254 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2255 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
2256
2257 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
2258
2259 vos_mem_copy(pInfo->macAddr,
2260 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
2261
2262 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2263 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
2264 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
2265 {
2266 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2267 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
2268 {
2269 pInfo->state = WIFI_DISCONNECTED;
2270 }
2271 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
2272 {
2273 hddLog(VOS_TRACE_LEVEL_ERROR,
2274 "%s: Session ID %d, Connection is in progress", __func__,
2275 pAdapter->sessionId);
2276 pInfo->state = WIFI_ASSOCIATING;
2277 }
2278 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
2279 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
2280 {
2281 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
2282 hddLog(VOS_TRACE_LEVEL_ERROR,
2283 "%s: client " MAC_ADDRESS_STR
2284 " is in the middle of WPS/EAPOL exchange.", __func__,
2285 MAC_ADDR_ARRAY(staMac));
2286 pInfo->state = WIFI_AUTHENTICATING;
2287 }
2288 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
2289 {
2290 pInfo->state = WIFI_ASSOCIATED;
2291 vos_mem_copy(pInfo->bssid,
2292 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
2293 vos_mem_copy(pInfo->ssid,
2294 pHddStaCtx->conn_info.SSID.SSID.ssId,
2295 pHddStaCtx->conn_info.SSID.SSID.length);
2296 //NULL Terminate the string.
2297 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
2298 }
2299 }
2300 vos_mem_copy(pInfo->countryStr,
2301 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2302
2303 vos_mem_copy(pInfo->apCountryStr,
2304 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2305
2306 return TRUE;
2307}
2308
2309/*
2310 * hdd_link_layer_process_peer_stats () - This function is called after
2311 * receiving Link Layer Peer statistics from FW.This function converts
2312 * the firmware data to the NL data and sends the same to the kernel/upper
2313 * layers.
2314 */
2315static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
2316 v_VOID_t *pData)
2317{
2318 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302319 tpSirWifiPeerStat pWifiPeerStat;
2320 tpSirWifiPeerInfo pWifiPeerInfo;
2321 struct nlattr *peerInfo;
2322 struct sk_buff *vendor_event;
2323 int status, i;
2324
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302325 ENTER();
2326
Sunil Duttc69bccb2014-05-26 21:30:20 +05302327 status = wlan_hdd_validate_context(pHddCtx);
2328 if (0 != status)
2329 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302330 return;
2331 }
2332
2333 pWifiPeerStat = (tpSirWifiPeerStat) pData;
2334
2335 hddLog(VOS_TRACE_LEVEL_INFO,
2336 "LL_STATS_PEER_ALL : numPeers %u",
2337 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302338 /*
2339 * Allocate a size of 4096 for the peer stats comprising
2340 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
2341 * sizeof (tSirWifiRateStat).Each field is put with an
2342 * NL attribute.The size of 4096 is considered assuming
2343 * that number of rates shall not exceed beyond 50 with
2344 * the sizeof (tSirWifiRateStat) being 32.
2345 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302346 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2347 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302348 if (!vendor_event)
2349 {
2350 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302351 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05302352 __func__);
2353 return;
2354 }
2355 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302356 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2357 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
2358 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302359 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
2360 pWifiPeerStat->numPeers))
2361 {
2362 hddLog(VOS_TRACE_LEVEL_ERROR,
2363 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
2364 kfree_skb(vendor_event);
2365 return;
2366 }
2367
2368 peerInfo = nla_nest_start(vendor_event,
2369 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302370 if(!peerInfo)
2371 {
2372 hddLog(VOS_TRACE_LEVEL_ERROR,
2373 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
2374 __func__);
2375 kfree_skb(vendor_event);
2376 return;
2377 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302378
2379 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2380 pWifiPeerStat->peerInfo);
2381
2382 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
2383 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302384 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302385 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302386
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302387 if(!peers)
2388 {
2389 hddLog(VOS_TRACE_LEVEL_ERROR,
2390 "%s: peer stats put fail",
2391 __func__);
2392 kfree_skb(vendor_event);
2393 return;
2394 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302395 if (FALSE == put_wifi_peer_info(
2396 pWifiPeerInfo, vendor_event))
2397 {
2398 hddLog(VOS_TRACE_LEVEL_ERROR,
2399 "%s: put_wifi_peer_info put fail", __func__);
2400 kfree_skb(vendor_event);
2401 return;
2402 }
2403
2404 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2405 pWifiPeerStat->peerInfo +
2406 (i * sizeof(tSirWifiPeerInfo)) +
2407 (numRate * sizeof (tSirWifiRateStat)));
2408 nla_nest_end(vendor_event, peers);
2409 }
2410 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302411 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302412 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302413}
2414
2415/*
2416 * hdd_link_layer_process_iface_stats () - This function is called after
2417 * receiving Link Layer Interface statistics from FW.This function converts
2418 * the firmware data to the NL data and sends the same to the kernel/upper
2419 * layers.
2420 */
2421static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
2422 v_VOID_t *pData)
2423{
2424 tpSirWifiIfaceStat pWifiIfaceStat;
2425 struct sk_buff *vendor_event;
2426 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2427 int status;
2428
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302429 ENTER();
2430
Sunil Duttc69bccb2014-05-26 21:30:20 +05302431 status = wlan_hdd_validate_context(pHddCtx);
2432 if (0 != status)
2433 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302434 return;
2435 }
2436 /*
2437 * Allocate a size of 4096 for the interface stats comprising
2438 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
2439 * assuming that all these fit with in the limit.Please take
2440 * a call on the limit based on the data requirements on
2441 * interface statistics.
2442 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302443 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2444 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302445 if (!vendor_event)
2446 {
2447 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302448 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302449 return;
2450 }
2451
2452 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
2453
Dino Mycle3b9536d2014-07-09 22:05:24 +05302454
2455 if (FALSE == hdd_get_interface_info( pAdapter,
2456 &pWifiIfaceStat->info))
2457 {
2458 hddLog(VOS_TRACE_LEVEL_ERROR,
2459 FL("hdd_get_interface_info get fail") );
2460 kfree_skb(vendor_event);
2461 return;
2462 }
2463
2464 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
2465 vendor_event))
2466 {
2467 hddLog(VOS_TRACE_LEVEL_ERROR,
2468 FL("put_wifi_iface_stats fail") );
2469 kfree_skb(vendor_event);
2470 return;
2471 }
2472
Sunil Duttc69bccb2014-05-26 21:30:20 +05302473 hddLog(VOS_TRACE_LEVEL_INFO,
2474 "WMI_LINK_STATS_IFACE Data");
2475
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302476 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302477
2478 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302479}
2480
2481/*
2482 * hdd_link_layer_process_radio_stats () - This function is called after
2483 * receiving Link Layer Radio statistics from FW.This function converts
2484 * the firmware data to the NL data and sends the same to the kernel/upper
2485 * layers.
2486 */
2487static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
2488 v_VOID_t *pData)
2489{
2490 int status, i;
2491 tpSirWifiRadioStat pWifiRadioStat;
2492 tpSirWifiChannelStats pWifiChannelStats;
2493 struct sk_buff *vendor_event;
2494 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2495 struct nlattr *chList;
2496
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302497 ENTER();
2498
Sunil Duttc69bccb2014-05-26 21:30:20 +05302499 status = wlan_hdd_validate_context(pHddCtx);
2500 if (0 != status)
2501 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302502 return;
2503 }
2504 pWifiRadioStat = (tpSirWifiRadioStat) pData;
2505
2506 hddLog(VOS_TRACE_LEVEL_INFO,
2507 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302508 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05302509 " radio is %d onTime is %u "
2510 " txTime is %u rxTime is %u "
2511 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05302512 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05302513 " onTimePnoScan is %u onTimeHs20 is %u "
2514 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302515 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302516 pWifiRadioStat->radio, pWifiRadioStat->onTime,
2517 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
2518 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302519 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302520 pWifiRadioStat->onTimeRoamScan,
2521 pWifiRadioStat->onTimePnoScan,
2522 pWifiRadioStat->onTimeHs20,
2523 pWifiRadioStat->numChannels);
2524 /*
2525 * Allocate a size of 4096 for the Radio stats comprising
2526 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
2527 * (tSirWifiChannelStats).Each channel data is put with an
2528 * NL attribute.The size of 4096 is considered assuming that
2529 * number of channels shall not exceed beyond 60 with the
2530 * sizeof (tSirWifiChannelStats) being 24 bytes.
2531 */
2532
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302533 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2534 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302535 if (!vendor_event)
2536 {
2537 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302538 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302539 return;
2540 }
2541
2542 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302543 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2544 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2545 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302546 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2547 pWifiRadioStat->radio) ||
2548 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302549 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2550 NUM_RADIOS) ||
2551 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302552 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2553 pWifiRadioStat->onTime) ||
2554 nla_put_u32(vendor_event,
2555 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2556 pWifiRadioStat->txTime) ||
2557 nla_put_u32(vendor_event,
2558 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2559 pWifiRadioStat->rxTime) ||
2560 nla_put_u32(vendor_event,
2561 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2562 pWifiRadioStat->onTimeScan) ||
2563 nla_put_u32(vendor_event,
2564 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2565 pWifiRadioStat->onTimeNbd) ||
2566 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302567 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2568 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302569 nla_put_u32(vendor_event,
2570 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2571 pWifiRadioStat->onTimeRoamScan) ||
2572 nla_put_u32(vendor_event,
2573 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2574 pWifiRadioStat->onTimePnoScan) ||
2575 nla_put_u32(vendor_event,
2576 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2577 pWifiRadioStat->onTimeHs20) ||
2578 nla_put_u32(vendor_event,
2579 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2580 pWifiRadioStat->numChannels))
2581 {
2582 hddLog(VOS_TRACE_LEVEL_ERROR,
2583 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2584 kfree_skb(vendor_event);
2585 return ;
2586 }
2587
2588 chList = nla_nest_start(vendor_event,
2589 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302590 if(!chList)
2591 {
2592 hddLog(VOS_TRACE_LEVEL_ERROR,
2593 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2594 __func__);
2595 kfree_skb(vendor_event);
2596 return;
2597 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302598 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2599 {
2600 struct nlattr *chInfo;
2601
2602 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2603 pWifiRadioStat->channels +
2604 (i * sizeof(tSirWifiChannelStats)));
2605
Sunil Duttc69bccb2014-05-26 21:30:20 +05302606 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302607 if(!chInfo)
2608 {
2609 hddLog(VOS_TRACE_LEVEL_ERROR,
2610 "%s: failed to put chInfo",
2611 __func__);
2612 kfree_skb(vendor_event);
2613 return;
2614 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302615
2616 if (nla_put_u32(vendor_event,
2617 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2618 pWifiChannelStats->channel.width) ||
2619 nla_put_u32(vendor_event,
2620 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2621 pWifiChannelStats->channel.centerFreq) ||
2622 nla_put_u32(vendor_event,
2623 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2624 pWifiChannelStats->channel.centerFreq0) ||
2625 nla_put_u32(vendor_event,
2626 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2627 pWifiChannelStats->channel.centerFreq1) ||
2628 nla_put_u32(vendor_event,
2629 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2630 pWifiChannelStats->onTime) ||
2631 nla_put_u32(vendor_event,
2632 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2633 pWifiChannelStats->ccaBusyTime))
2634 {
2635 hddLog(VOS_TRACE_LEVEL_ERROR,
2636 FL("cfg80211_vendor_event_alloc failed") );
2637 kfree_skb(vendor_event);
2638 return ;
2639 }
2640 nla_nest_end(vendor_event, chInfo);
2641 }
2642 nla_nest_end(vendor_event, chList);
2643
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302644 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302645
2646 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302647 return;
2648}
2649
2650/*
2651 * hdd_link_layer_stats_ind_callback () - This function is called after
2652 * receiving Link Layer indications from FW.This callback converts the firmware
2653 * data to the NL data and send the same to the kernel/upper layers.
2654 */
2655static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2656 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302657 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302658{
Dino Mycled3d50022014-07-07 12:58:25 +05302659 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2660 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302661 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302662 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302663 int status;
2664
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302665 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302666
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302667 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302668 if (0 != status)
2669 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302670 return;
2671 }
2672
Dino Mycled3d50022014-07-07 12:58:25 +05302673 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2674 if (NULL == pAdapter)
2675 {
2676 hddLog(VOS_TRACE_LEVEL_ERROR,
2677 FL(" MAC address %pM does not exist with host"),
2678 macAddr);
2679 return;
2680 }
2681
Sunil Duttc69bccb2014-05-26 21:30:20 +05302682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302683 "%s: Interface: %s LLStats indType: %d", __func__,
2684 pAdapter->dev->name, indType);
2685
Sunil Duttc69bccb2014-05-26 21:30:20 +05302686 switch (indType)
2687 {
2688 case SIR_HAL_LL_STATS_RESULTS_RSP:
2689 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302690 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302691 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2692 "respId = %u, moreResultToFollow = %u",
2693 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2694 macAddr, linkLayerStatsResults->respId,
2695 linkLayerStatsResults->moreResultToFollow);
2696
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302697 spin_lock(&hdd_context_lock);
2698 context = &pHddCtx->ll_stats_context;
2699 /* validate response received from target */
2700 if ((context->request_id != linkLayerStatsResults->respId) ||
2701 !(context->request_bitmap & linkLayerStatsResults->paramId))
2702 {
2703 spin_unlock(&hdd_context_lock);
2704 hddLog(LOGE,
2705 FL("Error : Request id %d response id %d request bitmap 0x%x"
2706 "response bitmap 0x%x"),
2707 context->request_id, linkLayerStatsResults->respId,
2708 context->request_bitmap, linkLayerStatsResults->paramId);
2709 return;
2710 }
2711 spin_unlock(&hdd_context_lock);
2712
Sunil Duttc69bccb2014-05-26 21:30:20 +05302713 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2714 {
2715 hdd_link_layer_process_radio_stats(pAdapter,
2716 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302717 spin_lock(&hdd_context_lock);
2718 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2719 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302720 }
2721 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2722 {
2723 hdd_link_layer_process_iface_stats(pAdapter,
2724 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302725 spin_lock(&hdd_context_lock);
2726 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2727 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302728 }
2729 else if ( linkLayerStatsResults->paramId &
2730 WMI_LINK_STATS_ALL_PEER )
2731 {
2732 hdd_link_layer_process_peer_stats(pAdapter,
2733 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302734 spin_lock(&hdd_context_lock);
2735 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2736 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302737 } /* WMI_LINK_STATS_ALL_PEER */
2738 else
2739 {
2740 hddLog(VOS_TRACE_LEVEL_ERROR,
2741 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2742 }
2743
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302744 spin_lock(&hdd_context_lock);
2745 /* complete response event if all requests are completed */
2746 if (0 == context->request_bitmap)
2747 complete(&context->response_event);
2748 spin_unlock(&hdd_context_lock);
2749
Sunil Duttc69bccb2014-05-26 21:30:20 +05302750 break;
2751 }
2752 default:
2753 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2754 break;
2755 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302756
2757 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302758 return;
2759}
2760
2761const struct
2762nla_policy
2763qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2764{
2765 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2766 { .type = NLA_U32 },
2767 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2768 { .type = NLA_U32 },
2769};
2770
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302771static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2772 struct wireless_dev *wdev,
2773 const void *data,
2774 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302775{
2776 int status;
2777 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302778 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302779 struct net_device *dev = wdev->netdev;
2780 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2781 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2782
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302783 ENTER();
2784
Sunil Duttc69bccb2014-05-26 21:30:20 +05302785 status = wlan_hdd_validate_context(pHddCtx);
2786 if (0 != status)
2787 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302788 return -EINVAL;
2789 }
2790
2791 if (NULL == pAdapter)
2792 {
2793 hddLog(VOS_TRACE_LEVEL_ERROR,
2794 FL("HDD adapter is Null"));
2795 return -ENODEV;
2796 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302797 /* check the LLStats Capability */
2798 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2799 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2800 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302801 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302802 FL("Link Layer Statistics not supported by Firmware"));
2803 return -EINVAL;
2804 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302805
2806 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2807 (struct nlattr *)data,
2808 data_len, qca_wlan_vendor_ll_set_policy))
2809 {
2810 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2811 return -EINVAL;
2812 }
2813 if (!tb_vendor
2814 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2815 {
2816 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2817 return -EINVAL;
2818 }
2819 if (!tb_vendor[
2820 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2821 {
2822 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2823 return -EINVAL;
2824 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302825 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302826 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302827
Dino Mycledf0a5d92014-07-04 09:41:55 +05302828 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302829 nla_get_u32(
2830 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2831
Dino Mycledf0a5d92014-07-04 09:41:55 +05302832 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302833 nla_get_u32(
2834 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2835
Dino Mycled3d50022014-07-07 12:58:25 +05302836 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2837 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302838
2839
2840 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302841 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2842 "Statistics Gathering = %d ",
2843 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2844 linkLayerStatsSetReq.mpduSizeThreshold,
2845 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302846
2847 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2848 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302849 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302850 {
2851 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2852 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302853 return -EINVAL;
2854
2855 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302856
Sunil Duttc69bccb2014-05-26 21:30:20 +05302857 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302858 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302859 {
2860 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2861 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302862 return -EINVAL;
2863 }
2864
2865 pAdapter->isLinkLayerStatsSet = 1;
2866
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302867 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302868 return 0;
2869}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302870static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2871 struct wireless_dev *wdev,
2872 const void *data,
2873 int data_len)
2874{
2875 int ret = 0;
2876
2877 vos_ssr_protect(__func__);
2878 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2879 vos_ssr_unprotect(__func__);
2880
2881 return ret;
2882}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302883
2884const struct
2885nla_policy
2886qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2887{
2888 /* Unsigned 32bit value provided by the caller issuing the GET stats
2889 * command. When reporting
2890 * the stats results, the driver uses the same value to indicate
2891 * which GET request the results
2892 * correspond to.
2893 */
2894 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2895
2896 /* Unsigned 32bit value . bit mask to identify what statistics are
2897 requested for retrieval */
2898 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2899};
2900
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302901static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2902 struct wireless_dev *wdev,
2903 const void *data,
2904 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302905{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302906 unsigned long rc;
2907 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302908 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2909 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302910 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302911 struct net_device *dev = wdev->netdev;
2912 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302913 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302914 int status;
2915
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302916 ENTER();
2917
Sunil Duttc69bccb2014-05-26 21:30:20 +05302918 status = wlan_hdd_validate_context(pHddCtx);
2919 if (0 != status)
2920 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302921 return -EINVAL ;
2922 }
2923
2924 if (NULL == pAdapter)
2925 {
2926 hddLog(VOS_TRACE_LEVEL_FATAL,
2927 "%s: HDD adapter is Null", __func__);
2928 return -ENODEV;
2929 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302930
2931 if (pHddStaCtx == NULL)
2932 {
2933 hddLog(VOS_TRACE_LEVEL_FATAL,
2934 "%s: HddStaCtx is Null", __func__);
2935 return -ENODEV;
2936 }
2937
Dino Mycledf0a5d92014-07-04 09:41:55 +05302938 /* check the LLStats Capability */
2939 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2940 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2941 {
2942 hddLog(VOS_TRACE_LEVEL_ERROR,
2943 FL("Link Layer Statistics not supported by Firmware"));
2944 return -EINVAL;
2945 }
2946
Sunil Duttc69bccb2014-05-26 21:30:20 +05302947
2948 if (!pAdapter->isLinkLayerStatsSet)
2949 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302950 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302951 "%s: isLinkLayerStatsSet : %d",
2952 __func__, pAdapter->isLinkLayerStatsSet);
2953 return -EINVAL;
2954 }
2955
Mukul Sharma10313ba2015-07-29 19:14:39 +05302956 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2957 {
2958 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2959 "%s: Roaming in progress, so unable to proceed this request", __func__);
2960 return -EBUSY;
2961 }
2962
Sunil Duttc69bccb2014-05-26 21:30:20 +05302963 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2964 (struct nlattr *)data,
2965 data_len, qca_wlan_vendor_ll_get_policy))
2966 {
2967 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2968 return -EINVAL;
2969 }
2970
2971 if (!tb_vendor
2972 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2973 {
2974 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2975 return -EINVAL;
2976 }
2977
2978 if (!tb_vendor
2979 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2980 {
2981 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2982 return -EINVAL;
2983 }
2984
Sunil Duttc69bccb2014-05-26 21:30:20 +05302985
Dino Mycledf0a5d92014-07-04 09:41:55 +05302986 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302987 nla_get_u32( tb_vendor[
2988 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302989 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302990 nla_get_u32( tb_vendor[
2991 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2992
Dino Mycled3d50022014-07-07 12:58:25 +05302993 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2994 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302995
2996 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302997 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
2998 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302999 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303000
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303001 spin_lock(&hdd_context_lock);
3002 context = &pHddCtx->ll_stats_context;
3003 context->request_id = linkLayerStatsGetReq.reqId;
3004 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
3005 INIT_COMPLETION(context->response_event);
3006 spin_unlock(&hdd_context_lock);
3007
Sunil Duttc69bccb2014-05-26 21:30:20 +05303008 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303009 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303010 {
3011 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3012 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303013 return -EINVAL;
3014 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303015
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303016 rc = wait_for_completion_timeout(&context->response_event,
3017 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
3018 if (!rc)
3019 {
3020 hddLog(LOGE,
3021 FL("Target response timed out request id %d request bitmap 0x%x"),
3022 context->request_id, context->request_bitmap);
3023 return -ETIMEDOUT;
3024 }
3025
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303026 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303027 return 0;
3028}
3029
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303030static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
3031 struct wireless_dev *wdev,
3032 const void *data,
3033 int data_len)
3034{
3035 int ret = 0;
3036
3037 vos_ssr_protect(__func__);
3038 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
3039 vos_ssr_unprotect(__func__);
3040
3041 return ret;
3042}
3043
Sunil Duttc69bccb2014-05-26 21:30:20 +05303044const struct
3045nla_policy
3046qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
3047{
3048 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
3049 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
3050 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
3051 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
3052};
3053
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303054static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3055 struct wireless_dev *wdev,
3056 const void *data,
3057 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303058{
3059 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3060 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05303061 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303062 struct net_device *dev = wdev->netdev;
3063 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3064 u32 statsClearReqMask;
3065 u8 stopReq;
3066 int status;
3067
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303068 ENTER();
3069
Sunil Duttc69bccb2014-05-26 21:30:20 +05303070 status = wlan_hdd_validate_context(pHddCtx);
3071 if (0 != status)
3072 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303073 return -EINVAL;
3074 }
3075
3076 if (NULL == pAdapter)
3077 {
3078 hddLog(VOS_TRACE_LEVEL_FATAL,
3079 "%s: HDD adapter is Null", __func__);
3080 return -ENODEV;
3081 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05303082 /* check the LLStats Capability */
3083 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
3084 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
3085 {
3086 hddLog(VOS_TRACE_LEVEL_ERROR,
3087 FL("Enable LLStats Capability"));
3088 return -EINVAL;
3089 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05303090
3091 if (!pAdapter->isLinkLayerStatsSet)
3092 {
3093 hddLog(VOS_TRACE_LEVEL_FATAL,
3094 "%s: isLinkLayerStatsSet : %d",
3095 __func__, pAdapter->isLinkLayerStatsSet);
3096 return -EINVAL;
3097 }
3098
3099 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
3100 (struct nlattr *)data,
3101 data_len, qca_wlan_vendor_ll_clr_policy))
3102 {
3103 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
3104 return -EINVAL;
3105 }
3106
3107 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
3108
3109 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
3110 {
3111 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
3112 return -EINVAL;
3113
3114 }
3115
Sunil Duttc69bccb2014-05-26 21:30:20 +05303116
Dino Mycledf0a5d92014-07-04 09:41:55 +05303117 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303118 nla_get_u32(
3119 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
3120
Dino Mycledf0a5d92014-07-04 09:41:55 +05303121 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303122 nla_get_u8(
3123 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
3124
3125 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05303126 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303127
Dino Mycled3d50022014-07-07 12:58:25 +05303128 vos_mem_copy(linkLayerStatsClearReq.macAddr,
3129 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05303130
3131 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05303132 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
3133 "statsClearReqMask = 0x%X, stopReq = %d",
3134 linkLayerStatsClearReq.reqId,
3135 linkLayerStatsClearReq.macAddr,
3136 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303137 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303138
3139 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303140 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303141 {
3142 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05303143 hdd_station_ctx_t *pHddStaCtx;
3144
3145 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3146 if (VOS_STATUS_SUCCESS !=
3147 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
3148 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
3149 {
3150 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3151 "WLANTL_ClearInterfaceStats Failed", __func__);
3152 return -EINVAL;
3153 }
3154 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
3155 (statsClearReqMask & WIFI_STATS_IFACE)) {
3156 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
3157 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
3158 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
3159 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
3160 }
3161
Sunil Duttc69bccb2014-05-26 21:30:20 +05303162 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
3163 2 * sizeof(u32) +
3164 NLMSG_HDRLEN);
3165
3166 if (temp_skbuff != NULL)
3167 {
3168
3169 if (nla_put_u32(temp_skbuff,
3170 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
3171 statsClearReqMask) ||
3172 nla_put_u32(temp_skbuff,
3173 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
3174 stopReq))
3175 {
3176 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
3177 kfree_skb(temp_skbuff);
3178 return -EINVAL;
3179 }
3180 /* If the ask is to stop the stats collection as part of clear
3181 * (stopReq = 1) , ensure that no further requests of get
3182 * go to the firmware by having isLinkLayerStatsSet set to 0.
3183 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303184 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05303185 * case the firmware is just asked to clear the statistics.
3186 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05303187 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303188 pAdapter->isLinkLayerStatsSet = 0;
3189 return cfg80211_vendor_cmd_reply(temp_skbuff);
3190 }
3191 return -ENOMEM;
3192 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303193
3194 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303195 return -EINVAL;
3196}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303197static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3198 struct wireless_dev *wdev,
3199 const void *data,
3200 int data_len)
3201{
3202 int ret = 0;
3203
3204 vos_ssr_protect(__func__);
3205 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
3206 vos_ssr_unprotect(__func__);
3207
3208 return ret;
3209
3210
3211}
Sunil Duttc69bccb2014-05-26 21:30:20 +05303212#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
3213
Dino Mycle6fb96c12014-06-10 11:52:40 +05303214#ifdef WLAN_FEATURE_EXTSCAN
3215static const struct nla_policy
3216wlan_hdd_extscan_config_policy
3217 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
3218{
3219 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
3220 { .type = NLA_U32 },
3221 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
3222 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05303223 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
3224 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303225 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
3226 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
3227 { .type = NLA_U32 },
3228 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
3229 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
3230
3231 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
3232 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
3233 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
3234 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
3235 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303236 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
3237 { .type = NLA_U32 },
3238 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
3239 { .type = NLA_U32 },
3240 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
3241 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303242 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
3243 { .type = NLA_U32 },
3244 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
3245 { .type = NLA_U32 },
3246 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
3247 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303248 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
3249 { .type = NLA_U8 },
3250 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303251 { .type = NLA_U8 },
3252 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
3253 { .type = NLA_U8 },
3254 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
3255 { .type = NLA_U8 },
3256
3257 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
3258 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05303259 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
3260 .type = NLA_UNSPEC,
3261 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05303262 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
3263 { .type = NLA_S32 },
3264 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
3265 { .type = NLA_S32 },
3266 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
3267 { .type = NLA_U32 },
3268 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
3269 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303270 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
3271 { .type = NLA_U32 },
3272 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
3273 { .type = NLA_BINARY,
3274 .len = IEEE80211_MAX_SSID_LEN + 1 },
3275 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303276 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303277 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
3278 { .type = NLA_U32 },
3279 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
3280 { .type = NLA_U8 },
3281 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
3282 { .type = NLA_S32 },
3283 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
3284 { .type = NLA_S32 },
3285 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
3286 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303287};
3288
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303289/**
3290 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
3291 * @ctx: hdd global context
3292 * @data: capabilities data
3293 *
3294 * Return: none
3295 */
3296static void
3297wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303298{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303299 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303300 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303301 tSirEXTScanCapabilitiesEvent *data =
3302 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303303
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303304 ENTER();
3305
3306 if (wlan_hdd_validate_context(pHddCtx))
3307 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303308 return;
3309 }
3310
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303311 if (!pMsg)
3312 {
3313 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3314 return;
3315 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303316
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303317 vos_spin_lock_acquire(&hdd_context_lock);
3318
3319 context = &pHddCtx->ext_scan_context;
3320 /* validate response received from target*/
3321 if (context->request_id != data->requestId)
3322 {
3323 vos_spin_lock_release(&hdd_context_lock);
3324 hddLog(LOGE,
3325 FL("Target response id did not match: request_id %d resposne_id %d"),
3326 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303327 return;
3328 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303329 else
3330 {
3331 context->capability_response = *data;
3332 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303333 }
3334
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303335 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303336
Dino Mycle6fb96c12014-06-10 11:52:40 +05303337 return;
3338}
3339
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303340/*
3341 * define short names for the global vendor params
3342 * used by wlan_hdd_send_ext_scan_capability()
3343 */
3344#define PARAM_REQUEST_ID \
3345 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3346#define PARAM_STATUS \
3347 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
3348#define MAX_SCAN_CACHE_SIZE \
3349 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
3350#define MAX_SCAN_BUCKETS \
3351 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
3352#define MAX_AP_CACHE_PER_SCAN \
3353 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
3354#define MAX_RSSI_SAMPLE_SIZE \
3355 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
3356#define MAX_SCAN_RPT_THRHOLD \
3357 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
3358#define MAX_HOTLIST_BSSIDS \
3359 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
3360#define MAX_BSSID_HISTORY_ENTRIES \
3361 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
3362#define MAX_HOTLIST_SSIDS \
3363 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303364#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
3365 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303366
3367static int wlan_hdd_send_ext_scan_capability(void *ctx)
3368{
3369 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3370 struct sk_buff *skb = NULL;
3371 int ret;
3372 tSirEXTScanCapabilitiesEvent *data;
3373 tANI_U32 nl_buf_len;
3374
3375 ret = wlan_hdd_validate_context(pHddCtx);
3376 if (0 != ret)
3377 {
3378 return ret;
3379 }
3380
3381 data = &(pHddCtx->ext_scan_context.capability_response);
3382
3383 nl_buf_len = NLMSG_HDRLEN;
3384 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
3385 (sizeof(data->status) + NLA_HDRLEN) +
3386 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
3387 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
3388 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
3389 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
3390 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
3391 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
3392 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
3393 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
3394
3395 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
3396
3397 if (!skb)
3398 {
3399 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
3400 return -ENOMEM;
3401 }
3402
3403 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
3404 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
3405 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
3406 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
3407 data->maxRssiSampleSize, data->maxScanReportingThreshold);
3408 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
3409 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
3410 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
3411
3412 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
3413 nla_put_u32(skb, PARAM_STATUS, data->status) ||
3414 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
3415 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
3416 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
3417 data->maxApPerScan) ||
3418 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
3419 data->maxRssiSampleSize) ||
3420 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
3421 data->maxScanReportingThreshold) ||
3422 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
3423 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
3424 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303425 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
3426 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303427 {
3428 hddLog(LOGE, FL("nla put fail"));
3429 goto nla_put_failure;
3430 }
3431
3432 cfg80211_vendor_cmd_reply(skb);
3433 return 0;
3434
3435nla_put_failure:
3436 kfree_skb(skb);
3437 return -EINVAL;;
3438}
3439
3440/*
3441 * done with short names for the global vendor params
3442 * used by wlan_hdd_send_ext_scan_capability()
3443 */
3444#undef PARAM_REQUEST_ID
3445#undef PARAM_STATUS
3446#undef MAX_SCAN_CACHE_SIZE
3447#undef MAX_SCAN_BUCKETS
3448#undef MAX_AP_CACHE_PER_SCAN
3449#undef MAX_RSSI_SAMPLE_SIZE
3450#undef MAX_SCAN_RPT_THRHOLD
3451#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303452#undef MAX_BSSID_HISTORY_ENTRIES
3453#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05303454
3455static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
3456{
3457 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
3458 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303459 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303460 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303461
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303462 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303463
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303464 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303465 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303466
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303467 if (!pMsg)
3468 {
3469 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303470 return;
3471 }
3472
Dino Mycle6fb96c12014-06-10 11:52:40 +05303473 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3474 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
3475
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303476 context = &pHddCtx->ext_scan_context;
3477 spin_lock(&hdd_context_lock);
3478 if (context->request_id == pData->requestId) {
3479 context->response_status = pData->status ? -EINVAL : 0;
3480 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303481 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303482 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303483
3484 /*
3485 * Store the Request ID for comparing with the requestID obtained
3486 * in other requests.HDD shall return a failure is the extscan_stop
3487 * request is issued with a different requestId as that of the
3488 * extscan_start request. Also, This requestId shall be used while
3489 * indicating the full scan results to the upper layers.
3490 * The requestId is stored with the assumption that the firmware
3491 * shall return the ext scan start request's requestId in ext scan
3492 * start response.
3493 */
3494 if (pData->status == 0)
3495 pMac->sme.extScanStartReqId = pData->requestId;
3496
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303497 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303498 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303499}
3500
3501
3502static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
3503{
3504 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
3505 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303506 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303507
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303508 ENTER();
3509
3510 if (wlan_hdd_validate_context(pHddCtx)){
3511 return;
3512 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303513
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303514 if (!pMsg)
3515 {
3516 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303517 return;
3518 }
3519
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303520 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3521 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303522
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303523 context = &pHddCtx->ext_scan_context;
3524 spin_lock(&hdd_context_lock);
3525 if (context->request_id == pData->requestId) {
3526 context->response_status = pData->status ? -EINVAL : 0;
3527 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303528 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303529 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303530
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303531 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303532 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303533}
3534
Dino Mycle6fb96c12014-06-10 11:52:40 +05303535static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3536 void *pMsg)
3537{
3538 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303539 tpSirEXTScanSetBssidHotListRspParams pData =
3540 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303541 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303542
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303543 ENTER();
3544
3545 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303546 return;
3547 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303548
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303549 if (!pMsg)
3550 {
3551 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3552 return;
3553 }
3554
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303555 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3556 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303557
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303558 context = &pHddCtx->ext_scan_context;
3559 spin_lock(&hdd_context_lock);
3560 if (context->request_id == pData->requestId) {
3561 context->response_status = pData->status ? -EINVAL : 0;
3562 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303563 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303564 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303565
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303566 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303567 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303568}
3569
3570static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3571 void *pMsg)
3572{
3573 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303574 tpSirEXTScanResetBssidHotlistRspParams pData =
3575 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303576 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303577
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303578 ENTER();
3579
3580 if (wlan_hdd_validate_context(pHddCtx)) {
3581 return;
3582 }
3583 if (!pMsg)
3584 {
3585 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303586 return;
3587 }
3588
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303589 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3590 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303591
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303592 context = &pHddCtx->ext_scan_context;
3593 spin_lock(&hdd_context_lock);
3594 if (context->request_id == pData->requestId) {
3595 context->response_status = pData->status ? -EINVAL : 0;
3596 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303597 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303598 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303599
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303600 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303601 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303602}
3603
Dino Mycle6fb96c12014-06-10 11:52:40 +05303604static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3605 void *pMsg)
3606{
3607 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3608 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303609 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303610 tANI_S32 totalResults;
3611 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303612 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3613 struct hdd_ext_scan_context *context;
3614 bool ignore_cached_results = false;
3615 tExtscanCachedScanResult *result;
3616 struct nlattr *nla_results;
3617 tANI_U16 ieLength= 0;
3618 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303619
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303620 ENTER();
3621
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303622 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303623 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303624
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303625 if (!pMsg)
3626 {
3627 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3628 return;
3629 }
3630
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303631 spin_lock(&hdd_context_lock);
3632 context = &pHddCtx->ext_scan_context;
3633 ignore_cached_results = context->ignore_cached_results;
3634 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303635
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303636 if (ignore_cached_results) {
3637 hddLog(LOGE,
3638 FL("Ignore the cached results received after timeout"));
3639 return;
3640 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303641
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303642 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3643 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303644
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303645 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303646
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303647 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3648 scan_id_index++) {
3649 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303650
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303651 totalResults = result->num_results;
3652 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3653 result->scan_id, result->flags, totalResults);
3654 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303655
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303656 do{
3657 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3658 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3659 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303660
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303661 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3662 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3663
3664 if (!skb) {
3665 hddLog(VOS_TRACE_LEVEL_ERROR,
3666 FL("cfg80211_vendor_event_alloc failed"));
3667 return;
3668 }
3669
3670 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3671
3672 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3673 pData->requestId) ||
3674 nla_put_u32(skb,
3675 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3676 resultsPerEvent)) {
3677 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3678 goto fail;
3679 }
3680 if (nla_put_u8(skb,
3681 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3682 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303683 {
3684 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3685 goto fail;
3686 }
3687
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303688 if (nla_put_u32(skb,
3689 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3690 result->scan_id)) {
3691 hddLog(LOGE, FL("put fail"));
3692 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303693 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303694
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303695 nla_results = nla_nest_start(skb,
3696 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3697 if (!nla_results)
3698 goto fail;
3699
3700 if (resultsPerEvent) {
3701 struct nlattr *aps;
3702 struct nlattr *nla_result;
3703
3704 nla_result = nla_nest_start(skb, scan_id_index);
3705 if(!nla_result)
3706 goto fail;
3707
3708 if (nla_put_u32(skb,
3709 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3710 result->scan_id) ||
3711 nla_put_u32(skb,
3712 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3713 result->flags) ||
3714 nla_put_u32(skb,
3715 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3716 totalResults)) {
3717 hddLog(LOGE, FL("put fail"));
3718 goto fail;
3719 }
3720
3721 aps = nla_nest_start(skb,
3722 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3723 if (!aps)
3724 {
3725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3726 goto fail;
3727 }
3728
3729 head_ptr = (tpSirWifiScanResult) &(result->ap);
3730
3731 for (j = 0; j < resultsPerEvent; j++, i++) {
3732 struct nlattr *ap;
3733 pSirWifiScanResult = head_ptr + i;
3734
3735 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303736 * Firmware returns timestamp from extscan_start till
3737 * BSSID was cached (in micro seconds). Add this with
3738 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303739 * to derive the time since boot when the
3740 * BSSID was cached.
3741 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303742 pSirWifiScanResult->ts +=
3743 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303744 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3745 "Ssid (%s)"
3746 "Bssid: %pM "
3747 "Channel (%u)"
3748 "Rssi (%d)"
3749 "RTT (%u)"
3750 "RTT_SD (%u)"
3751 "Beacon Period %u"
3752 "Capability 0x%x "
3753 "Ie length %d",
3754 i,
3755 pSirWifiScanResult->ts,
3756 pSirWifiScanResult->ssid,
3757 pSirWifiScanResult->bssid,
3758 pSirWifiScanResult->channel,
3759 pSirWifiScanResult->rssi,
3760 pSirWifiScanResult->rtt,
3761 pSirWifiScanResult->rtt_sd,
3762 pSirWifiScanResult->beaconPeriod,
3763 pSirWifiScanResult->capability,
3764 ieLength);
3765
3766 ap = nla_nest_start(skb, j + 1);
3767 if (!ap)
3768 {
3769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3770 goto fail;
3771 }
3772
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303773 if (hdd_wlan_nla_put_u64(skb,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303774 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3775 pSirWifiScanResult->ts) )
3776 {
3777 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3778 goto fail;
3779 }
3780 if (nla_put(skb,
3781 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3782 sizeof(pSirWifiScanResult->ssid),
3783 pSirWifiScanResult->ssid) )
3784 {
3785 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3786 goto fail;
3787 }
3788 if (nla_put(skb,
3789 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3790 sizeof(pSirWifiScanResult->bssid),
3791 pSirWifiScanResult->bssid) )
3792 {
3793 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3794 goto fail;
3795 }
3796 if (nla_put_u32(skb,
3797 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3798 pSirWifiScanResult->channel) )
3799 {
3800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3801 goto fail;
3802 }
3803 if (nla_put_s32(skb,
3804 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3805 pSirWifiScanResult->rssi) )
3806 {
3807 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3808 goto fail;
3809 }
3810 if (nla_put_u32(skb,
3811 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3812 pSirWifiScanResult->rtt) )
3813 {
3814 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3815 goto fail;
3816 }
3817 if (nla_put_u32(skb,
3818 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3819 pSirWifiScanResult->rtt_sd))
3820 {
3821 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3822 goto fail;
3823 }
3824 if (nla_put_u32(skb,
3825 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3826 pSirWifiScanResult->beaconPeriod))
3827 {
3828 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3829 goto fail;
3830 }
3831 if (nla_put_u32(skb,
3832 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3833 pSirWifiScanResult->capability))
3834 {
3835 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3836 goto fail;
3837 }
3838 if (nla_put_u32(skb,
3839 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3840 ieLength))
3841 {
3842 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3843 goto fail;
3844 }
3845
3846 if (ieLength)
3847 if (nla_put(skb,
3848 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3849 ieLength, ie)) {
3850 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3851 goto fail;
3852 }
3853
3854 nla_nest_end(skb, ap);
3855 }
3856 nla_nest_end(skb, aps);
3857 nla_nest_end(skb, nla_result);
3858 }
3859
3860 nla_nest_end(skb, nla_results);
3861
3862 cfg80211_vendor_cmd_reply(skb);
3863
3864 } while (totalResults > 0);
3865 }
3866
3867 if (!pData->moreData) {
3868 spin_lock(&hdd_context_lock);
3869 context->response_status = 0;
3870 complete(&context->response_event);
3871 spin_unlock(&hdd_context_lock);
3872 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303873
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303874 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303875 return;
3876fail:
3877 kfree_skb(skb);
3878 return;
3879}
3880
3881static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3882 void *pMsg)
3883{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303884 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303885 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3886 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303887 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303888
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303889 ENTER();
3890
3891 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303892 hddLog(LOGE,
3893 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303894 return;
3895 }
3896 if (!pMsg)
3897 {
3898 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303899 return;
3900 }
3901
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303902 if (pData->bss_found)
3903 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3904 else
3905 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3906
Dino Mycle6fb96c12014-06-10 11:52:40 +05303907 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303908#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3909 NULL,
3910#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303911 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303912 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303913
3914 if (!skb) {
3915 hddLog(VOS_TRACE_LEVEL_ERROR,
3916 FL("cfg80211_vendor_event_alloc failed"));
3917 return;
3918 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303919
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303920 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3921 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3922 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3923 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3924
3925 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303926 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3927 "Ssid (%s) "
3928 "Bssid (" MAC_ADDRESS_STR ") "
3929 "Channel (%u) "
3930 "Rssi (%d) "
3931 "RTT (%u) "
3932 "RTT_SD (%u) ",
3933 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303934 pData->bssHotlist[i].ts,
3935 pData->bssHotlist[i].ssid,
3936 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3937 pData->bssHotlist[i].channel,
3938 pData->bssHotlist[i].rssi,
3939 pData->bssHotlist[i].rtt,
3940 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303941 }
3942
3943 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3944 pData->requestId) ||
3945 nla_put_u32(skb,
3946 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303947 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303948 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3949 goto fail;
3950 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303951 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303952 struct nlattr *aps;
3953
3954 aps = nla_nest_start(skb,
3955 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3956 if (!aps)
3957 goto fail;
3958
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303959 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303960 struct nlattr *ap;
3961
3962 ap = nla_nest_start(skb, i + 1);
3963 if (!ap)
3964 goto fail;
3965
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303966 if (hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303967 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303968 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303969 nla_put(skb,
3970 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303971 sizeof(pData->bssHotlist[i].ssid),
3972 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303973 nla_put(skb,
3974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303975 sizeof(pData->bssHotlist[i].bssid),
3976 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303977 nla_put_u32(skb,
3978 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303979 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303980 nla_put_s32(skb,
3981 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303982 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303983 nla_put_u32(skb,
3984 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303985 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303986 nla_put_u32(skb,
3987 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303988 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303989 goto fail;
3990
3991 nla_nest_end(skb, ap);
3992 }
3993 nla_nest_end(skb, aps);
3994
3995 if (nla_put_u8(skb,
3996 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3997 pData->moreData))
3998 goto fail;
3999 }
4000
4001 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304002 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304003 return;
4004
4005fail:
4006 kfree_skb(skb);
4007 return;
4008
4009}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304010
4011static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
4012 void *pMsg)
4013{
4014 struct sk_buff *skb;
4015 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4016 tpSirWifiFullScanResultEvent pData =
4017 (tpSirWifiFullScanResultEvent) (pMsg);
4018
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304019 ENTER();
4020
4021 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304022 hddLog(LOGE,
4023 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304024 return;
4025 }
4026 if (!pMsg)
4027 {
4028 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304029 return;
4030 }
4031
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304032 /*
4033 * If the full scan result including IE data exceeds NL 4K size
4034 * limitation, drop that beacon/probe rsp frame.
4035 */
4036 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
4037 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
4038 return;
4039 }
4040
Dino Mycle6fb96c12014-06-10 11:52:40 +05304041 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304042#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4043 NULL,
4044#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304045 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4046 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
4047 GFP_KERNEL);
4048
4049 if (!skb) {
4050 hddLog(VOS_TRACE_LEVEL_ERROR,
4051 FL("cfg80211_vendor_event_alloc failed"));
4052 return;
4053 }
4054
Dino Mycle6fb96c12014-06-10 11:52:40 +05304055 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
4056 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
4057 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
4058 "Ssid (%s)"
4059 "Bssid (" MAC_ADDRESS_STR ")"
4060 "Channel (%u)"
4061 "Rssi (%d)"
4062 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304063 "RTT_SD (%u)"
4064 "Bcn Period %d"
4065 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05304066 pData->ap.ts,
4067 pData->ap.ssid,
4068 MAC_ADDR_ARRAY(pData->ap.bssid),
4069 pData->ap.channel,
4070 pData->ap.rssi,
4071 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304072 pData->ap.rtt_sd,
4073 pData->ap.beaconPeriod,
4074 pData->ap.capability);
4075
Dino Mycle6fb96c12014-06-10 11:52:40 +05304076 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
4077 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4078 pData->requestId) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304079 hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304080 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
4081 pData->ap.ts) ||
4082 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
4083 sizeof(pData->ap.ssid),
4084 pData->ap.ssid) ||
4085 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
4086 WNI_CFG_BSSID_LEN,
4087 pData->ap.bssid) ||
4088 nla_put_u32(skb,
4089 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
4090 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05304091 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304092 pData->ap.rssi) ||
4093 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
4094 pData->ap.rtt) ||
4095 nla_put_u32(skb,
4096 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
4097 pData->ap.rtt_sd) ||
4098 nla_put_u16(skb,
4099 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
4100 pData->ap.beaconPeriod) ||
4101 nla_put_u16(skb,
4102 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
4103 pData->ap.capability) ||
4104 nla_put_u32(skb,
4105 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304106 pData->ieLength) ||
4107 nla_put_u8(skb,
4108 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
4109 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304110 {
4111 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4112 goto nla_put_failure;
4113 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304114
4115 if (pData->ieLength) {
4116 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
4117 pData->ieLength,
4118 pData->ie))
4119 {
4120 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4121 goto nla_put_failure;
4122 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304123 }
4124
4125 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304126 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304127 return;
4128
4129nla_put_failure:
4130 kfree_skb(skb);
4131 return;
4132}
4133
4134static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
4135 void *pMsg)
4136{
4137 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4138 struct sk_buff *skb = NULL;
4139 tpSirEXTScanResultsAvailableIndParams pData =
4140 (tpSirEXTScanResultsAvailableIndParams) pMsg;
4141
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304142 ENTER();
4143
4144 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304145 hddLog(LOGE,
4146 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304147 return;
4148 }
4149 if (!pMsg)
4150 {
4151 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304152 return;
4153 }
4154
4155 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304156#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4157 NULL,
4158#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304159 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4160 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
4161 GFP_KERNEL);
4162
4163 if (!skb) {
4164 hddLog(VOS_TRACE_LEVEL_ERROR,
4165 FL("cfg80211_vendor_event_alloc failed"));
4166 return;
4167 }
4168
Dino Mycle6fb96c12014-06-10 11:52:40 +05304169 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
4170 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
4171 pData->numResultsAvailable);
4172 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4173 pData->requestId) ||
4174 nla_put_u32(skb,
4175 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
4176 pData->numResultsAvailable)) {
4177 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4178 goto nla_put_failure;
4179 }
4180
4181 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304182 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304183 return;
4184
4185nla_put_failure:
4186 kfree_skb(skb);
4187 return;
4188}
4189
4190static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
4191{
4192 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4193 struct sk_buff *skb = NULL;
4194 tpSirEXTScanProgressIndParams pData =
4195 (tpSirEXTScanProgressIndParams) pMsg;
4196
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304197 ENTER();
4198
4199 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304200 hddLog(LOGE,
4201 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304202 return;
4203 }
4204 if (!pMsg)
4205 {
4206 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304207 return;
4208 }
4209
4210 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304211#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4212 NULL,
4213#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304214 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4215 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
4216 GFP_KERNEL);
4217
4218 if (!skb) {
4219 hddLog(VOS_TRACE_LEVEL_ERROR,
4220 FL("cfg80211_vendor_event_alloc failed"));
4221 return;
4222 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304223 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304224 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
4225 pData->extScanEventType);
4226 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
4227 pData->status);
4228
4229 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
4230 pData->extScanEventType) ||
4231 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05304232 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4233 pData->requestId) ||
4234 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304235 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
4236 pData->status)) {
4237 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4238 goto nla_put_failure;
4239 }
4240
4241 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304242 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304243 return;
4244
4245nla_put_failure:
4246 kfree_skb(skb);
4247 return;
4248}
4249
4250void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
4251 void *pMsg)
4252{
4253 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4254
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304255 ENTER();
4256
Dino Mycle6fb96c12014-06-10 11:52:40 +05304257 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304258 return;
4259 }
4260
4261 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
4262
4263
4264 switch(evType) {
4265 case SIR_HAL_EXTSCAN_START_RSP:
4266 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
4267 break;
4268
4269 case SIR_HAL_EXTSCAN_STOP_RSP:
4270 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
4271 break;
4272 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
4273 /* There is no need to send this response to upper layer
4274 Just log the message */
4275 hddLog(VOS_TRACE_LEVEL_INFO,
4276 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
4277 break;
4278 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
4279 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
4280 break;
4281
4282 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
4283 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
4284 break;
4285
Dino Mycle6fb96c12014-06-10 11:52:40 +05304286 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304287 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304288 break;
4289 case SIR_HAL_EXTSCAN_PROGRESS_IND:
4290 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
4291 break;
4292 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
4293 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
4294 break;
4295 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
4296 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
4297 break;
4298 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
4299 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
4300 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304301 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
4302 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
4303 break;
4304 default:
4305 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
4306 break;
4307 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304308 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304309}
4310
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304311static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4312 struct wireless_dev *wdev,
4313 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304314{
Dino Myclee8843b32014-07-04 14:21:45 +05304315 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304316 struct net_device *dev = wdev->netdev;
4317 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4318 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4319 struct nlattr
4320 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4321 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304322 struct hdd_ext_scan_context *context;
4323 unsigned long rc;
4324 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304325
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304326 ENTER();
4327
Dino Mycle6fb96c12014-06-10 11:52:40 +05304328 status = wlan_hdd_validate_context(pHddCtx);
4329 if (0 != status)
4330 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304331 return -EINVAL;
4332 }
Dino Myclee8843b32014-07-04 14:21:45 +05304333 /* check the EXTScan Capability */
4334 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304335 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4336 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304337 {
4338 hddLog(VOS_TRACE_LEVEL_ERROR,
4339 FL("EXTScan not enabled/supported by Firmware"));
4340 return -EINVAL;
4341 }
4342
Dino Mycle6fb96c12014-06-10 11:52:40 +05304343 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4344 data, dataLen,
4345 wlan_hdd_extscan_config_policy)) {
4346 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4347 return -EINVAL;
4348 }
4349
4350 /* Parse and fetch request Id */
4351 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4352 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4353 return -EINVAL;
4354 }
4355
Dino Myclee8843b32014-07-04 14:21:45 +05304356 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304357 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304358 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304359
Dino Myclee8843b32014-07-04 14:21:45 +05304360 reqMsg.sessionId = pAdapter->sessionId;
4361 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304362
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304363 vos_spin_lock_acquire(&hdd_context_lock);
4364 context = &pHddCtx->ext_scan_context;
4365 context->request_id = reqMsg.requestId;
4366 INIT_COMPLETION(context->response_event);
4367 vos_spin_lock_release(&hdd_context_lock);
4368
Dino Myclee8843b32014-07-04 14:21:45 +05304369 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304370 if (!HAL_STATUS_SUCCESS(status)) {
4371 hddLog(VOS_TRACE_LEVEL_ERROR,
4372 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304373 return -EINVAL;
4374 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304375
4376 rc = wait_for_completion_timeout(&context->response_event,
4377 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4378 if (!rc) {
4379 hddLog(LOGE, FL("Target response timed out"));
4380 return -ETIMEDOUT;
4381 }
4382
4383 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
4384 if (ret)
4385 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
4386
4387 return ret;
4388
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304389 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304390 return 0;
4391}
4392
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304393static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4394 struct wireless_dev *wdev,
4395 const void *data, int dataLen)
4396{
4397 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304398
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304399 vos_ssr_protect(__func__);
4400 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
4401 vos_ssr_unprotect(__func__);
4402
4403 return ret;
4404}
4405
4406static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4407 struct wireless_dev *wdev,
4408 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304409{
Dino Myclee8843b32014-07-04 14:21:45 +05304410 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304411 struct net_device *dev = wdev->netdev;
4412 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4413 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4414 struct nlattr
4415 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4416 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304417 struct hdd_ext_scan_context *context;
4418 unsigned long rc;
4419 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304420
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304421 ENTER();
4422
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304423 if (VOS_FTM_MODE == hdd_get_conparam()) {
4424 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4425 return -EINVAL;
4426 }
4427
Dino Mycle6fb96c12014-06-10 11:52:40 +05304428 status = wlan_hdd_validate_context(pHddCtx);
4429 if (0 != status)
4430 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304431 return -EINVAL;
4432 }
Dino Myclee8843b32014-07-04 14:21:45 +05304433 /* check the EXTScan Capability */
4434 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304435 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4436 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304437 {
4438 hddLog(VOS_TRACE_LEVEL_ERROR,
4439 FL("EXTScan not enabled/supported by Firmware"));
4440 return -EINVAL;
4441 }
4442
Dino Mycle6fb96c12014-06-10 11:52:40 +05304443 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4444 data, dataLen,
4445 wlan_hdd_extscan_config_policy)) {
4446 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4447 return -EINVAL;
4448 }
4449 /* Parse and fetch request Id */
4450 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4451 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4452 return -EINVAL;
4453 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304454
Dino Myclee8843b32014-07-04 14:21:45 +05304455 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304456 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4457
Dino Myclee8843b32014-07-04 14:21:45 +05304458 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304459
Dino Myclee8843b32014-07-04 14:21:45 +05304460 reqMsg.sessionId = pAdapter->sessionId;
4461 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304462
4463 /* Parse and fetch flush parameter */
4464 if (!tb
4465 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
4466 {
4467 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
4468 goto failed;
4469 }
Dino Myclee8843b32014-07-04 14:21:45 +05304470 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304471 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
4472
Dino Myclee8843b32014-07-04 14:21:45 +05304473 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304474
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304475 spin_lock(&hdd_context_lock);
4476 context = &pHddCtx->ext_scan_context;
4477 context->request_id = reqMsg.requestId;
4478 context->ignore_cached_results = false;
4479 INIT_COMPLETION(context->response_event);
4480 spin_unlock(&hdd_context_lock);
4481
Dino Myclee8843b32014-07-04 14:21:45 +05304482 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304483 if (!HAL_STATUS_SUCCESS(status)) {
4484 hddLog(VOS_TRACE_LEVEL_ERROR,
4485 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304486 return -EINVAL;
4487 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304488
4489 rc = wait_for_completion_timeout(&context->response_event,
4490 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4491 if (!rc) {
4492 hddLog(LOGE, FL("Target response timed out"));
4493 retval = -ETIMEDOUT;
4494 spin_lock(&hdd_context_lock);
4495 context->ignore_cached_results = true;
4496 spin_unlock(&hdd_context_lock);
4497 } else {
4498 spin_lock(&hdd_context_lock);
4499 retval = context->response_status;
4500 spin_unlock(&hdd_context_lock);
4501 }
4502
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304503 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304504 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304505
4506failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05304507 return -EINVAL;
4508}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304509static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4510 struct wireless_dev *wdev,
4511 const void *data, int dataLen)
4512{
4513 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304514
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304515 vos_ssr_protect(__func__);
4516 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
4517 vos_ssr_unprotect(__func__);
4518
4519 return ret;
4520}
4521
4522static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304523 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05304524 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304525{
4526 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
4527 struct net_device *dev = wdev->netdev;
4528 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4529 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4530 struct nlattr
4531 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4532 struct nlattr
4533 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4534 struct nlattr *apTh;
4535 eHalStatus status;
4536 tANI_U8 i = 0;
4537 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304538 struct hdd_ext_scan_context *context;
4539 tANI_U32 request_id;
4540 unsigned long rc;
4541 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304542
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304543 ENTER();
4544
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304545 if (VOS_FTM_MODE == hdd_get_conparam()) {
4546 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4547 return -EINVAL;
4548 }
4549
Dino Mycle6fb96c12014-06-10 11:52:40 +05304550 status = wlan_hdd_validate_context(pHddCtx);
4551 if (0 != status)
4552 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304553 return -EINVAL;
4554 }
Dino Myclee8843b32014-07-04 14:21:45 +05304555 /* check the EXTScan Capability */
4556 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304557 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4558 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304559 {
4560 hddLog(VOS_TRACE_LEVEL_ERROR,
4561 FL("EXTScan not enabled/supported by Firmware"));
4562 return -EINVAL;
4563 }
4564
Dino Mycle6fb96c12014-06-10 11:52:40 +05304565 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4566 data, dataLen,
4567 wlan_hdd_extscan_config_policy)) {
4568 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4569 return -EINVAL;
4570 }
4571
4572 /* Parse and fetch request Id */
4573 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4574 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4575 return -EINVAL;
4576 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304577 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4578 vos_mem_malloc(sizeof(*pReqMsg));
4579 if (!pReqMsg) {
4580 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4581 return -ENOMEM;
4582 }
4583
Dino Myclee8843b32014-07-04 14:21:45 +05304584
Dino Mycle6fb96c12014-06-10 11:52:40 +05304585 pReqMsg->requestId = nla_get_u32(
4586 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4587 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4588
4589 /* Parse and fetch number of APs */
4590 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4591 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4592 goto fail;
4593 }
4594
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304595 /* Parse and fetch lost ap sample size */
4596 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4597 hddLog(LOGE, FL("attr lost ap sample size failed"));
4598 goto fail;
4599 }
4600
4601 pReqMsg->lostBssidSampleSize = nla_get_u32(
4602 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4603 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4604
Dino Mycle6fb96c12014-06-10 11:52:40 +05304605 pReqMsg->sessionId = pAdapter->sessionId;
4606 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4607
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304608 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304609 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304610 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4611 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4612 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4613 goto fail;
4614 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304615 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304616
4617 nla_for_each_nested(apTh,
4618 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304619 if (i == pReqMsg->numBssid) {
4620 hddLog(LOGW, FL("Ignoring excess AP"));
4621 break;
4622 }
4623
Dino Mycle6fb96c12014-06-10 11:52:40 +05304624 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4625 nla_data(apTh), nla_len(apTh),
4626 NULL)) {
4627 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4628 goto fail;
4629 }
4630
4631 /* Parse and fetch MAC address */
4632 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4633 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4634 goto fail;
4635 }
4636 memcpy(pReqMsg->ap[i].bssid, nla_data(
4637 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4638 sizeof(tSirMacAddr));
4639 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4640
4641 /* Parse and fetch low RSSI */
4642 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4643 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4644 goto fail;
4645 }
4646 pReqMsg->ap[i].low = nla_get_s32(
4647 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4648 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4649
4650 /* Parse and fetch high RSSI */
4651 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4652 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4653 goto fail;
4654 }
4655 pReqMsg->ap[i].high = nla_get_s32(
4656 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4657 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4658 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304659 i++;
4660 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304661
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304662 if (i < pReqMsg->numBssid) {
4663 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4664 i, pReqMsg->numBssid);
4665 pReqMsg->numBssid = i;
4666 }
4667
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304668 context = &pHddCtx->ext_scan_context;
4669 spin_lock(&hdd_context_lock);
4670 INIT_COMPLETION(context->response_event);
4671 context->request_id = request_id = pReqMsg->requestId;
4672 spin_unlock(&hdd_context_lock);
4673
Dino Mycle6fb96c12014-06-10 11:52:40 +05304674 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4675 if (!HAL_STATUS_SUCCESS(status)) {
4676 hddLog(VOS_TRACE_LEVEL_ERROR,
4677 FL("sme_SetBssHotlist failed(err=%d)"), status);
4678 vos_mem_free(pReqMsg);
4679 return -EINVAL;
4680 }
4681
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304682 /* request was sent -- wait for the response */
4683 rc = wait_for_completion_timeout(&context->response_event,
4684 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4685
4686 if (!rc) {
4687 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4688 retval = -ETIMEDOUT;
4689 } else {
4690 spin_lock(&hdd_context_lock);
4691 if (context->request_id == request_id)
4692 retval = context->response_status;
4693 else
4694 retval = -EINVAL;
4695 spin_unlock(&hdd_context_lock);
4696 }
4697
Dino Myclee8843b32014-07-04 14:21:45 +05304698 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304699 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304700 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304701
4702fail:
4703 vos_mem_free(pReqMsg);
4704 return -EINVAL;
4705}
4706
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304707static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4708 struct wireless_dev *wdev,
4709 const void *data, int dataLen)
4710{
4711 int ret = 0;
4712
4713 vos_ssr_protect(__func__);
4714 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4715 dataLen);
4716 vos_ssr_unprotect(__func__);
4717
4718 return ret;
4719}
4720
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304721static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304722 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304723 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304724{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304725 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4726 struct net_device *dev = wdev->netdev;
4727 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4728 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4729 uint8_t num_channels = 0;
4730 uint8_t num_chan_new = 0;
4731 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304732 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304733 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304734 tWifiBand wifiBand;
4735 eHalStatus status;
4736 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304737 tANI_U8 i,j,k;
4738 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304739
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304740 ENTER();
4741
Dino Mycle6fb96c12014-06-10 11:52:40 +05304742 status = wlan_hdd_validate_context(pHddCtx);
4743 if (0 != status)
4744 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304745 return -EINVAL;
4746 }
Dino Myclee8843b32014-07-04 14:21:45 +05304747
Dino Mycle6fb96c12014-06-10 11:52:40 +05304748 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4749 data, dataLen,
4750 wlan_hdd_extscan_config_policy)) {
4751 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4752 return -EINVAL;
4753 }
4754
4755 /* Parse and fetch request Id */
4756 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4757 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4758 return -EINVAL;
4759 }
4760 requestId = nla_get_u32(
4761 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4762 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4763
4764 /* Parse and fetch wifi band */
4765 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4766 {
4767 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4768 return -EINVAL;
4769 }
4770 wifiBand = nla_get_u32(
4771 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4772 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4773
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304774 /* Parse and fetch max channels */
4775 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4776 {
4777 hddLog(LOGE, FL("attr max channels failed"));
4778 return -EINVAL;
4779 }
4780 maxChannels = nla_get_u32(
4781 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4782 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4783
Dino Mycle6fb96c12014-06-10 11:52:40 +05304784 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304785 wifiBand, chan_list,
4786 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304787 if (eHAL_STATUS_SUCCESS != status) {
4788 hddLog(VOS_TRACE_LEVEL_ERROR,
4789 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4790 return -EINVAL;
4791 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304792
Agrawal Ashish16abf782016-08-18 22:42:59 +05304793 num_channels = VOS_MIN(num_channels, maxChannels);
4794 num_chan_new = num_channels;
4795 /* remove the indoor only channels if iface is SAP */
4796 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4797 {
4798 num_chan_new = 0;
4799 for (i = 0; i < num_channels; i++)
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304800 for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) {
Agrawal Ashish16abf782016-08-18 22:42:59 +05304801 if (wiphy->bands[j] == NULL)
4802 continue;
4803 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4804 if ((chan_list[i] ==
4805 wiphy->bands[j]->channels[k].center_freq) &&
4806 (!(wiphy->bands[j]->channels[k].flags &
4807 IEEE80211_CHAN_INDOOR_ONLY))) {
4808 chan_list[num_chan_new] = chan_list[i];
4809 num_chan_new++;
4810 }
4811 }
4812 }
4813 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304814
Agrawal Ashish16abf782016-08-18 22:42:59 +05304815 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4816 for (i = 0; i < num_chan_new; i++)
4817 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4818 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304819
4820 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304821 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304822 NLMSG_HDRLEN);
4823
4824 if (!replySkb) {
4825 hddLog(VOS_TRACE_LEVEL_ERROR,
4826 FL("valid channels: buffer alloc fail"));
4827 return -EINVAL;
4828 }
4829 if (nla_put_u32(replySkb,
4830 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304831 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304832 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304833 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304834
4835 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4836 kfree_skb(replySkb);
4837 return -EINVAL;
4838 }
4839
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304840 ret = cfg80211_vendor_cmd_reply(replySkb);
4841
4842 EXIT();
4843 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304844}
4845
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304846static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4847 struct wireless_dev *wdev,
4848 const void *data, int dataLen)
4849{
4850 int ret = 0;
4851
4852 vos_ssr_protect(__func__);
4853 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4854 dataLen);
4855 vos_ssr_unprotect(__func__);
4856
4857 return ret;
4858}
4859
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304860static int hdd_extscan_start_fill_bucket_channel_spec(
4861 hdd_context_t *pHddCtx,
4862 tpSirEXTScanStartReqParams pReqMsg,
4863 struct nlattr **tb)
4864{
4865 struct nlattr *bucket[
4866 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4867 struct nlattr *channel[
4868 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4869 struct nlattr *buckets;
4870 struct nlattr *channels;
4871 int rem1, rem2;
4872 eHalStatus status;
4873 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304874 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304875 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4876 tANI_U32 passive_max_chn_time, active_max_chn_time;
4877
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304878 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304879 bktIndex = 0;
4880
4881 nla_for_each_nested(buckets,
4882 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304883 if (bktIndex >= expected_buckets) {
4884 hddLog(LOGW, FL("ignoring excess buckets"));
4885 break;
4886 }
4887
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304888 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304889 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4890 nla_data(buckets), nla_len(buckets),
4891 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304892 hddLog(LOGE, FL("nla_parse failed"));
4893 return -EINVAL;
4894 }
4895
4896 /* Parse and fetch bucket spec */
4897 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4898 hddLog(LOGE, FL("attr bucket index failed"));
4899 return -EINVAL;
4900 }
4901 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4902 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4903 hddLog(LOG1, FL("Bucket spec Index %d"),
4904 pReqMsg->buckets[bktIndex].bucket);
4905
4906 /* Parse and fetch wifi band */
4907 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4908 hddLog(LOGE, FL("attr wifi band failed"));
4909 return -EINVAL;
4910 }
4911 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4912 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4913 hddLog(LOG1, FL("Wifi band %d"),
4914 pReqMsg->buckets[bktIndex].band);
4915
4916 /* Parse and fetch period */
4917 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4918 hddLog(LOGE, FL("attr period failed"));
4919 return -EINVAL;
4920 }
4921 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4922 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4923 hddLog(LOG1, FL("period %d"),
4924 pReqMsg->buckets[bktIndex].period);
4925
4926 /* Parse and fetch report events */
4927 if (!bucket[
4928 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4929 hddLog(LOGE, FL("attr report events failed"));
4930 return -EINVAL;
4931 }
4932 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4933 bucket[
4934 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4935 hddLog(LOG1, FL("report events %d"),
4936 pReqMsg->buckets[bktIndex].reportEvents);
4937
4938 /* Parse and fetch max period */
4939 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4940 hddLog(LOGE, FL("attr max period failed"));
4941 return -EINVAL;
4942 }
4943 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4944 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4945 hddLog(LOG1, FL("max period %u"),
4946 pReqMsg->buckets[bktIndex].max_period);
4947
4948 /* Parse and fetch exponent */
4949 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4950 hddLog(LOGE, FL("attr exponent failed"));
4951 return -EINVAL;
4952 }
4953 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4954 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4955 hddLog(LOG1, FL("exponent %u"),
4956 pReqMsg->buckets[bktIndex].exponent);
4957
4958 /* Parse and fetch step count */
4959 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4960 hddLog(LOGE, FL("attr step count failed"));
4961 return -EINVAL;
4962 }
4963 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4964 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4965 hddLog(LOG1, FL("Step count %u"),
4966 pReqMsg->buckets[bktIndex].step_count);
4967
4968 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4969 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4970
4971 /* Framework shall pass the channel list if the input WiFi band is
4972 * WIFI_BAND_UNSPECIFIED.
4973 * If the input WiFi band is specified (any value other than
4974 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4975 */
4976 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4977 numChannels = 0;
4978 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4979 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4980 pReqMsg->buckets[bktIndex].band,
4981 chanList, &numChannels);
4982 if (!HAL_STATUS_SUCCESS(status)) {
4983 hddLog(LOGE,
4984 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4985 status);
4986 return -EINVAL;
4987 }
4988
4989 pReqMsg->buckets[bktIndex].numChannels =
4990 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4991 hddLog(LOG1, FL("Num channels %d"),
4992 pReqMsg->buckets[bktIndex].numChannels);
4993
4994 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4995 j++) {
4996 pReqMsg->buckets[bktIndex].channels[j].channel =
4997 chanList[j];
4998 pReqMsg->buckets[bktIndex].channels[j].
4999 chnlClass = 0;
5000 if (CSR_IS_CHANNEL_DFS(
5001 vos_freq_to_chan(chanList[j]))) {
5002 pReqMsg->buckets[bktIndex].channels[j].
5003 passive = 1;
5004 pReqMsg->buckets[bktIndex].channels[j].
5005 dwellTimeMs = passive_max_chn_time;
5006 } else {
5007 pReqMsg->buckets[bktIndex].channels[j].
5008 passive = 0;
5009 pReqMsg->buckets[bktIndex].channels[j].
5010 dwellTimeMs = active_max_chn_time;
5011 }
5012
5013 hddLog(LOG1,
5014 "Channel %u Passive %u Dwell time %u ms",
5015 pReqMsg->buckets[bktIndex].channels[j].channel,
5016 pReqMsg->buckets[bktIndex].channels[j].passive,
5017 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5018 }
5019
5020 bktIndex++;
5021 continue;
5022 }
5023
5024 /* Parse and fetch number of channels */
5025 if (!bucket[
5026 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
5027 hddLog(LOGE, FL("attr num channels failed"));
5028 return -EINVAL;
5029 }
5030
5031 pReqMsg->buckets[bktIndex].numChannels =
5032 nla_get_u32(bucket[
5033 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
5034 hddLog(LOG1, FL("num channels %d"),
5035 pReqMsg->buckets[bktIndex].numChannels);
5036
5037 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
5038 hddLog(LOGE, FL("attr channel spec failed"));
5039 return -EINVAL;
5040 }
5041
5042 j = 0;
5043 nla_for_each_nested(channels,
5044 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
5045 if (nla_parse(channel,
5046 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5047 nla_data(channels), nla_len(channels),
5048 wlan_hdd_extscan_config_policy)) {
5049 hddLog(LOGE, FL("nla_parse failed"));
5050 return -EINVAL;
5051 }
5052
5053 /* Parse and fetch channel */
5054 if (!channel[
5055 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
5056 hddLog(LOGE, FL("attr channel failed"));
5057 return -EINVAL;
5058 }
5059 pReqMsg->buckets[bktIndex].channels[j].channel =
5060 nla_get_u32(channel[
5061 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
5062 hddLog(LOG1, FL("channel %u"),
5063 pReqMsg->buckets[bktIndex].channels[j].channel);
5064
5065 /* Parse and fetch dwell time */
5066 if (!channel[
5067 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
5068 hddLog(LOGE, FL("attr dwelltime failed"));
5069 return -EINVAL;
5070 }
5071 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
5072 nla_get_u32(channel[
5073 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
5074
5075 hddLog(LOG1, FL("Dwell time (%u ms)"),
5076 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5077
5078
5079 /* Parse and fetch channel spec passive */
5080 if (!channel[
5081 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
5082 hddLog(LOGE,
5083 FL("attr channel spec passive failed"));
5084 return -EINVAL;
5085 }
5086 pReqMsg->buckets[bktIndex].channels[j].passive =
5087 nla_get_u8(channel[
5088 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
5089 hddLog(LOG1, FL("Chnl spec passive %u"),
5090 pReqMsg->buckets[bktIndex].channels[j].passive);
5091
5092 j++;
5093 }
5094
5095 bktIndex++;
5096 }
5097
5098 return 0;
5099}
5100
5101
5102/*
5103 * define short names for the global vendor params
5104 * used by wlan_hdd_cfg80211_extscan_start()
5105 */
5106#define PARAM_MAX \
5107QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
5108#define PARAM_REQUEST_ID \
5109QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
5110#define PARAM_BASE_PERIOD \
5111QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
5112#define PARAM_MAX_AP_PER_SCAN \
5113QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
5114#define PARAM_RPT_THRHLD_PERCENT \
5115QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
5116#define PARAM_RPT_THRHLD_NUM_SCANS \
5117QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
5118#define PARAM_NUM_BUCKETS \
5119QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
5120
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305121static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305122 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305123 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305124{
Dino Myclee8843b32014-07-04 14:21:45 +05305125 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305126 struct net_device *dev = wdev->netdev;
5127 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5128 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5129 struct nlattr *tb[PARAM_MAX + 1];
5130 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305131 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305132 tANI_U32 request_id;
5133 struct hdd_ext_scan_context *context;
5134 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305135
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305136 ENTER();
5137
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305138 if (VOS_FTM_MODE == hdd_get_conparam()) {
5139 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5140 return -EINVAL;
5141 }
5142
Dino Mycle6fb96c12014-06-10 11:52:40 +05305143 status = wlan_hdd_validate_context(pHddCtx);
5144 if (0 != status)
5145 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305146 return -EINVAL;
5147 }
Dino Myclee8843b32014-07-04 14:21:45 +05305148 /* check the EXTScan Capability */
5149 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305150 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5151 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305152 {
5153 hddLog(VOS_TRACE_LEVEL_ERROR,
5154 FL("EXTScan not enabled/supported by Firmware"));
5155 return -EINVAL;
5156 }
5157
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305158 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305159 data, dataLen,
5160 wlan_hdd_extscan_config_policy)) {
5161 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5162 return -EINVAL;
5163 }
5164
5165 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305166 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305167 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5168 return -EINVAL;
5169 }
5170
Dino Myclee8843b32014-07-04 14:21:45 +05305171 pReqMsg = (tpSirEXTScanStartReqParams)
5172 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305173 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305174 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5175 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305176 }
5177
5178 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305179 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305180 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5181
5182 pReqMsg->sessionId = pAdapter->sessionId;
5183 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5184
5185 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305186 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305187 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5188 goto fail;
5189 }
5190 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305191 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305192 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5193 pReqMsg->basePeriod);
5194
5195 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305196 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305197 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5198 goto fail;
5199 }
5200 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305201 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305202 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5203 pReqMsg->maxAPperScan);
5204
5205 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305206 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305207 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5208 goto fail;
5209 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305210 pReqMsg->reportThresholdPercent = nla_get_u8(
5211 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305212 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305213 pReqMsg->reportThresholdPercent);
5214
5215 /* Parse and fetch report threshold num scans */
5216 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5217 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5218 goto fail;
5219 }
5220 pReqMsg->reportThresholdNumScans = nla_get_u8(
5221 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5222 hddLog(LOG1, FL("Report Threshold num scans %d"),
5223 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305224
5225 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305226 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305227 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5228 goto fail;
5229 }
5230 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305231 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305232 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5233 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5234 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5235 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5236 }
5237 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5238 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305239
Dino Mycle6fb96c12014-06-10 11:52:40 +05305240 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5241 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5242 goto fail;
5243 }
5244
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305245 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305246
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305247 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5248 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305249
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305250 context = &pHddCtx->ext_scan_context;
5251 spin_lock(&hdd_context_lock);
5252 INIT_COMPLETION(context->response_event);
5253 context->request_id = request_id = pReqMsg->requestId;
5254 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305255
Dino Mycle6fb96c12014-06-10 11:52:40 +05305256 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5257 if (!HAL_STATUS_SUCCESS(status)) {
5258 hddLog(VOS_TRACE_LEVEL_ERROR,
5259 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305260 goto fail;
5261 }
5262
Srinivas Dasari91727c12016-03-23 17:59:06 +05305263 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5264
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305265 /* request was sent -- wait for the response */
5266 rc = wait_for_completion_timeout(&context->response_event,
5267 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5268
5269 if (!rc) {
5270 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5271 retval = -ETIMEDOUT;
5272 } else {
5273 spin_lock(&hdd_context_lock);
5274 if (context->request_id == request_id)
5275 retval = context->response_status;
5276 else
5277 retval = -EINVAL;
5278 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305279 }
5280
Dino Myclee8843b32014-07-04 14:21:45 +05305281 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305282 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305283 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305284
5285fail:
5286 vos_mem_free(pReqMsg);
5287 return -EINVAL;
5288}
5289
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305290/*
5291 * done with short names for the global vendor params
5292 * used by wlan_hdd_cfg80211_extscan_start()
5293 */
5294#undef PARAM_MAX
5295#undef PARAM_REQUEST_ID
5296#undef PARAM_BASE_PERIOD
5297#undef PARAMS_MAX_AP_PER_SCAN
5298#undef PARAMS_RPT_THRHLD_PERCENT
5299#undef PARAMS_RPT_THRHLD_NUM_SCANS
5300#undef PARAMS_NUM_BUCKETS
5301
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305302static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5303 struct wireless_dev *wdev,
5304 const void *data, int dataLen)
5305{
5306 int ret = 0;
5307
5308 vos_ssr_protect(__func__);
5309 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5310 vos_ssr_unprotect(__func__);
5311
5312 return ret;
5313}
5314
5315static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305316 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305317 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305318{
Dino Myclee8843b32014-07-04 14:21:45 +05305319 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305320 struct net_device *dev = wdev->netdev;
5321 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5322 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5323 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5324 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305325 int retval;
5326 unsigned long rc;
5327 struct hdd_ext_scan_context *context;
5328 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305329
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305330 ENTER();
5331
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305332 if (VOS_FTM_MODE == hdd_get_conparam()) {
5333 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5334 return -EINVAL;
5335 }
5336
Dino Mycle6fb96c12014-06-10 11:52:40 +05305337 status = wlan_hdd_validate_context(pHddCtx);
5338 if (0 != status)
5339 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305340 return -EINVAL;
5341 }
Dino Myclee8843b32014-07-04 14:21:45 +05305342 /* check the EXTScan Capability */
5343 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305344 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5345 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305346 {
5347 hddLog(VOS_TRACE_LEVEL_ERROR,
5348 FL("EXTScan not enabled/supported by Firmware"));
5349 return -EINVAL;
5350 }
5351
Dino Mycle6fb96c12014-06-10 11:52:40 +05305352 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5353 data, dataLen,
5354 wlan_hdd_extscan_config_policy)) {
5355 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5356 return -EINVAL;
5357 }
5358
5359 /* Parse and fetch request Id */
5360 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5361 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5362 return -EINVAL;
5363 }
5364
Dino Myclee8843b32014-07-04 14:21:45 +05305365 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305366 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305367 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305368
Dino Myclee8843b32014-07-04 14:21:45 +05305369 reqMsg.sessionId = pAdapter->sessionId;
5370 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305371
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305372 context = &pHddCtx->ext_scan_context;
5373 spin_lock(&hdd_context_lock);
5374 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305375 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305376 spin_unlock(&hdd_context_lock);
5377
Dino Myclee8843b32014-07-04 14:21:45 +05305378 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305379 if (!HAL_STATUS_SUCCESS(status)) {
5380 hddLog(VOS_TRACE_LEVEL_ERROR,
5381 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305382 return -EINVAL;
5383 }
5384
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305385 /* request was sent -- wait for the response */
5386 rc = wait_for_completion_timeout(&context->response_event,
5387 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5388
5389 if (!rc) {
5390 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5391 retval = -ETIMEDOUT;
5392 } else {
5393 spin_lock(&hdd_context_lock);
5394 if (context->request_id == request_id)
5395 retval = context->response_status;
5396 else
5397 retval = -EINVAL;
5398 spin_unlock(&hdd_context_lock);
5399 }
5400
5401 return retval;
5402
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305403 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305404 return 0;
5405}
5406
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305407static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5408 struct wireless_dev *wdev,
5409 const void *data, int dataLen)
5410{
5411 int ret = 0;
5412
5413 vos_ssr_protect(__func__);
5414 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5415 vos_ssr_unprotect(__func__);
5416
5417 return ret;
5418}
5419
5420static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305421 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305422 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305423{
Dino Myclee8843b32014-07-04 14:21:45 +05305424 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305425 struct net_device *dev = wdev->netdev;
5426 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5427 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5428 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5429 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305430 struct hdd_ext_scan_context *context;
5431 tANI_U32 request_id;
5432 unsigned long rc;
5433 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305434
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305435 ENTER();
5436
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305437 if (VOS_FTM_MODE == hdd_get_conparam()) {
5438 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5439 return -EINVAL;
5440 }
5441
Dino Mycle6fb96c12014-06-10 11:52:40 +05305442 status = wlan_hdd_validate_context(pHddCtx);
5443 if (0 != status)
5444 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305445 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305446 return -EINVAL;
5447 }
Dino Myclee8843b32014-07-04 14:21:45 +05305448 /* check the EXTScan Capability */
5449 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305450 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5451 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305452 {
5453 hddLog(VOS_TRACE_LEVEL_ERROR,
5454 FL("EXTScan not enabled/supported by Firmware"));
5455 return -EINVAL;
5456 }
5457
Dino Mycle6fb96c12014-06-10 11:52:40 +05305458 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5459 data, dataLen,
5460 wlan_hdd_extscan_config_policy)) {
5461 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5462 return -EINVAL;
5463 }
5464
5465 /* Parse and fetch request Id */
5466 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5467 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5468 return -EINVAL;
5469 }
5470
Dino Myclee8843b32014-07-04 14:21:45 +05305471 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305472 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305473 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305474
Dino Myclee8843b32014-07-04 14:21:45 +05305475 reqMsg.sessionId = pAdapter->sessionId;
5476 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305477
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305478 context = &pHddCtx->ext_scan_context;
5479 spin_lock(&hdd_context_lock);
5480 INIT_COMPLETION(context->response_event);
5481 context->request_id = request_id = reqMsg.requestId;
5482 spin_unlock(&hdd_context_lock);
5483
Dino Myclee8843b32014-07-04 14:21:45 +05305484 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305485 if (!HAL_STATUS_SUCCESS(status)) {
5486 hddLog(VOS_TRACE_LEVEL_ERROR,
5487 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305488 return -EINVAL;
5489 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305490
5491 /* request was sent -- wait for the response */
5492 rc = wait_for_completion_timeout(&context->response_event,
5493 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5494 if (!rc) {
5495 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5496 retval = -ETIMEDOUT;
5497 } else {
5498 spin_lock(&hdd_context_lock);
5499 if (context->request_id == request_id)
5500 retval = context->response_status;
5501 else
5502 retval = -EINVAL;
5503 spin_unlock(&hdd_context_lock);
5504 }
5505
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305506 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305507 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305508}
5509
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305510static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5511 struct wireless_dev *wdev,
5512 const void *data, int dataLen)
5513{
5514 int ret = 0;
5515
5516 vos_ssr_protect(__func__);
5517 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5518 vos_ssr_unprotect(__func__);
5519
5520 return ret;
5521}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305522#endif /* WLAN_FEATURE_EXTSCAN */
5523
Atul Mittal115287b2014-07-08 13:26:33 +05305524/*EXT TDLS*/
5525static const struct nla_policy
5526wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5527{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305528 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5529 .type = NLA_UNSPEC,
5530 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305531 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5532 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5533 {.type = NLA_S32 },
5534 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5535 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5536
5537};
5538
5539static const struct nla_policy
5540wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5541{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305542 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5543 .type = NLA_UNSPEC,
5544 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305545
5546};
5547
5548static const struct nla_policy
5549wlan_hdd_tdls_config_state_change_policy[
5550 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5551{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305552 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5553 .type = NLA_UNSPEC,
5554 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305555 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5556 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305557 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5558 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5559 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305560
5561};
5562
5563static const struct nla_policy
5564wlan_hdd_tdls_config_get_status_policy[
5565 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5566{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305567 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5568 .type = NLA_UNSPEC,
5569 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305570 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5571 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305572 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5573 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5574 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305575
5576};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305577
5578static const struct nla_policy
5579wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5580{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305581 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5582 .type = NLA_UNSPEC,
5583 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305584};
5585
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305586static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305587 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305588 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305589 int data_len)
5590{
5591
5592 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5593 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5594
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305595 ENTER();
5596
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305597 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305598 return -EINVAL;
5599 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305600 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305601 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305602 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305603 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305604 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305605 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305606 return -ENOTSUPP;
5607 }
5608
5609 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5610 data, data_len, wlan_hdd_mac_config)) {
5611 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5612 return -EINVAL;
5613 }
5614
5615 /* Parse and fetch mac address */
5616 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5618 return -EINVAL;
5619 }
5620
5621 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5622 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5623 VOS_MAC_ADDR_LAST_3_BYTES);
5624
Siddharth Bhal76972212014-10-15 16:22:51 +05305625 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5626
5627 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305628 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5629 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305630 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5631 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5632 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5633 {
5634 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5635 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5636 VOS_MAC_ADDRESS_LEN);
5637 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305638 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305639
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305640 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5641 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305642
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305643 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305644 return 0;
5645}
5646
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305647static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5648 struct wireless_dev *wdev,
5649 const void *data,
5650 int data_len)
5651{
5652 int ret = 0;
5653
5654 vos_ssr_protect(__func__);
5655 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5656 vos_ssr_unprotect(__func__);
5657
5658 return ret;
5659}
5660
5661static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305662 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305663 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305664 int data_len)
5665{
5666 u8 peer[6] = {0};
5667 struct net_device *dev = wdev->netdev;
5668 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5669 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5670 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5671 eHalStatus ret;
5672 tANI_S32 state;
5673 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305674 tANI_S32 global_operating_class = 0;
5675 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305676 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305677 int retVal;
5678
5679 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305680
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305681 if (!pAdapter) {
5682 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5683 return -EINVAL;
5684 }
5685
Atul Mittal115287b2014-07-08 13:26:33 +05305686 ret = wlan_hdd_validate_context(pHddCtx);
5687 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305688 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305689 return -EINVAL;
5690 }
5691 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305692 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305693 return -ENOTSUPP;
5694 }
5695 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5696 data, data_len,
5697 wlan_hdd_tdls_config_get_status_policy)) {
5698 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5699 return -EINVAL;
5700 }
5701
5702 /* Parse and fetch mac address */
5703 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5704 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5705 return -EINVAL;
5706 }
5707
5708 memcpy(peer, nla_data(
5709 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5710 sizeof(peer));
5711 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5712
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305713 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305714
Atul Mittal115287b2014-07-08 13:26:33 +05305715 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305716 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305717 NLMSG_HDRLEN);
5718
5719 if (!skb) {
5720 hddLog(VOS_TRACE_LEVEL_ERROR,
5721 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5722 return -EINVAL;
5723 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305724 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05305725 reason,
5726 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305727 global_operating_class,
5728 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305729 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305730 if (nla_put_s32(skb,
5731 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5732 state) ||
5733 nla_put_s32(skb,
5734 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5735 reason) ||
5736 nla_put_s32(skb,
5737 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5738 global_operating_class) ||
5739 nla_put_s32(skb,
5740 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5741 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305742
5743 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5744 goto nla_put_failure;
5745 }
5746
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305747 retVal = cfg80211_vendor_cmd_reply(skb);
5748 EXIT();
5749 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305750
5751nla_put_failure:
5752 kfree_skb(skb);
5753 return -EINVAL;
5754}
5755
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305756static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5757 struct wireless_dev *wdev,
5758 const void *data,
5759 int data_len)
5760{
5761 int ret = 0;
5762
5763 vos_ssr_protect(__func__);
5764 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5765 vos_ssr_unprotect(__func__);
5766
5767 return ret;
5768}
5769
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305770static int wlan_hdd_cfg80211_exttdls_callback(
5771#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5772 const tANI_U8* mac,
5773#else
5774 tANI_U8* mac,
5775#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305776 tANI_S32 state,
5777 tANI_S32 reason,
5778 void *ctx)
5779{
5780 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305781 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305782 tANI_S32 global_operating_class = 0;
5783 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305784 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305785
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305786 ENTER();
5787
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305788 if (!pAdapter) {
5789 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5790 return -EINVAL;
5791 }
5792
5793 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305794 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305795 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305796 return -EINVAL;
5797 }
5798
5799 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305801 return -ENOTSUPP;
5802 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305803 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5804#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5805 NULL,
5806#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305807 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5808 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5809 GFP_KERNEL);
5810
5811 if (!skb) {
5812 hddLog(VOS_TRACE_LEVEL_ERROR,
5813 FL("cfg80211_vendor_event_alloc failed"));
5814 return -EINVAL;
5815 }
5816 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305817 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5818 reason,
5819 state,
5820 global_operating_class,
5821 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305822 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5823 MAC_ADDR_ARRAY(mac));
5824
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305825 if (nla_put(skb,
5826 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5827 VOS_MAC_ADDR_SIZE, mac) ||
5828 nla_put_s32(skb,
5829 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5830 state) ||
5831 nla_put_s32(skb,
5832 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5833 reason) ||
5834 nla_put_s32(skb,
5835 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5836 channel) ||
5837 nla_put_s32(skb,
5838 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5839 global_operating_class)
5840 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305841 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5842 goto nla_put_failure;
5843 }
5844
5845 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305846 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305847 return (0);
5848
5849nla_put_failure:
5850 kfree_skb(skb);
5851 return -EINVAL;
5852}
5853
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305854static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305855 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305856 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305857 int data_len)
5858{
5859 u8 peer[6] = {0};
5860 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305861 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5862 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5863 eHalStatus status;
5864 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305865 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305866 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305867
5868 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305869
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305870 if (!dev) {
5871 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5872 return -EINVAL;
5873 }
5874
5875 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5876 if (!pAdapter) {
5877 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5878 return -EINVAL;
5879 }
5880
Atul Mittal115287b2014-07-08 13:26:33 +05305881 status = wlan_hdd_validate_context(pHddCtx);
5882 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305884 return -EINVAL;
5885 }
5886 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305888 return -ENOTSUPP;
5889 }
5890 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5891 data, data_len,
5892 wlan_hdd_tdls_config_enable_policy)) {
5893 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5894 return -EINVAL;
5895 }
5896
5897 /* Parse and fetch mac address */
5898 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5899 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5900 return -EINVAL;
5901 }
5902
5903 memcpy(peer, nla_data(
5904 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5905 sizeof(peer));
5906 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5907
5908 /* Parse and fetch channel */
5909 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5910 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5911 return -EINVAL;
5912 }
5913 pReqMsg.channel = nla_get_s32(
5914 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5915 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5916
5917 /* Parse and fetch global operating class */
5918 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5919 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5920 return -EINVAL;
5921 }
5922 pReqMsg.global_operating_class = nla_get_s32(
5923 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5924 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5925 pReqMsg.global_operating_class);
5926
5927 /* Parse and fetch latency ms */
5928 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5929 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5930 return -EINVAL;
5931 }
5932 pReqMsg.max_latency_ms = nla_get_s32(
5933 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5934 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5935 pReqMsg.max_latency_ms);
5936
5937 /* Parse and fetch required bandwidth kbps */
5938 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5939 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5940 return -EINVAL;
5941 }
5942
5943 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5944 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5945 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5946 pReqMsg.min_bandwidth_kbps);
5947
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305948 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305949 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305950 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305951 wlan_hdd_cfg80211_exttdls_callback);
5952
5953 EXIT();
5954 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305955}
5956
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305957static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5958 struct wireless_dev *wdev,
5959 const void *data,
5960 int data_len)
5961{
5962 int ret = 0;
5963
5964 vos_ssr_protect(__func__);
5965 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5966 vos_ssr_unprotect(__func__);
5967
5968 return ret;
5969}
5970
5971static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305972 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305973 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305974 int data_len)
5975{
5976 u8 peer[6] = {0};
5977 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305978 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5979 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5980 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305981 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305982 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305983
5984 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305985
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305986 if (!dev) {
5987 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5988 return -EINVAL;
5989 }
5990
5991 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5992 if (!pAdapter) {
5993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5994 return -EINVAL;
5995 }
5996
Atul Mittal115287b2014-07-08 13:26:33 +05305997 status = wlan_hdd_validate_context(pHddCtx);
5998 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305999 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05306000 return -EINVAL;
6001 }
6002 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05306003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05306004 return -ENOTSUPP;
6005 }
6006 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
6007 data, data_len,
6008 wlan_hdd_tdls_config_disable_policy)) {
6009 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6010 return -EINVAL;
6011 }
6012 /* Parse and fetch mac address */
6013 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
6014 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
6015 return -EINVAL;
6016 }
6017
6018 memcpy(peer, nla_data(
6019 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
6020 sizeof(peer));
6021 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
6022
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306023 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
6024
6025 EXIT();
6026 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05306027}
6028
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306029static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
6030 struct wireless_dev *wdev,
6031 const void *data,
6032 int data_len)
6033{
6034 int ret = 0;
6035
6036 vos_ssr_protect(__func__);
6037 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
6038 vos_ssr_unprotect(__func__);
6039
6040 return ret;
6041}
6042
Dasari Srinivas7875a302014-09-26 17:50:57 +05306043static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306044__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05306045 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306046 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05306047{
6048 struct net_device *dev = wdev->netdev;
6049 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6050 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6051 struct sk_buff *skb = NULL;
6052 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306053 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306054
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306055 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306056
6057 ret = wlan_hdd_validate_context(pHddCtx);
6058 if (0 != ret)
6059 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306060 return ret;
6061 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306062 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
6063 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
6064 fset |= WIFI_FEATURE_INFRA;
6065 }
6066
6067 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
6068 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
6069 fset |= WIFI_FEATURE_INFRA_5G;
6070 }
6071
6072#ifdef WLAN_FEATURE_P2P
6073 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
6074 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
6075 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
6076 fset |= WIFI_FEATURE_P2P;
6077 }
6078#endif
6079
6080 /* Soft-AP is supported currently by default */
6081 fset |= WIFI_FEATURE_SOFT_AP;
6082
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05306083 /* HOTSPOT is a supplicant feature, enable it by default */
6084 fset |= WIFI_FEATURE_HOTSPOT;
6085
Dasari Srinivas7875a302014-09-26 17:50:57 +05306086#ifdef WLAN_FEATURE_EXTSCAN
6087 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05306088 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
6089 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
6090 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306091 fset |= WIFI_FEATURE_EXTSCAN;
6092 }
6093#endif
6094
Dasari Srinivas7875a302014-09-26 17:50:57 +05306095 if (sme_IsFeatureSupportedByFW(NAN)) {
6096 hddLog(LOG1, FL("NAN is supported by firmware"));
6097 fset |= WIFI_FEATURE_NAN;
6098 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306099
6100 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05306101 if (sme_IsFeatureSupportedByFW(RTT) &&
6102 pHddCtx->cfg_ini->enable_rtt_support) {
6103 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306104 fset |= WIFI_FEATURE_D2AP_RTT;
6105 }
6106
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05306107 if (sme_IsFeatureSupportedByFW(RTT3)) {
6108 hddLog(LOG1, FL("RTT3 is supported by firmware"));
6109 fset |= WIFI_FEATURE_RTT3;
6110 }
6111
Dasari Srinivas7875a302014-09-26 17:50:57 +05306112#ifdef FEATURE_WLAN_BATCH_SCAN
6113 if (fset & WIFI_FEATURE_EXTSCAN) {
6114 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
6115 fset &= ~WIFI_FEATURE_BATCH_SCAN;
6116 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
6117 hddLog(LOG1, FL("Batch scan is supported by firmware"));
6118 fset |= WIFI_FEATURE_BATCH_SCAN;
6119 }
6120#endif
6121
6122#ifdef FEATURE_WLAN_SCAN_PNO
6123 if (pHddCtx->cfg_ini->configPNOScanSupport &&
6124 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
6125 hddLog(LOG1, FL("PNO is supported by firmware"));
6126 fset |= WIFI_FEATURE_PNO;
6127 }
6128#endif
6129
6130 /* STA+STA is supported currently by default */
6131 fset |= WIFI_FEATURE_ADDITIONAL_STA;
6132
6133#ifdef FEATURE_WLAN_TDLS
6134 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6135 sme_IsFeatureSupportedByFW(TDLS)) {
6136 hddLog(LOG1, FL("TDLS is supported by firmware"));
6137 fset |= WIFI_FEATURE_TDLS;
6138 }
6139
6140 /* TDLS_OFFCHANNEL is not supported currently by default */
6141#endif
6142
6143#ifdef WLAN_AP_STA_CONCURRENCY
6144 /* AP+STA concurrency is supported currently by default */
6145 fset |= WIFI_FEATURE_AP_STA;
6146#endif
6147
Mukul Sharma5add0532015-08-17 15:57:47 +05306148#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306149 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6150 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306151 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6152 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306153 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306154#endif
6155
Dasari Srinivas7875a302014-09-26 17:50:57 +05306156 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6157 NLMSG_HDRLEN);
6158
6159 if (!skb) {
6160 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6161 return -EINVAL;
6162 }
6163 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6164
6165 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6166 hddLog(LOGE, FL("nla put fail"));
6167 goto nla_put_failure;
6168 }
6169
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306170 ret = cfg80211_vendor_cmd_reply(skb);
6171 EXIT();
6172 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306173
6174nla_put_failure:
6175 kfree_skb(skb);
6176 return -EINVAL;
6177}
6178
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306179static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306180wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6181 struct wireless_dev *wdev,
6182 const void *data, int data_len)
6183{
6184 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306185 vos_ssr_protect(__func__);
6186 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6187 vos_ssr_unprotect(__func__);
6188
6189 return ret;
6190}
6191
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306192
6193static const struct
6194nla_policy
6195qca_wlan_vendor_wifi_logger_get_ring_data_policy
6196[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6197 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6198 = {.type = NLA_U32 },
6199};
6200
6201static int
6202 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6203 struct wireless_dev *wdev,
6204 const void *data,
6205 int data_len)
6206{
6207 int ret;
6208 VOS_STATUS status;
6209 uint32_t ring_id;
6210 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6211 struct nlattr *tb
6212 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6213
6214 ENTER();
6215
6216 ret = wlan_hdd_validate_context(hdd_ctx);
6217 if (0 != ret) {
6218 return ret;
6219 }
6220
6221 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6222 data, data_len,
6223 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6224 hddLog(LOGE, FL("Invalid attribute"));
6225 return -EINVAL;
6226 }
6227
6228 /* Parse and fetch ring id */
6229 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6230 hddLog(LOGE, FL("attr ATTR failed"));
6231 return -EINVAL;
6232 }
6233
6234 ring_id = nla_get_u32(
6235 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6236
6237 hddLog(LOG1, FL("Bug report triggered by framework"));
6238
6239 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6240 WLAN_LOG_INDICATOR_FRAMEWORK,
6241 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306242 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306243 );
6244 if (VOS_STATUS_SUCCESS != status) {
6245 hddLog(LOGE, FL("Failed to trigger bug report"));
6246
6247 return -EINVAL;
6248 }
6249
6250 return 0;
6251
6252
6253}
6254
6255
6256static int
6257 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6258 struct wireless_dev *wdev,
6259 const void *data,
6260 int data_len)
6261{
6262 int ret = 0;
6263
6264 vos_ssr_protect(__func__);
6265 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6266 wdev, data, data_len);
6267 vos_ssr_unprotect(__func__);
6268
6269 return ret;
6270
6271}
6272
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306273#define MAX_CONCURRENT_MATRIX \
6274 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6275#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6276 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6277static const struct nla_policy
6278wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6279 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6280};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306281
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306282static int
6283__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306284 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306285 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306286{
6287 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6288 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306289 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306290 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306291 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6292 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306293
6294 ENTER();
6295
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306296 ret = wlan_hdd_validate_context(pHddCtx);
6297 if (0 != ret)
6298 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306299 return ret;
6300 }
6301
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306302 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6303 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306304 hddLog(LOGE, FL("Invalid ATTR"));
6305 return -EINVAL;
6306 }
6307
6308 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306309 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306310 hddLog(LOGE, FL("Attr max feature set size failed"));
6311 return -EINVAL;
6312 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306313 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306314 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6315
6316 /* Fill feature combination matrix */
6317 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306318 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6319 WIFI_FEATURE_P2P;
6320
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306321 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6322 WIFI_FEATURE_SOFT_AP;
6323
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306324 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6325 WIFI_FEATURE_SOFT_AP;
6326
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306327 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6328 WIFI_FEATURE_SOFT_AP |
6329 WIFI_FEATURE_P2P;
6330
6331 /* Add more feature combinations here */
6332
6333 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6334 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6335 hddLog(LOG1, "Feature set matrix");
6336 for (i = 0; i < feature_sets; i++)
6337 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6338
6339 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6340 sizeof(u32) * feature_sets +
6341 NLMSG_HDRLEN);
6342
6343 if (reply_skb) {
6344 if (nla_put_u32(reply_skb,
6345 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6346 feature_sets) ||
6347 nla_put(reply_skb,
6348 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6349 sizeof(u32) * feature_sets, feature_set_matrix)) {
6350 hddLog(LOGE, FL("nla put fail"));
6351 kfree_skb(reply_skb);
6352 return -EINVAL;
6353 }
6354
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306355 ret = cfg80211_vendor_cmd_reply(reply_skb);
6356 EXIT();
6357 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306358 }
6359 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6360 return -ENOMEM;
6361
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306362}
6363
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306364#undef MAX_CONCURRENT_MATRIX
6365#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6366
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306367static int
6368wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6369 struct wireless_dev *wdev,
6370 const void *data, int data_len)
6371{
6372 int ret = 0;
6373
6374 vos_ssr_protect(__func__);
6375 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6376 data_len);
6377 vos_ssr_unprotect(__func__);
6378
6379 return ret;
6380}
6381
c_manjeecfd1efb2015-09-25 19:32:34 +05306382
6383static int
6384__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6385 struct wireless_dev *wdev,
6386 const void *data, int data_len)
6387{
6388 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6389 int ret;
6390 ENTER();
6391
6392 ret = wlan_hdd_validate_context(pHddCtx);
6393 if (0 != ret)
6394 {
6395 return ret;
6396 }
6397
6398 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6399 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6400 {
6401 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306402 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306403 }
6404 /*call common API for FW mem dump req*/
6405 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6406
Abhishek Singhc783fa72015-12-09 18:07:34 +05306407 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306408 {
6409 /*indicate to userspace the status of fw mem dump */
6410 wlan_indicate_mem_dump_complete(true);
6411 }
6412 else
6413 {
6414 /*else send failure to userspace */
6415 wlan_indicate_mem_dump_complete(false);
6416 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306417 EXIT();
6418 return ret;
6419}
6420
6421/**
6422 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6423 * @wiphy: pointer to wireless wiphy structure.
6424 * @wdev: pointer to wireless_dev structure.
6425 * @data: Pointer to the NL data.
6426 * @data_len:Length of @data
6427 *
6428 * This is called when wlan driver needs to get the firmware memory dump
6429 * via vendor specific command.
6430 *
6431 * Return: 0 on success, error number otherwise.
6432 */
6433
6434static int
6435wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6436 struct wireless_dev *wdev,
6437 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306438{
6439 int ret = 0;
6440 vos_ssr_protect(__func__);
6441 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6442 data_len);
6443 vos_ssr_unprotect(__func__);
6444 return ret;
6445}
c_manjeecfd1efb2015-09-25 19:32:34 +05306446
Sushant Kaushik8e644982015-09-23 12:18:54 +05306447static const struct
6448nla_policy
6449qca_wlan_vendor_wifi_logger_start_policy
6450[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6451 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6452 = {.type = NLA_U32 },
6453 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6454 = {.type = NLA_U32 },
6455 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6456 = {.type = NLA_U32 },
6457};
6458
6459/**
6460 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6461 * or disable the collection of packet statistics from the firmware
6462 * @wiphy: WIPHY structure pointer
6463 * @wdev: Wireless device structure pointer
6464 * @data: Pointer to the data received
6465 * @data_len: Length of the data received
6466 *
6467 * This function is used to enable or disable the collection of packet
6468 * statistics from the firmware
6469 *
6470 * Return: 0 on success and errno on failure
6471 */
6472static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6473 struct wireless_dev *wdev,
6474 const void *data,
6475 int data_len)
6476{
6477 eHalStatus status;
6478 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6479 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6480 tAniWifiStartLog start_log;
6481
6482 status = wlan_hdd_validate_context(hdd_ctx);
6483 if (0 != status) {
6484 return -EINVAL;
6485 }
6486
6487 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6488 data, data_len,
6489 qca_wlan_vendor_wifi_logger_start_policy)) {
6490 hddLog(LOGE, FL("Invalid attribute"));
6491 return -EINVAL;
6492 }
6493
6494 /* Parse and fetch ring id */
6495 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6496 hddLog(LOGE, FL("attr ATTR failed"));
6497 return -EINVAL;
6498 }
6499 start_log.ringId = nla_get_u32(
6500 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6501 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6502
6503 /* Parse and fetch verbose level */
6504 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6505 hddLog(LOGE, FL("attr verbose_level failed"));
6506 return -EINVAL;
6507 }
6508 start_log.verboseLevel = nla_get_u32(
6509 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6510 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6511
6512 /* Parse and fetch flag */
6513 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6514 hddLog(LOGE, FL("attr flag failed"));
6515 return -EINVAL;
6516 }
6517 start_log.flag = nla_get_u32(
6518 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6519 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6520
6521 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306522 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6523 !vos_isPktStatsEnabled()))
6524
Sushant Kaushik8e644982015-09-23 12:18:54 +05306525 {
6526 hddLog(LOGE, FL("per pkt stats not enabled"));
6527 return -EINVAL;
6528 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306529
Sushant Kaushik33200572015-08-05 16:46:20 +05306530 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306531 return 0;
6532}
6533
6534/**
6535 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6536 * or disable the collection of packet statistics from the firmware
6537 * @wiphy: WIPHY structure pointer
6538 * @wdev: Wireless device structure pointer
6539 * @data: Pointer to the data received
6540 * @data_len: Length of the data received
6541 *
6542 * This function is used to enable or disable the collection of packet
6543 * statistics from the firmware
6544 *
6545 * Return: 0 on success and errno on failure
6546 */
6547static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6548 struct wireless_dev *wdev,
6549 const void *data,
6550 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306551{
6552 int ret = 0;
6553
6554 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306555
6556 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6557 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306558 vos_ssr_unprotect(__func__);
6559
6560 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306561}
6562
6563
Agarwal Ashish738843c2014-09-25 12:27:56 +05306564static const struct nla_policy
6565wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6566 +1] =
6567{
6568 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6569};
6570
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306571static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306572 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306573 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306574 int data_len)
6575{
6576 struct net_device *dev = wdev->netdev;
6577 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6578 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6579 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6580 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6581 eHalStatus status;
6582 u32 dfsFlag = 0;
6583
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306584 ENTER();
6585
Agarwal Ashish738843c2014-09-25 12:27:56 +05306586 status = wlan_hdd_validate_context(pHddCtx);
6587 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306588 return -EINVAL;
6589 }
6590 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6591 data, data_len,
6592 wlan_hdd_set_no_dfs_flag_config_policy)) {
6593 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6594 return -EINVAL;
6595 }
6596
6597 /* Parse and fetch required bandwidth kbps */
6598 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6599 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6600 return -EINVAL;
6601 }
6602
6603 dfsFlag = nla_get_u32(
6604 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6605 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6606 dfsFlag);
6607
6608 pHddCtx->disable_dfs_flag = dfsFlag;
6609
6610 sme_disable_dfs_channel(hHal, dfsFlag);
6611 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306612
6613 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306614 return 0;
6615}
Atul Mittal115287b2014-07-08 13:26:33 +05306616
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306617static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6618 struct wireless_dev *wdev,
6619 const void *data,
6620 int data_len)
6621{
6622 int ret = 0;
6623
6624 vos_ssr_protect(__func__);
6625 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6626 vos_ssr_unprotect(__func__);
6627
6628 return ret;
6629
6630}
6631
Mukul Sharma2a271632014-10-13 14:59:01 +05306632const struct
6633nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6634{
6635 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306636 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6637 .type = NLA_UNSPEC,
6638 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306639};
6640
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306641static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306642 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306643{
6644
6645 u8 bssid[6] = {0};
6646 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6647 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6648 eHalStatus status = eHAL_STATUS_SUCCESS;
6649 v_U32_t isFwrRoamEnabled = FALSE;
6650 int ret;
6651
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306652 ENTER();
6653
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306654 ret = wlan_hdd_validate_context(pHddCtx);
6655 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306656 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306657 }
6658
6659 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6660 data, data_len,
6661 qca_wlan_vendor_attr);
6662 if (ret){
6663 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6664 return -EINVAL;
6665 }
6666
6667 /* Parse and fetch Enable flag */
6668 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6669 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6670 return -EINVAL;
6671 }
6672
6673 isFwrRoamEnabled = nla_get_u32(
6674 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6675
6676 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6677
6678 /* Parse and fetch bssid */
6679 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6680 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6681 return -EINVAL;
6682 }
6683
6684 memcpy(bssid, nla_data(
6685 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6686 sizeof(bssid));
6687 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6688
6689 //Update roaming
6690 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306691 if (!HAL_STATUS_SUCCESS(status)) {
6692 hddLog(LOGE,
6693 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6694 return -EINVAL;
6695 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306696 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306697 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306698}
6699
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306700static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6701 struct wireless_dev *wdev, const void *data, int data_len)
6702{
6703 int ret = 0;
6704
6705 vos_ssr_protect(__func__);
6706 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6707 vos_ssr_unprotect(__func__);
6708
6709 return ret;
6710}
6711
Sushant Kaushik847890c2015-09-28 16:05:17 +05306712static const struct
6713nla_policy
6714qca_wlan_vendor_get_wifi_info_policy[
6715 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6716 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6717 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6718};
6719
6720
6721/**
6722 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6723 * @wiphy: pointer to wireless wiphy structure.
6724 * @wdev: pointer to wireless_dev structure.
6725 * @data: Pointer to the data to be passed via vendor interface
6726 * @data_len:Length of the data to be passed
6727 *
6728 * This is called when wlan driver needs to send wifi driver related info
6729 * (driver/fw version) to the user space application upon request.
6730 *
6731 * Return: Return the Success or Failure code.
6732 */
6733static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6734 struct wireless_dev *wdev,
6735 const void *data, int data_len)
6736{
6737 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6738 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6739 tSirVersionString version;
6740 uint32 version_len;
6741 uint8 attr;
6742 int status;
6743 struct sk_buff *reply_skb = NULL;
6744
6745 if (VOS_FTM_MODE == hdd_get_conparam()) {
6746 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6747 return -EINVAL;
6748 }
6749
6750 status = wlan_hdd_validate_context(hdd_ctx);
6751 if (0 != status) {
6752 hddLog(LOGE, FL("HDD context is not valid"));
6753 return -EINVAL;
6754 }
6755
6756 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6757 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6758 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6759 return -EINVAL;
6760 }
6761
6762 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6763 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6764 QWLAN_VERSIONSTR);
6765 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6766 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6767 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6768 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6769 hdd_ctx->fw_Version);
6770 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6771 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6772 } else {
6773 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6774 return -EINVAL;
6775 }
6776
6777 version_len = strlen(version);
6778 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6779 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6780 if (!reply_skb) {
6781 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6782 return -ENOMEM;
6783 }
6784
6785 if (nla_put(reply_skb, attr, version_len, version)) {
6786 hddLog(LOGE, FL("nla put fail"));
6787 kfree_skb(reply_skb);
6788 return -EINVAL;
6789 }
6790
6791 return cfg80211_vendor_cmd_reply(reply_skb);
6792}
6793
6794/**
6795 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6796 * @wiphy: pointer to wireless wiphy structure.
6797 * @wdev: pointer to wireless_dev structure.
6798 * @data: Pointer to the data to be passed via vendor interface
6799 * @data_len:Length of the data to be passed
6800 * @data_len: Length of the data received
6801 *
6802 * This function is used to enable or disable the collection of packet
6803 * statistics from the firmware
6804 *
6805 * Return: 0 on success and errno on failure
6806 */
6807
6808static int
6809wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6810 struct wireless_dev *wdev,
6811 const void *data, int data_len)
6812
6813
6814{
6815 int ret = 0;
6816
6817 vos_ssr_protect(__func__);
6818 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6819 wdev, data, data_len);
6820 vos_ssr_unprotect(__func__);
6821
6822 return ret;
6823}
6824
6825
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306826/*
6827 * define short names for the global vendor params
6828 * used by __wlan_hdd_cfg80211_monitor_rssi()
6829 */
6830#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6831#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6832#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6833#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6834#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6835
6836/**---------------------------------------------------------------------------
6837
6838 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6839 monitor start is completed successfully.
6840
6841 \return - None
6842
6843 --------------------------------------------------------------------------*/
6844void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6845{
6846 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6847
6848 if (NULL == pHddCtx)
6849 {
6850 hddLog(VOS_TRACE_LEVEL_ERROR,
6851 "%s: HDD context is NULL",__func__);
6852 return;
6853 }
6854
6855 if (VOS_STATUS_SUCCESS == status)
6856 {
6857 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6858 }
6859 else
6860 {
6861 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6862 }
6863
6864 return;
6865}
6866
6867/**---------------------------------------------------------------------------
6868
6869 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6870 stop is completed successfully.
6871
6872 \return - None
6873
6874 --------------------------------------------------------------------------*/
6875void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6876{
6877 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6878
6879 if (NULL == pHddCtx)
6880 {
6881 hddLog(VOS_TRACE_LEVEL_ERROR,
6882 "%s: HDD context is NULL",__func__);
6883 return;
6884 }
6885
6886 if (VOS_STATUS_SUCCESS == status)
6887 {
6888 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6889 }
6890 else
6891 {
6892 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6893 }
6894
6895 return;
6896}
6897
6898/**
6899 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6900 * @wiphy: Pointer to wireless phy
6901 * @wdev: Pointer to wireless device
6902 * @data: Pointer to data
6903 * @data_len: Data length
6904 *
6905 * Return: 0 on success, negative errno on failure
6906 */
6907
6908static int
6909__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6910 struct wireless_dev *wdev,
6911 const void *data,
6912 int data_len)
6913{
6914 struct net_device *dev = wdev->netdev;
6915 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6916 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6917 hdd_station_ctx_t *pHddStaCtx;
6918 struct nlattr *tb[PARAM_MAX + 1];
6919 tpSirRssiMonitorReq pReq;
6920 eHalStatus status;
6921 int ret;
6922 uint32_t control;
6923 static const struct nla_policy policy[PARAM_MAX + 1] = {
6924 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6925 [PARAM_CONTROL] = { .type = NLA_U32 },
6926 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6927 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6928 };
6929
6930 ENTER();
6931
6932 ret = wlan_hdd_validate_context(hdd_ctx);
6933 if (0 != ret) {
6934 return -EINVAL;
6935 }
6936
6937 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6938 hddLog(LOGE, FL("Not in Connected state!"));
6939 return -ENOTSUPP;
6940 }
6941
6942 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6943 hddLog(LOGE, FL("Invalid ATTR"));
6944 return -EINVAL;
6945 }
6946
6947 if (!tb[PARAM_REQUEST_ID]) {
6948 hddLog(LOGE, FL("attr request id failed"));
6949 return -EINVAL;
6950 }
6951
6952 if (!tb[PARAM_CONTROL]) {
6953 hddLog(LOGE, FL("attr control failed"));
6954 return -EINVAL;
6955 }
6956
6957 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6958
6959 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6960 if(NULL == pReq)
6961 {
6962 hddLog(LOGE,
6963 FL("vos_mem_alloc failed "));
6964 return eHAL_STATUS_FAILED_ALLOC;
6965 }
6966 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6967
6968 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6969 pReq->sessionId = pAdapter->sessionId;
6970 pReq->rssiMonitorCbContext = hdd_ctx;
6971 control = nla_get_u32(tb[PARAM_CONTROL]);
6972 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6973
6974 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6975 pReq->requestId, pReq->sessionId, control);
6976
6977 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6978 if (!tb[PARAM_MIN_RSSI]) {
6979 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306980 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306981 }
6982
6983 if (!tb[PARAM_MAX_RSSI]) {
6984 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306985 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306986 }
6987
6988 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6989 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6990 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6991
6992 if (!(pReq->minRssi < pReq->maxRssi)) {
6993 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6994 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306995 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306996 }
6997 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6998 pReq->minRssi, pReq->maxRssi);
6999 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
7000
7001 }
7002 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
7003 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
7004 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
7005 }
7006 else {
7007 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307008 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307009 }
7010
7011 if (!HAL_STATUS_SUCCESS(status)) {
7012 hddLog(LOGE,
7013 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307014 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307015 }
7016
7017 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307018fail:
7019 vos_mem_free(pReq);
7020 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307021}
7022
7023/*
7024 * done with short names for the global vendor params
7025 * used by __wlan_hdd_cfg80211_monitor_rssi()
7026 */
7027#undef PARAM_MAX
7028#undef PARAM_CONTROL
7029#undef PARAM_REQUEST_ID
7030#undef PARAM_MAX_RSSI
7031#undef PARAM_MIN_RSSI
7032
7033/**
7034 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
7035 * @wiphy: wiphy structure pointer
7036 * @wdev: Wireless device structure pointer
7037 * @data: Pointer to the data received
7038 * @data_len: Length of @data
7039 *
7040 * Return: 0 on success; errno on failure
7041 */
7042static int
7043wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
7044 const void *data, int data_len)
7045{
7046 int ret;
7047
7048 vos_ssr_protect(__func__);
7049 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
7050 vos_ssr_unprotect(__func__);
7051
7052 return ret;
7053}
7054
7055/**
7056 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
7057 * @hddctx: HDD context
7058 * @data: rssi breached event data
7059 *
7060 * This function reads the rssi breached event %data and fill in the skb with
7061 * NL attributes and send up the NL event.
7062 * This callback execute in atomic context and must not invoke any
7063 * blocking calls.
7064 *
7065 * Return: none
7066 */
7067void hdd_rssi_threshold_breached_cb(void *hddctx,
7068 struct rssi_breach_event *data)
7069{
7070 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
7071 int status;
7072 struct sk_buff *skb;
7073
7074 ENTER();
7075 status = wlan_hdd_validate_context(pHddCtx);
7076
7077 if (0 != status) {
7078 return;
7079 }
7080
7081 if (!data) {
7082 hddLog(LOGE, FL("data is null"));
7083 return;
7084 }
7085
7086 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
7087#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7088 NULL,
7089#endif
7090 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
7091 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
7092 GFP_KERNEL);
7093
7094 if (!skb) {
7095 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
7096 return;
7097 }
7098
7099 hddLog(LOG1, "Req Id: %u Current rssi: %d",
7100 data->request_id, data->curr_rssi);
7101 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
7102 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
7103
7104 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
7105 data->request_id) ||
7106 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
7107 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
7108 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
7109 data->curr_rssi)) {
7110 hddLog(LOGE, FL("nla put fail"));
7111 goto fail;
7112 }
7113
7114 cfg80211_vendor_event(skb, GFP_KERNEL);
7115 return;
7116
7117fail:
7118 kfree_skb(skb);
7119 return;
7120}
7121
7122
7123
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307124/**
7125 * __wlan_hdd_cfg80211_setband() - set band
7126 * @wiphy: Pointer to wireless phy
7127 * @wdev: Pointer to wireless device
7128 * @data: Pointer to data
7129 * @data_len: Data length
7130 *
7131 * Return: 0 on success, negative errno on failure
7132 */
7133static int
7134__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7135 struct wireless_dev *wdev,
7136 const void *data,
7137 int data_len)
7138{
7139 struct net_device *dev = wdev->netdev;
7140 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7141 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7142 int ret;
7143 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7144 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7145
7146 ENTER();
7147
7148 ret = wlan_hdd_validate_context(hdd_ctx);
7149 if (0 != ret) {
7150 hddLog(LOGE, FL("HDD context is not valid"));
7151 return ret;
7152 }
7153
7154 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7155 policy)) {
7156 hddLog(LOGE, FL("Invalid ATTR"));
7157 return -EINVAL;
7158 }
7159
7160 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7161 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7162 return -EINVAL;
7163 }
7164
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307165 hdd_ctx->isSetBandByNL = TRUE;
7166 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307167 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307168 hdd_ctx->isSetBandByNL = FALSE;
7169
7170 EXIT();
7171 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307172}
7173
7174/**
7175 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7176 * @wiphy: wiphy structure pointer
7177 * @wdev: Wireless device structure pointer
7178 * @data: Pointer to the data received
7179 * @data_len: Length of @data
7180 *
7181 * Return: 0 on success; errno on failure
7182 */
7183static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7184 struct wireless_dev *wdev,
7185 const void *data,
7186 int data_len)
7187{
7188 int ret = 0;
7189
7190 vos_ssr_protect(__func__);
7191 ret = __wlan_hdd_cfg80211_setband(wiphy,
7192 wdev, data, data_len);
7193 vos_ssr_unprotect(__func__);
7194
7195 return ret;
7196}
7197
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307198#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7199/**
7200 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7201 * @hdd_ctx: HDD context
7202 * @request_id: [input] request id
7203 * @pattern_id: [output] pattern id
7204 *
7205 * This function loops through request id to pattern id array
7206 * if the slot is available, store the request id and return pattern id
7207 * if entry exists, return the pattern id
7208 *
7209 * Return: 0 on success and errno on failure
7210 */
7211static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7212 uint32_t request_id,
7213 uint8_t *pattern_id)
7214{
7215 uint32_t i;
7216
7217 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7218 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7219 {
7220 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7221 {
7222 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7223 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7224 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7225 return 0;
7226 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7227 request_id) {
7228 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7229 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7230 return 0;
7231 }
7232 }
7233 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7234 return -EINVAL;
7235}
7236
7237/**
7238 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7239 * @hdd_ctx: HDD context
7240 * @request_id: [input] request id
7241 * @pattern_id: [output] pattern id
7242 *
7243 * This function loops through request id to pattern id array
7244 * reset request id to 0 (slot available again) and
7245 * return pattern id
7246 *
7247 * Return: 0 on success and errno on failure
7248 */
7249static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7250 uint32_t request_id,
7251 uint8_t *pattern_id)
7252{
7253 uint32_t i;
7254
7255 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7256 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7257 {
7258 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7259 {
7260 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7261 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7262 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7263 return 0;
7264 }
7265 }
7266 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7267 return -EINVAL;
7268}
7269
7270
7271/*
7272 * define short names for the global vendor params
7273 * used by __wlan_hdd_cfg80211_offloaded_packets()
7274 */
7275#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7276#define PARAM_REQUEST_ID \
7277 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7278#define PARAM_CONTROL \
7279 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7280#define PARAM_IP_PACKET \
7281 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7282#define PARAM_SRC_MAC_ADDR \
7283 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7284#define PARAM_DST_MAC_ADDR \
7285 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7286#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7287
7288/**
7289 * wlan_hdd_add_tx_ptrn() - add tx pattern
7290 * @adapter: adapter pointer
7291 * @hdd_ctx: hdd context
7292 * @tb: nl attributes
7293 *
7294 * This function reads the NL attributes and forms a AddTxPtrn message
7295 * posts it to SME.
7296 *
7297 */
7298static int
7299wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7300 struct nlattr **tb)
7301{
7302 struct sSirAddPeriodicTxPtrn *add_req;
7303 eHalStatus status;
7304 uint32_t request_id, ret, len;
7305 uint8_t pattern_id = 0;
7306 v_MACADDR_t dst_addr;
7307 uint16_t eth_type = htons(ETH_P_IP);
7308
7309 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7310 {
7311 hddLog(LOGE, FL("Not in Connected state!"));
7312 return -ENOTSUPP;
7313 }
7314
7315 add_req = vos_mem_malloc(sizeof(*add_req));
7316 if (!add_req)
7317 {
7318 hddLog(LOGE, FL("memory allocation failed"));
7319 return -ENOMEM;
7320 }
7321
7322 /* Parse and fetch request Id */
7323 if (!tb[PARAM_REQUEST_ID])
7324 {
7325 hddLog(LOGE, FL("attr request id failed"));
7326 goto fail;
7327 }
7328
7329 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7330 hddLog(LOG1, FL("Request Id: %u"), request_id);
7331 if (request_id == 0)
7332 {
7333 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307334 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307335 }
7336
7337 if (!tb[PARAM_PERIOD])
7338 {
7339 hddLog(LOGE, FL("attr period failed"));
7340 goto fail;
7341 }
7342 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7343 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7344 if (add_req->usPtrnIntervalMs == 0)
7345 {
7346 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7347 goto fail;
7348 }
7349
7350 if (!tb[PARAM_SRC_MAC_ADDR])
7351 {
7352 hddLog(LOGE, FL("attr source mac address failed"));
7353 goto fail;
7354 }
7355 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7356 VOS_MAC_ADDR_SIZE);
7357 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7358 MAC_ADDR_ARRAY(add_req->macAddress));
7359
7360 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7361 VOS_MAC_ADDR_SIZE))
7362 {
7363 hddLog(LOGE,
7364 FL("input src mac address and connected ap bssid are different"));
7365 goto fail;
7366 }
7367
7368 if (!tb[PARAM_DST_MAC_ADDR])
7369 {
7370 hddLog(LOGE, FL("attr dst mac address failed"));
7371 goto fail;
7372 }
7373 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7374 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7375 MAC_ADDR_ARRAY(dst_addr.bytes));
7376
7377 if (!tb[PARAM_IP_PACKET])
7378 {
7379 hddLog(LOGE, FL("attr ip packet failed"));
7380 goto fail;
7381 }
7382 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7383 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7384
7385 if (add_req->ucPtrnSize < 0 ||
7386 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7387 HDD_ETH_HEADER_LEN))
7388 {
7389 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7390 add_req->ucPtrnSize);
7391 goto fail;
7392 }
7393
7394 len = 0;
7395 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7396 len += VOS_MAC_ADDR_SIZE;
7397 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7398 VOS_MAC_ADDR_SIZE);
7399 len += VOS_MAC_ADDR_SIZE;
7400 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7401 len += 2;
7402
7403 /*
7404 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7405 * ------------------------------------------------------------
7406 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7407 * ------------------------------------------------------------
7408 */
7409 vos_mem_copy(&add_req->ucPattern[len],
7410 nla_data(tb[PARAM_IP_PACKET]),
7411 add_req->ucPtrnSize);
7412 add_req->ucPtrnSize += len;
7413
7414 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7415 add_req->ucPattern, add_req->ucPtrnSize);
7416
7417 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7418 if (ret)
7419 {
7420 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7421 goto fail;
7422 }
7423 add_req->ucPtrnId = pattern_id;
7424 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7425
7426 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7427 if (!HAL_STATUS_SUCCESS(status))
7428 {
7429 hddLog(LOGE,
7430 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7431 goto fail;
7432 }
7433
7434 EXIT();
7435 vos_mem_free(add_req);
7436 return 0;
7437
7438fail:
7439 vos_mem_free(add_req);
7440 return -EINVAL;
7441}
7442
7443/**
7444 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7445 * @adapter: adapter pointer
7446 * @hdd_ctx: hdd context
7447 * @tb: nl attributes
7448 *
7449 * This function reads the NL attributes and forms a DelTxPtrn message
7450 * posts it to SME.
7451 *
7452 */
7453static int
7454wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7455 struct nlattr **tb)
7456{
7457 struct sSirDelPeriodicTxPtrn *del_req;
7458 eHalStatus status;
7459 uint32_t request_id, ret;
7460 uint8_t pattern_id = 0;
7461
7462 /* Parse and fetch request Id */
7463 if (!tb[PARAM_REQUEST_ID])
7464 {
7465 hddLog(LOGE, FL("attr request id failed"));
7466 return -EINVAL;
7467 }
7468 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7469 if (request_id == 0)
7470 {
7471 hddLog(LOGE, FL("request_id cannot be zero"));
7472 return -EINVAL;
7473 }
7474
7475 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7476 if (ret)
7477 {
7478 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7479 return -EINVAL;
7480 }
7481
7482 del_req = vos_mem_malloc(sizeof(*del_req));
7483 if (!del_req)
7484 {
7485 hddLog(LOGE, FL("memory allocation failed"));
7486 return -ENOMEM;
7487 }
7488
7489 vos_mem_set(del_req, sizeof(*del_req), 0);
7490 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7491 VOS_MAC_ADDR_SIZE);
7492 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7493 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7494 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7495 request_id, pattern_id, del_req->ucPatternIdBitmap);
7496
7497 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7498 if (!HAL_STATUS_SUCCESS(status))
7499 {
7500 hddLog(LOGE,
7501 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7502 goto fail;
7503 }
7504
7505 EXIT();
7506 vos_mem_free(del_req);
7507 return 0;
7508
7509fail:
7510 vos_mem_free(del_req);
7511 return -EINVAL;
7512}
7513
7514
7515/**
7516 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7517 * @wiphy: Pointer to wireless phy
7518 * @wdev: Pointer to wireless device
7519 * @data: Pointer to data
7520 * @data_len: Data length
7521 *
7522 * Return: 0 on success, negative errno on failure
7523 */
7524static int
7525__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7526 struct wireless_dev *wdev,
7527 const void *data,
7528 int data_len)
7529{
7530 struct net_device *dev = wdev->netdev;
7531 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7532 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7533 struct nlattr *tb[PARAM_MAX + 1];
7534 uint8_t control;
7535 int ret;
7536 static const struct nla_policy policy[PARAM_MAX + 1] =
7537 {
7538 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7539 [PARAM_CONTROL] = { .type = NLA_U32 },
7540 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7541 .len = VOS_MAC_ADDR_SIZE },
7542 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7543 .len = VOS_MAC_ADDR_SIZE },
7544 [PARAM_PERIOD] = { .type = NLA_U32 },
7545 };
7546
7547 ENTER();
7548
7549 ret = wlan_hdd_validate_context(hdd_ctx);
7550 if (0 != ret)
7551 {
7552 hddLog(LOGE, FL("HDD context is not valid"));
7553 return ret;
7554 }
7555
7556 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7557 {
7558 hddLog(LOGE,
7559 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7560 return -ENOTSUPP;
7561 }
7562
7563 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7564 {
7565 hddLog(LOGE, FL("Invalid ATTR"));
7566 return -EINVAL;
7567 }
7568
7569 if (!tb[PARAM_CONTROL])
7570 {
7571 hddLog(LOGE, FL("attr control failed"));
7572 return -EINVAL;
7573 }
7574 control = nla_get_u32(tb[PARAM_CONTROL]);
7575 hddLog(LOG1, FL("Control: %d"), control);
7576
7577 if (control == WLAN_START_OFFLOADED_PACKETS)
7578 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7579 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7580 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7581 else
7582 {
7583 hddLog(LOGE, FL("Invalid control: %d"), control);
7584 return -EINVAL;
7585 }
7586}
7587
7588/*
7589 * done with short names for the global vendor params
7590 * used by __wlan_hdd_cfg80211_offloaded_packets()
7591 */
7592#undef PARAM_MAX
7593#undef PARAM_REQUEST_ID
7594#undef PARAM_CONTROL
7595#undef PARAM_IP_PACKET
7596#undef PARAM_SRC_MAC_ADDR
7597#undef PARAM_DST_MAC_ADDR
7598#undef PARAM_PERIOD
7599
7600/**
7601 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7602 * @wiphy: wiphy structure pointer
7603 * @wdev: Wireless device structure pointer
7604 * @data: Pointer to the data received
7605 * @data_len: Length of @data
7606 *
7607 * Return: 0 on success; errno on failure
7608 */
7609static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7610 struct wireless_dev *wdev,
7611 const void *data,
7612 int data_len)
7613{
7614 int ret = 0;
7615
7616 vos_ssr_protect(__func__);
7617 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7618 wdev, data, data_len);
7619 vos_ssr_unprotect(__func__);
7620
7621 return ret;
7622}
7623#endif
7624
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307625static const struct
7626nla_policy
7627qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307628 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7629 .type = NLA_BINARY,
7630 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307631};
7632
7633/**
7634 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7635 * get link properties like nss, rate flags and operating frequency for
7636 * the connection with the given peer.
7637 * @wiphy: WIPHY structure pointer
7638 * @wdev: Wireless device structure pointer
7639 * @data: Pointer to the data received
7640 * @data_len: Length of the data received
7641 *
7642 * This function return the above link properties on success.
7643 *
7644 * Return: 0 on success and errno on failure
7645 */
7646static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7647 struct wireless_dev *wdev,
7648 const void *data,
7649 int data_len)
7650{
7651 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7652 struct net_device *dev = wdev->netdev;
7653 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7654 hdd_station_ctx_t *hdd_sta_ctx;
7655 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7656 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7657 uint32_t sta_id;
7658 struct sk_buff *reply_skb;
7659 uint32_t rate_flags = 0;
7660 uint8_t nss;
7661 uint8_t final_rate_flags = 0;
7662 uint32_t freq;
7663 v_CONTEXT_t pVosContext = NULL;
7664 ptSapContext pSapCtx = NULL;
7665
7666 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7668 return -EINVAL;
7669 }
7670
7671 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7672 qca_wlan_vendor_attr_policy)) {
7673 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7674 return -EINVAL;
7675 }
7676
7677 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7678 hddLog(VOS_TRACE_LEVEL_ERROR,
7679 FL("Attribute peerMac not provided for mode=%d"),
7680 adapter->device_mode);
7681 return -EINVAL;
7682 }
7683
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307684 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7685 hddLog(VOS_TRACE_LEVEL_ERROR,
7686 FL("Attribute peerMac is invalid=%d"),
7687 adapter->device_mode);
7688 return -EINVAL;
7689 }
7690
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307691 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7692 sizeof(peer_mac));
7693 hddLog(VOS_TRACE_LEVEL_INFO,
7694 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7695 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7696
7697 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7698 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7699 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7700 if ((hdd_sta_ctx->conn_info.connState !=
7701 eConnectionState_Associated) ||
7702 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7703 VOS_MAC_ADDRESS_LEN)) {
7704 hddLog(VOS_TRACE_LEVEL_ERROR,
7705 FL("Not Associated to mac "MAC_ADDRESS_STR),
7706 MAC_ADDR_ARRAY(peer_mac));
7707 return -EINVAL;
7708 }
7709
7710 nss = 1; //pronto supports only one spatial stream
7711 freq = vos_chan_to_freq(
7712 hdd_sta_ctx->conn_info.operationChannel);
7713 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7714
7715 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7716 adapter->device_mode == WLAN_HDD_SOFTAP) {
7717
7718 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7719 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7720 if(pSapCtx == NULL){
7721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7722 FL("psapCtx is NULL"));
7723 return -ENOENT;
7724 }
7725
7726
7727 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7728 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7729 !vos_is_macaddr_broadcast(
7730 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7731 vos_mem_compare(
7732 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7733 peer_mac, VOS_MAC_ADDRESS_LEN))
7734 break;
7735 }
7736
7737 if (WLAN_MAX_STA_COUNT == sta_id) {
7738 hddLog(VOS_TRACE_LEVEL_ERROR,
7739 FL("No active peer with mac="MAC_ADDRESS_STR),
7740 MAC_ADDR_ARRAY(peer_mac));
7741 return -EINVAL;
7742 }
7743
7744 nss = 1; //pronto supports only one spatial stream
7745 freq = vos_chan_to_freq(
7746 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7747 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7748 } else {
7749 hddLog(VOS_TRACE_LEVEL_ERROR,
7750 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7751 MAC_ADDR_ARRAY(peer_mac));
7752 return -EINVAL;
7753 }
7754
7755 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7756 if (rate_flags & eHAL_TX_RATE_VHT80) {
7757 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307758#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7759 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307760 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307761#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307762 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7763 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307764#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7765 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307766 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307767#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307768 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7769 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7770 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7771 final_rate_flags |= RATE_INFO_FLAGS_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307772#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7773 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307774 if (rate_flags & eHAL_TX_RATE_HT40)
7775 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307776#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307777 }
7778
7779 if (rate_flags & eHAL_TX_RATE_SGI) {
7780 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7781 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7782 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7783 }
7784 }
7785
7786 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7787 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7788
7789 if (NULL == reply_skb) {
7790 hddLog(VOS_TRACE_LEVEL_ERROR,
7791 FL("getLinkProperties: skb alloc failed"));
7792 return -EINVAL;
7793 }
7794
7795 if (nla_put_u8(reply_skb,
7796 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7797 nss) ||
7798 nla_put_u8(reply_skb,
7799 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7800 final_rate_flags) ||
7801 nla_put_u32(reply_skb,
7802 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7803 freq)) {
7804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7805 kfree_skb(reply_skb);
7806 return -EINVAL;
7807 }
7808
7809 return cfg80211_vendor_cmd_reply(reply_skb);
7810}
7811
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307812#define BEACON_MISS_THRESH_2_4 \
7813 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7814#define BEACON_MISS_THRESH_5_0 \
7815 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307816#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7817#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7818#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7819#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307820#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7821 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307822#define PARAM_FORCE_RSN_IE \
7823 QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307824/*
7825 * hdd_set_qpower() - Process the qpower command and invoke the SME api
7826 * @hdd_ctx: hdd context
7827 * @enable: Value received in the command, 1 for disable and 2 for enable
7828 *
7829 * Return: void
7830 */
7831static void hdd_set_qpower(hdd_context_t *hdd_ctx, uint8_t enable)
7832{
7833 if (!hdd_ctx) {
7834 hddLog(LOGE, "hdd_ctx NULL");
7835 return;
7836 }
7837
7838 sme_set_qpower(hdd_ctx->hHal, enable);
7839}
7840
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307841/**
7842 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7843 * vendor command
7844 *
7845 * @wiphy: wiphy device pointer
7846 * @wdev: wireless device pointer
7847 * @data: Vendor command data buffer
7848 * @data_len: Buffer length
7849 *
7850 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7851 *
7852 * Return: EOK or other error codes.
7853 */
7854
7855static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7856 struct wireless_dev *wdev,
7857 const void *data,
7858 int data_len)
7859{
7860 struct net_device *dev = wdev->netdev;
7861 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7862 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7863 hdd_station_ctx_t *pHddStaCtx;
7864 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7865 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307866 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307867 eHalStatus status;
7868 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307869 uint8_t hb_thresh_val;
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307870 uint8_t qpower;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307871
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307872 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7873 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7874 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307875 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7876 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7877 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307878 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7879 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307880 [PARAM_FORCE_RSN_IE] = {.type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307881 };
7882
7883 ENTER();
7884
7885 if (VOS_FTM_MODE == hdd_get_conparam()) {
7886 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7887 return -EINVAL;
7888 }
7889
7890 ret_val = wlan_hdd_validate_context(pHddCtx);
7891 if (ret_val) {
7892 return ret_val;
7893 }
7894
7895 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7896
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307897 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7898 hddLog(LOGE, FL("Invalid ATTR"));
7899 return -EINVAL;
7900 }
7901
7902 /* check the Wifi Capability */
7903 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7904 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7905 {
7906 hddLog(VOS_TRACE_LEVEL_ERROR,
7907 FL("WIFICONFIG not supported by Firmware"));
7908 return -EINVAL;
7909 }
7910
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307911 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7912 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7913 modifyRoamParamsReq.value =
7914 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7915
7916 if (eHAL_STATUS_SUCCESS !=
7917 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7918 {
7919 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7920 ret_val = -EINVAL;
7921 }
7922 return ret_val;
7923 }
7924
7925 /* Moved this down in order to provide provision to set beacon
7926 * miss penalty count irrespective of connection state.
7927 */
7928 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7929 hddLog(LOGE, FL("Not in Connected state!"));
7930 return -ENOTSUPP;
7931 }
7932
7933 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307934
7935 if (!pReq) {
7936 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7937 "%s: Not able to allocate memory for tSetWifiConfigParams",
7938 __func__);
7939 return eHAL_STATUS_E_MALLOC_FAILED;
7940 }
7941
7942 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7943
7944 pReq->sessionId = pAdapter->sessionId;
7945 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7946
7947 if (tb[PARAM_MODULATED_DTIM]) {
7948 pReq->paramValue = nla_get_u32(
7949 tb[PARAM_MODULATED_DTIM]);
7950 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7951 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307952 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307953 hdd_set_pwrparams(pHddCtx);
7954 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7955 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7956
7957 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7958 iw_full_power_cbfn, pAdapter,
7959 eSME_FULL_PWR_NEEDED_BY_HDD);
7960 }
7961 else
7962 {
7963 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7964 }
7965 }
7966
7967 if (tb[PARAM_STATS_AVG_FACTOR]) {
7968 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7969 pReq->paramValue = nla_get_u16(
7970 tb[PARAM_STATS_AVG_FACTOR]);
7971 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7972 pReq->paramType, pReq->paramValue);
7973 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7974
7975 if (eHAL_STATUS_SUCCESS != status)
7976 {
7977 vos_mem_free(pReq);
7978 pReq = NULL;
7979 ret_val = -EPERM;
7980 return ret_val;
7981 }
7982 }
7983
7984
7985 if (tb[PARAM_GUARD_TIME]) {
7986 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7987 pReq->paramValue = nla_get_u32(
7988 tb[PARAM_GUARD_TIME]);
7989 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7990 pReq->paramType, pReq->paramValue);
7991 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7992
7993 if (eHAL_STATUS_SUCCESS != status)
7994 {
7995 vos_mem_free(pReq);
7996 pReq = NULL;
7997 ret_val = -EPERM;
7998 return ret_val;
7999 }
8000
8001 }
8002
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05308003 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
8004 hb_thresh_val = nla_get_u8(
8005 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
8006
8007 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
8008 hb_thresh_val);
8009 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
8010 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
8011 NULL, eANI_BOOLEAN_FALSE);
8012
8013 status = sme_update_hb_threshold(
8014 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
8015 WNI_CFG_HEART_BEAT_THRESHOLD,
8016 hb_thresh_val, eCSR_BAND_24);
8017 if (eHAL_STATUS_SUCCESS != status) {
8018 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
8019 vos_mem_free(pReq);
8020 pReq = NULL;
8021 return -EPERM;
8022 }
8023 }
8024
8025 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
8026 hb_thresh_val = nla_get_u8(
8027 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
8028
8029 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
8030 hb_thresh_val);
8031 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
8032 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
8033 NULL, eANI_BOOLEAN_FALSE);
8034
8035 status = sme_update_hb_threshold(
8036 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
8037 WNI_CFG_HEART_BEAT_THRESHOLD,
8038 hb_thresh_val, eCSR_BAND_5G);
8039 if (eHAL_STATUS_SUCCESS != status) {
8040 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
8041 vos_mem_free(pReq);
8042 pReq = NULL;
8043 return -EPERM;
8044 }
8045 }
8046
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05308047 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]) {
8048 qpower = nla_get_u8(
8049 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]);
8050
8051 if(qpower > 1) {
8052 hddLog(LOGE, "Invalid QPOWER value %d", qpower);
8053 vos_mem_free(pReq);
8054 pReq = NULL;
8055 return -EINVAL;
8056 }
8057 /* FW is expacting qpower as 1 for Disable and 2 for enable */
8058 qpower++;
8059 hdd_set_qpower(pHddCtx, qpower);
8060 }
8061
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05308062 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE] &&
8063 pHddCtx->cfg_ini->force_rsne_override) {
8064 uint8_t force_rsne_override;
8065
8066 force_rsne_override =
8067 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE]);
8068 if (force_rsne_override > 1) {
8069 hddLog(LOGE, "Invalid test_mode %d", force_rsne_override);
8070 ret_val = -EINVAL;
8071 }
8072 pHddCtx->force_rsne_override = force_rsne_override;
8073 hddLog(LOG1, "force_rsne_override - %d",
8074 pHddCtx->force_rsne_override);
8075 }
8076
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308077 EXIT();
8078 return ret_val;
8079}
8080
8081/**
8082 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
8083 * vendor command
8084 *
8085 * @wiphy: wiphy device pointer
8086 * @wdev: wireless device pointer
8087 * @data: Vendor command data buffer
8088 * @data_len: Buffer length
8089 *
8090 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
8091 *
8092 * Return: EOK or other error codes.
8093 */
8094static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
8095 struct wireless_dev *wdev,
8096 const void *data,
8097 int data_len)
8098{
8099 int ret;
8100
8101 vos_ssr_protect(__func__);
8102 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
8103 data, data_len);
8104 vos_ssr_unprotect(__func__);
8105
8106 return ret;
8107}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308108
8109/*
8110 * define short names for the global vendor params
8111 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8112 */
8113#define STATS_SET_INVALID \
8114 QCA_ATTR_NUD_STATS_SET_INVALID
8115#define STATS_SET_START \
8116 QCA_ATTR_NUD_STATS_SET_START
8117#define STATS_GW_IPV4 \
8118 QCA_ATTR_NUD_STATS_GW_IPV4
8119#define STATS_SET_MAX \
8120 QCA_ATTR_NUD_STATS_SET_MAX
8121
8122const struct nla_policy
8123qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
8124{
8125 [STATS_SET_START] = {.type = NLA_FLAG },
8126 [STATS_GW_IPV4] = {.type = NLA_U32 },
8127};
8128
8129/**
8130 * hdd_set_nud_stats_cb() - hdd callback api to get status
8131 * @data: pointer to adapter
8132 * @rsp: status
8133 *
8134 * Return: None
8135 */
8136static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
8137{
8138
8139 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8140
8141 if (NULL == adapter)
8142 return;
8143
8144 if (VOS_STATUS_SUCCESS == rsp) {
8145 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8146 "%s success received STATS_SET_START", __func__);
8147 } else {
8148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8149 "%s STATS_SET_START Failed!!", __func__);
8150 }
8151 return;
8152}
8153
8154/**
8155 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8156 * @wiphy: pointer to wireless wiphy structure.
8157 * @wdev: pointer to wireless_dev structure.
8158 * @data: pointer to apfind configuration data.
8159 * @data_len: the length in byte of apfind data.
8160 *
8161 * This is called when wlan driver needs to send arp stats to
8162 * firmware.
8163 *
8164 * Return: An error code or 0 on success.
8165 */
8166static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8167 struct wireless_dev *wdev,
8168 const void *data, int data_len)
8169{
8170 struct nlattr *tb[STATS_SET_MAX + 1];
8171 struct net_device *dev = wdev->netdev;
8172 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8173 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308174 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308175 setArpStatsParams arp_stats_params;
8176 int err = 0;
8177
8178 ENTER();
8179
8180 err = wlan_hdd_validate_context(hdd_ctx);
8181 if (0 != err)
8182 return err;
8183
8184 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8186 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8187 return -EINVAL;
8188 }
8189
8190 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8191 qca_wlan_vendor_set_nud_stats);
8192 if (err)
8193 {
8194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8195 "%s STATS_SET_START ATTR", __func__);
8196 return err;
8197 }
8198
8199 if (tb[STATS_SET_START])
8200 {
8201 if (!tb[STATS_GW_IPV4]) {
8202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8203 "%s STATS_SET_START CMD", __func__);
8204 return -EINVAL;
8205 }
8206 arp_stats_params.flag = true;
8207 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8208 } else {
8209 arp_stats_params.flag = false;
8210 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308211 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8213 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308214 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8215 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308216
8217 arp_stats_params.pkt_type = 1; // ARP packet type
8218
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308219 if (arp_stats_params.flag) {
8220 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8221 WLANTL_SetARPFWDatapath(pVosContext, true);
8222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8223 "%s Set FW in data path for ARP with tgt IP :%d",
8224 __func__, hdd_ctx->track_arp_ip);
8225 }
8226 else {
8227 WLANTL_SetARPFWDatapath(pVosContext, false);
8228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8229 "%s Remove FW from data path", __func__);
8230 }
8231
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308232 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8233 arp_stats_params.data_ctx = adapter;
8234
8235 if (eHAL_STATUS_SUCCESS !=
8236 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8238 "%s STATS_SET_START CMD Failed!!", __func__);
8239 return -EINVAL;
8240 }
8241
8242 EXIT();
8243
8244 return err;
8245}
8246
8247/**
8248 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8249 * @wiphy: pointer to wireless wiphy structure.
8250 * @wdev: pointer to wireless_dev structure.
8251 * @data: pointer to apfind configuration data.
8252 * @data_len: the length in byte of apfind data.
8253 *
8254 * This is called when wlan driver needs to send arp stats to
8255 * firmware.
8256 *
8257 * Return: An error code or 0 on success.
8258 */
8259static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8260 struct wireless_dev *wdev,
8261 const void *data, int data_len)
8262{
8263 int ret;
8264
8265 vos_ssr_protect(__func__);
8266 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8267 vos_ssr_unprotect(__func__);
8268
8269 return ret;
8270}
8271#undef STATS_SET_INVALID
8272#undef STATS_SET_START
8273#undef STATS_GW_IPV4
8274#undef STATS_SET_MAX
8275
8276/*
8277 * define short names for the global vendor params
8278 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8279 */
8280#define STATS_GET_INVALID \
8281 QCA_ATTR_NUD_STATS_SET_INVALID
8282#define COUNT_FROM_NETDEV \
8283 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8284#define COUNT_TO_LOWER_MAC \
8285 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8286#define RX_COUNT_BY_LOWER_MAC \
8287 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8288#define COUNT_TX_SUCCESS \
8289 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8290#define RSP_RX_COUNT_BY_LOWER_MAC \
8291 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8292#define RSP_RX_COUNT_BY_UPPER_MAC \
8293 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8294#define RSP_COUNT_TO_NETDEV \
8295 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8296#define RSP_COUNT_OUT_OF_ORDER_DROP \
8297 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8298#define AP_LINK_ACTIVE \
8299 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8300#define AP_LINK_DAD \
8301 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8302#define STATS_GET_MAX \
8303 QCA_ATTR_NUD_STATS_GET_MAX
8304
8305const struct nla_policy
8306qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8307{
8308 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8309 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8310 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8311 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8312 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8313 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8314 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8315 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8316 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8317 [AP_LINK_DAD] = {.type = NLA_FLAG },
8318};
8319
8320static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8321{
8322
8323 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308324 hdd_context_t *hdd_ctx;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308325 struct hdd_nud_stats_context *context;
8326 int status;
8327
8328 ENTER();
8329
8330 if (NULL == adapter)
8331 return;
8332
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308333 if (!rsp) {
8334 hddLog(LOGE, FL("data is null"));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308335 return;
8336 }
8337
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308338 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8339 status = wlan_hdd_validate_context(hdd_ctx);
8340 if (0 != status) {
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308341 return;
8342 }
8343
8344 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8345 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8346 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8347 adapter->dad |= rsp->dad;
8348
8349 spin_lock(&hdd_context_lock);
8350 context = &hdd_ctx->nud_stats_context;
8351 complete(&context->response_event);
8352 spin_unlock(&hdd_context_lock);
8353
8354 return;
8355}
8356static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8357 struct wireless_dev *wdev,
8358 const void *data, int data_len)
8359{
8360 int err = 0;
8361 unsigned long rc;
8362 struct hdd_nud_stats_context *context;
8363 struct net_device *dev = wdev->netdev;
8364 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8365 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8366 getArpStatsParams arp_stats_params;
8367 struct sk_buff *skb;
8368
8369 ENTER();
8370
8371 err = wlan_hdd_validate_context(hdd_ctx);
8372 if (0 != err)
8373 return err;
8374
8375 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8376 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8377 arp_stats_params.data_ctx = adapter;
8378
8379 spin_lock(&hdd_context_lock);
8380 context = &hdd_ctx->nud_stats_context;
8381 INIT_COMPLETION(context->response_event);
8382 spin_unlock(&hdd_context_lock);
8383
8384 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8386 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8387 return -EINVAL;
8388 }
8389
8390 if (eHAL_STATUS_SUCCESS !=
8391 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8393 "%s STATS_SET_START CMD Failed!!", __func__);
8394 return -EINVAL;
8395 }
8396
8397 rc = wait_for_completion_timeout(&context->response_event,
8398 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8399 if (!rc)
8400 {
8401 hddLog(LOGE,
8402 FL("Target response timed out request "));
8403 return -ETIMEDOUT;
8404 }
8405
8406 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8407 WLAN_NUD_STATS_LEN);
8408 if (!skb)
8409 {
8410 hddLog(VOS_TRACE_LEVEL_ERROR,
8411 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8412 __func__);
8413 return -ENOMEM;
8414 }
8415
8416 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8417 adapter->hdd_stats.hddArpStats.txCount) ||
8418 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8419 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8420 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8421 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8422 nla_put_u16(skb, COUNT_TX_SUCCESS,
8423 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8424 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8425 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8426 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8427 adapter->hdd_stats.hddArpStats.rxCount) ||
8428 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8429 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8430 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8431 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8432 hddLog(LOGE, FL("nla put fail"));
8433 kfree_skb(skb);
8434 return -EINVAL;
8435 }
8436 if (adapter->con_status)
8437 nla_put_flag(skb, AP_LINK_ACTIVE);
8438 if (adapter->dad)
8439 nla_put_flag(skb, AP_LINK_DAD);
8440
8441 cfg80211_vendor_cmd_reply(skb);
8442 return err;
8443}
8444
8445static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8446 struct wireless_dev *wdev,
8447 const void *data, int data_len)
8448{
8449 int ret;
8450
8451 vos_ssr_protect(__func__);
8452 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8453 vos_ssr_unprotect(__func__);
8454
8455 return ret;
8456}
8457
8458#undef QCA_ATTR_NUD_STATS_SET_INVALID
8459#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8460#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8461#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8462#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8463#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8464#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8465#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8466#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8467#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8468#undef QCA_ATTR_NUD_STATS_GET_MAX
8469
8470
8471
Kapil Guptaee33bf12016-12-20 18:27:37 +05308472#ifdef WLAN_FEATURE_APFIND
8473/**
8474 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8475 * @wiphy: pointer to wireless wiphy structure.
8476 * @wdev: pointer to wireless_dev structure.
8477 * @data: pointer to apfind configuration data.
8478 * @data_len: the length in byte of apfind data.
8479 *
8480 * This is called when wlan driver needs to send APFIND configurations to
8481 * firmware.
8482 *
8483 * Return: An error code or 0 on success.
8484 */
8485static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8486 struct wireless_dev *wdev,
8487 const void *data, int data_len)
8488{
8489 struct sme_ap_find_request_req apfind_req;
8490 VOS_STATUS status;
8491 int ret_val;
8492 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8493
8494 ENTER();
8495
8496 ret_val = wlan_hdd_validate_context(hdd_ctx);
8497 if (ret_val)
8498 return ret_val;
8499
8500 if (VOS_FTM_MODE == hdd_get_conparam()) {
8501 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8502 return -EPERM;
8503 }
8504
8505 apfind_req.request_data_len = data_len;
8506 apfind_req.request_data = data;
8507
8508 status = sme_apfind_set_cmd(&apfind_req);
8509 if (VOS_STATUS_SUCCESS != status) {
8510 ret_val = -EIO;
8511 }
8512 return ret_val;
8513}
8514
8515/**
8516 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8517 * @wiphy: pointer to wireless wiphy structure.
8518 * @wdev: pointer to wireless_dev structure.
8519 * @data: pointer to apfind configuration data.
8520 * @data_len: the length in byte of apfind data.
8521 *
8522 * This is called when wlan driver needs to send APFIND configurations to
8523 * firmware.
8524 *
8525 * Return: An error code or 0 on success.
8526 */
8527static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8528 struct wireless_dev *wdev,
8529 const void *data, int data_len)
8530{
8531 int ret;
8532
8533 vos_ssr_protect(__func__);
8534 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8535 vos_ssr_unprotect(__func__);
8536
8537 return ret;
8538}
8539#endif /* WLAN_FEATURE_APFIND */
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308540
8541/**
8542 * __wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8543 * @wiphy: pointer to wireless wiphy structure.
8544 * @wdev: pointer to wireless_dev structure.
8545 * @data: Pointer to the data to be passed via vendor interface
8546 * @data_len:Length of the data to be passed
8547 *
8548 * This is called by userspace to know the supported logger features
8549 *
8550 * Return: Return the Success or Failure code.
8551 */
8552static int
8553__wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8554 struct wireless_dev *wdev,
8555 const void *data, int data_len)
8556{
8557 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8558 int status;
8559 uint32_t features;
8560 struct sk_buff *reply_skb = NULL;
8561
8562 if (VOS_FTM_MODE == hdd_get_conparam()) {
8563 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8564 return -EINVAL;
8565 }
8566
8567 status = wlan_hdd_validate_context(hdd_ctx);
8568 if (0 != status)
8569 return -EINVAL;
8570
8571 features = 0;
8572
8573 if (hdd_is_memdump_supported())
8574 features |= WIFI_LOGGER_MEMORY_DUMP_SUPPORTED;
8575
8576 if (hdd_ctx->cfg_ini->wlanLoggingEnable &&
8577 hdd_ctx->cfg_ini->enableFatalEvent &&
8578 hdd_ctx->is_fatal_event_log_sup) {
8579 features |= WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED;
8580 features |= WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
8581 }
8582
8583 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8584 sizeof(uint32_t) + NLA_HDRLEN + NLMSG_HDRLEN);
8585 if (!reply_skb) {
8586 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
8587 return -ENOMEM;
8588 }
8589
8590 hddLog(LOG1, FL("Supported logger features: 0x%0x"), features);
8591 if (nla_put_u32(reply_skb, QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED,
8592 features)) {
8593 hddLog(LOGE, FL("nla put fail"));
8594 kfree_skb(reply_skb);
8595 return -EINVAL;
8596 }
8597
8598 return cfg80211_vendor_cmd_reply(reply_skb);
8599}
8600
8601/**
8602 * wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8603 * @wiphy: pointer to wireless wiphy structure.
8604 * @wdev: pointer to wireless_dev structure.
8605 * @data: Pointer to the data to be passed via vendor interface
8606 * @data_len:Length of the data to be passed
8607 *
8608 * This is called by userspace to know the supported logger features
8609 *
8610 * Return: Return the Success or Failure code.
8611 */
8612static int
8613wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8614 struct wireless_dev *wdev,
8615 const void *data, int data_len)
8616{
8617 int ret;
8618
8619 vos_ssr_protect(__func__);
8620 ret = __wlan_hdd_cfg80211_get_logger_supp_feature(wiphy, wdev,
8621 data, data_len);
8622 vos_ssr_unprotect(__func__);
8623
8624 return ret;
8625}
8626
Sunil Duttc69bccb2014-05-26 21:30:20 +05308627const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8628{
Mukul Sharma2a271632014-10-13 14:59:01 +05308629 {
8630 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8631 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8632 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8633 WIPHY_VENDOR_CMD_NEED_NETDEV |
8634 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308635 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308636 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308637
8638 {
8639 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8640 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8641 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8642 WIPHY_VENDOR_CMD_NEED_NETDEV |
8643 WIPHY_VENDOR_CMD_NEED_RUNNING,
8644 .doit = wlan_hdd_cfg80211_nan_request
8645 },
8646
Sunil Duttc69bccb2014-05-26 21:30:20 +05308647#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8648 {
8649 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8650 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8651 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8652 WIPHY_VENDOR_CMD_NEED_NETDEV |
8653 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308654 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308655 },
8656
8657 {
8658 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8659 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8660 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8661 WIPHY_VENDOR_CMD_NEED_NETDEV |
8662 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308663 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308664 },
8665
8666 {
8667 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8668 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8669 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8670 WIPHY_VENDOR_CMD_NEED_NETDEV |
8671 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308672 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308673 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308674#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308675#ifdef WLAN_FEATURE_EXTSCAN
8676 {
8677 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8678 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8679 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8680 WIPHY_VENDOR_CMD_NEED_NETDEV |
8681 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308682 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308683 },
8684 {
8685 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8686 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8687 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8688 WIPHY_VENDOR_CMD_NEED_NETDEV |
8689 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308690 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308691 },
8692 {
8693 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8694 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8695 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8696 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308697 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308698 },
8699 {
8700 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8701 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8702 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8703 WIPHY_VENDOR_CMD_NEED_NETDEV |
8704 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308705 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308706 },
8707 {
8708 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8709 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8710 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8711 WIPHY_VENDOR_CMD_NEED_NETDEV |
8712 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308713 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308714 },
8715 {
8716 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8717 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8718 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8719 WIPHY_VENDOR_CMD_NEED_NETDEV |
8720 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308721 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308722 },
8723 {
8724 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8725 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8726 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8727 WIPHY_VENDOR_CMD_NEED_NETDEV |
8728 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308729 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308730 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308731#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308732/*EXT TDLS*/
8733 {
8734 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8735 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8736 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8737 WIPHY_VENDOR_CMD_NEED_NETDEV |
8738 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308739 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308740 },
8741 {
8742 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8743 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8744 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8745 WIPHY_VENDOR_CMD_NEED_NETDEV |
8746 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308747 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308748 },
8749 {
8750 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8751 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8752 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8753 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308754 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308755 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308756 {
8757 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8758 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8759 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8760 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308761 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308762 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308763 {
8764 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8765 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8766 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8767 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308768 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308769 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308770 {
8771 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8772 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8773 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8774 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308775 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308776 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308777 {
8778 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8779 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8780 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8781 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308782 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308783 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308784 {
8785 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308786 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8787 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8788 WIPHY_VENDOR_CMD_NEED_NETDEV |
8789 WIPHY_VENDOR_CMD_NEED_RUNNING,
8790 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8791 },
8792 {
8793 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308794 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8795 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8796 WIPHY_VENDOR_CMD_NEED_NETDEV |
8797 WIPHY_VENDOR_CMD_NEED_RUNNING,
8798 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308799 },
8800 {
8801 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8802 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8803 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8804 WIPHY_VENDOR_CMD_NEED_NETDEV,
8805 .doit = wlan_hdd_cfg80211_wifi_logger_start
8806 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308807 {
8808 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8809 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8810 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8811 WIPHY_VENDOR_CMD_NEED_NETDEV|
8812 WIPHY_VENDOR_CMD_NEED_RUNNING,
8813 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308814 },
8815 {
8816 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8817 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8818 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8819 WIPHY_VENDOR_CMD_NEED_NETDEV |
8820 WIPHY_VENDOR_CMD_NEED_RUNNING,
8821 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308822 },
8823 {
8824 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8825 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8826 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8827 WIPHY_VENDOR_CMD_NEED_NETDEV |
8828 WIPHY_VENDOR_CMD_NEED_RUNNING,
8829 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308830 },
8831#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8832 {
8833 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8834 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8835 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8836 WIPHY_VENDOR_CMD_NEED_NETDEV |
8837 WIPHY_VENDOR_CMD_NEED_RUNNING,
8838 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308839 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308840#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308841 {
8842 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8843 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8844 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8845 WIPHY_VENDOR_CMD_NEED_NETDEV |
8846 WIPHY_VENDOR_CMD_NEED_RUNNING,
8847 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308848 },
8849 {
8850 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8851 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8852 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8853 WIPHY_VENDOR_CMD_NEED_NETDEV |
8854 WIPHY_VENDOR_CMD_NEED_RUNNING,
8855 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308856 },
8857#ifdef WLAN_FEATURE_APFIND
8858 {
8859 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8860 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8861 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8862 WIPHY_VENDOR_CMD_NEED_NETDEV,
8863 .doit = wlan_hdd_cfg80211_apfind_cmd
8864 },
8865#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308866 {
8867 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8868 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8869 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8870 WIPHY_VENDOR_CMD_NEED_NETDEV |
8871 WIPHY_VENDOR_CMD_NEED_RUNNING,
8872 .doit = wlan_hdd_cfg80211_set_nud_stats
8873 },
8874 {
8875 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8876 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8877 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8878 WIPHY_VENDOR_CMD_NEED_NETDEV |
8879 WIPHY_VENDOR_CMD_NEED_RUNNING,
8880 .doit = wlan_hdd_cfg80211_get_nud_stats
8881 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308882 {
8883 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8884 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8885 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8886 WIPHY_VENDOR_CMD_NEED_NETDEV |
8887 WIPHY_VENDOR_CMD_NEED_RUNNING,
8888 .doit = hdd_cfg80211_get_station_cmd
8889 },
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308890 {
8891 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8892 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET,
8893 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
Hanumanth Reddy Pothula07c95582018-05-23 12:41:22 +05308894 WIPHY_VENDOR_CMD_NEED_NETDEV,
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308895 .doit = wlan_hdd_cfg80211_get_logger_supp_feature
8896 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308897};
8898
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008899/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308900static const
8901struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008902{
8903#ifdef FEATURE_WLAN_CH_AVOID
8904 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308905 .vendor_id = QCA_NL80211_VENDOR_ID,
8906 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008907 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308908#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8909#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8910 {
8911 /* Index = 1*/
8912 .vendor_id = QCA_NL80211_VENDOR_ID,
8913 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8914 },
8915 {
8916 /* Index = 2*/
8917 .vendor_id = QCA_NL80211_VENDOR_ID,
8918 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8919 },
8920 {
8921 /* Index = 3*/
8922 .vendor_id = QCA_NL80211_VENDOR_ID,
8923 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8924 },
8925 {
8926 /* Index = 4*/
8927 .vendor_id = QCA_NL80211_VENDOR_ID,
8928 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8929 },
8930 {
8931 /* Index = 5*/
8932 .vendor_id = QCA_NL80211_VENDOR_ID,
8933 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8934 },
8935 {
8936 /* Index = 6*/
8937 .vendor_id = QCA_NL80211_VENDOR_ID,
8938 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8939 },
8940#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308941#ifdef WLAN_FEATURE_EXTSCAN
8942 {
8943 .vendor_id = QCA_NL80211_VENDOR_ID,
8944 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8945 },
8946 {
8947 .vendor_id = QCA_NL80211_VENDOR_ID,
8948 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8949 },
8950 {
8951 .vendor_id = QCA_NL80211_VENDOR_ID,
8952 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8953 },
8954 {
8955 .vendor_id = QCA_NL80211_VENDOR_ID,
8956 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8957 },
8958 {
8959 .vendor_id = QCA_NL80211_VENDOR_ID,
8960 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8961 },
8962 {
8963 .vendor_id = QCA_NL80211_VENDOR_ID,
8964 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8965 },
8966 {
8967 .vendor_id = QCA_NL80211_VENDOR_ID,
8968 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8969 },
8970 {
8971 .vendor_id = QCA_NL80211_VENDOR_ID,
8972 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8973 },
8974 {
8975 .vendor_id = QCA_NL80211_VENDOR_ID,
8976 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8977 },
8978 {
8979 .vendor_id = QCA_NL80211_VENDOR_ID,
8980 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8981 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308982#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308983/*EXT TDLS*/
8984 {
8985 .vendor_id = QCA_NL80211_VENDOR_ID,
8986 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8987 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308988 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8989 .vendor_id = QCA_NL80211_VENDOR_ID,
8990 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8991 },
8992
Srinivas Dasari030bad32015-02-18 23:23:54 +05308993
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308994 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308995 .vendor_id = QCA_NL80211_VENDOR_ID,
8996 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8997 },
8998
Sushant Kaushik084f6592015-09-10 13:11:56 +05308999 {
9000 .vendor_id = QCA_NL80211_VENDOR_ID,
9001 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05309002 },
9003 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
9004 .vendor_id = QCA_NL80211_VENDOR_ID,
9005 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
9006 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05309007 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
9008 .vendor_id = QCA_NL80211_VENDOR_ID,
9009 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
9010 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05309011 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
9012 .vendor_id = QCA_NL80211_VENDOR_ID,
9013 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
9014 },
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05309015 [QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
9016 .vendor_id = QCA_NL80211_VENDOR_ID,
9017 .subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
9018 },
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +05309019 [QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX] = {
9020 .vendor_id = QCA_NL80211_VENDOR_ID,
9021 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
9022 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009023};
9024
Jeff Johnson295189b2012-06-20 16:38:30 -07009025/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309026 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309027 * This function is called by hdd_wlan_startup()
9028 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309029 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07009030 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309031struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07009032{
9033 struct wiphy *wiphy;
9034 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309035 /*
9036 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07009037 */
9038 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
9039
9040 if (!wiphy)
9041 {
9042 /* Print error and jump into err label and free the memory */
9043 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
9044 return NULL;
9045 }
9046
Sunil Duttc69bccb2014-05-26 21:30:20 +05309047
Jeff Johnson295189b2012-06-20 16:38:30 -07009048 return wiphy;
9049}
9050
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309051#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
9052 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
9053/**
9054 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
9055 * @wiphy: pointer to wiphy
9056 * @config: pointer to config
9057 *
9058 * Return: None
9059 */
9060static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
9061 hdd_config_t *config)
9062{
9063 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
9064 if (config->max_sched_scan_plan_interval)
9065 wiphy->max_sched_scan_plan_interval =
9066 config->max_sched_scan_plan_interval;
9067 if (config->max_sched_scan_plan_iterations)
9068 wiphy->max_sched_scan_plan_iterations =
9069 config->max_sched_scan_plan_iterations;
9070}
9071#else
9072static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
9073 hdd_config_t *config)
9074{
9075}
9076#endif
9077
Jeff Johnson295189b2012-06-20 16:38:30 -07009078/*
9079 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309080 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07009081 * private ioctl to change the band value
9082 */
9083int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
9084{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309085 int i, j;
9086 eNVChannelEnabledType channelEnabledState;
9087
Jeff Johnsone7245742012-09-05 17:12:55 -07009088 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309089
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309090 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009091 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309092
9093 if (NULL == wiphy->bands[i])
9094 {
9095 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
9096 __func__, i);
9097 continue;
9098 }
9099
9100 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9101 {
9102 struct ieee80211_supported_band *band = wiphy->bands[i];
9103
9104 channelEnabledState = vos_nv_getChannelEnabledState(
9105 band->channels[j].hw_value);
9106
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309107 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309108 {
Abhishek Singh678227a2014-11-04 10:52:38 +05309109 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309110 continue;
9111 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309112 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309113 {
9114 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9115 continue;
9116 }
9117
9118 if (NV_CHANNEL_DISABLE == channelEnabledState ||
9119 NV_CHANNEL_INVALID == channelEnabledState)
9120 {
9121 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9122 }
9123 else if (NV_CHANNEL_DFS == channelEnabledState)
9124 {
9125 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9126 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
9127 }
9128 else
9129 {
9130 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
9131 |IEEE80211_CHAN_RADAR);
9132 }
9133 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009134 }
9135 return 0;
9136}
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309137
9138/**
9139 * hdd_add_channel_switch_support()- Adds Channel Switch flag if supported
9140 * @wiphy: Pointer to the wiphy.
9141 *
9142 * This Function adds Channel Switch support flag, if channel switch is
9143 * supported by kernel.
9144 * Return: void.
9145 */
9146#ifdef CHANNEL_SWITCH_SUPPORTED
9147static inline
9148void hdd_add_channel_switch_support(struct wiphy *wiphy)
9149{
9150 wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
9151 wiphy->max_num_csa_counters = WLAN_HDD_MAX_NUM_CSA_COUNTERS;
9152}
9153#else
9154static inline
9155void hdd_add_channel_switch_support(struct wiphy *wiphy)
9156{
9157}
9158#endif
9159
Jeff Johnson295189b2012-06-20 16:38:30 -07009160/*
9161 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309162 * This function is called by hdd_wlan_startup()
9163 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07009164 * This function is used to initialize and register wiphy structure.
9165 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309166int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009167 struct wiphy *wiphy,
9168 hdd_config_t *pCfg
9169 )
9170{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309171 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309172 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9173
Jeff Johnsone7245742012-09-05 17:12:55 -07009174 ENTER();
9175
Jeff Johnson295189b2012-06-20 16:38:30 -07009176 /* Now bind the underlying wlan device with wiphy */
9177 set_wiphy_dev(wiphy, dev);
9178
9179 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009180
Kiet Lam6c583332013-10-14 05:37:09 +05309181#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009182 /* the flag for the other case would be initialzed in
9183 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05309184#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9185 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
9186#else
Amar Singhal0a402232013-10-11 20:57:16 -07009187 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05309188#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05309189#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009190
Amar Singhalfddc28c2013-09-05 13:03:40 -07009191 /* This will disable updating of NL channels from passive to
9192 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309193#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9194 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
9195#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07009196 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309197#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07009198
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309199#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
9200 wiphy->wowlan = &wowlan_support_cfg80211_init;
9201#else
Nachiket Kukade1e1b90e2018-05-10 15:26:13 +05309202 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
9203 WIPHY_WOWLAN_MAGIC_PKT;
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309204 wiphy->wowlan.n_patterns = WOWL_MAX_PTRNS_ALLOWED;
9205 wiphy->wowlan.pattern_min_len = 1;
9206 wiphy->wowlan.pattern_max_len = WOWL_PTRN_MAX_SIZE;
9207#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009208
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009209#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009210 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
9211 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
9212 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07009213 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309214#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05309215 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309216#else
9217 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
9218#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009219#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009220
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009221#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009222 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08009223#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009224 || pCfg->isFastRoamIniFeatureEnabled
9225#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009226#ifdef FEATURE_WLAN_ESE
9227 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009228#endif
9229 )
9230 {
9231 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
9232 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08009233#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009234#ifdef FEATURE_WLAN_TDLS
9235 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
9236 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
9237#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309238#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05309239 if (pCfg->configPNOScanSupport)
9240 {
9241 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
9242 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
9243 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
9244 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
9245 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309246#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009247
Abhishek Singh10d85972015-04-17 10:27:23 +05309248#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9249 wiphy->features |= NL80211_FEATURE_HT_IBSS;
9250#endif
9251
Amar Singhalfddc28c2013-09-05 13:03:40 -07009252#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009253 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
9254 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07009255 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009256 driver need to determine what to do with both
9257 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07009258
9259 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07009260#else
9261 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009262#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009263
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309264 wiphy->max_scan_ssids = MAX_SCAN_SSID;
9265
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05309266 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07009267
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309268 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
9269
Jeff Johnson295189b2012-06-20 16:38:30 -07009270 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05309271 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
9272 | BIT(NL80211_IFTYPE_ADHOC)
9273 | BIT(NL80211_IFTYPE_P2P_CLIENT)
9274 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309275 | BIT(NL80211_IFTYPE_AP)
9276 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07009277
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309278 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009279 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309280#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9281 if( pCfg->enableMCC )
9282 {
9283 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309284 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009285
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309286 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309287 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009288
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309289 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309290 wiphy->iface_combinations = wlan_hdd_iface_combination;
9291 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009292#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309293 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009294
Jeff Johnson295189b2012-06-20 16:38:30 -07009295 /* Before registering we need to update the ht capabilitied based
9296 * on ini values*/
9297 if( !pCfg->ShortGI20MhzEnable )
9298 {
9299 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
9300 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07009301 }
9302
9303 if( !pCfg->ShortGI40MhzEnable )
9304 {
9305 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9306 }
9307
9308 if( !pCfg->nChannelBondingMode5GHz )
9309 {
9310 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9311 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309312 /*
9313 * In case of static linked driver at the time of driver unload,
9314 * module exit doesn't happens. Module cleanup helps in cleaning
9315 * of static memory.
9316 * If driver load happens statically, at the time of driver unload,
9317 * wiphy flags don't get reset because of static memory.
9318 * It's better not to store channel in static memory.
9319 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309320 wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9321 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309322 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309323 if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309324 {
9325 hddLog(VOS_TRACE_LEVEL_ERROR,
9326 FL("Not enough memory to allocate channels"));
9327 return -ENOMEM;
9328 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309329 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309330 &hdd_channels_2_4_GHZ[0],
9331 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009332
Agrawal Ashish97dec502015-11-26 20:20:58 +05309333 if (true == hdd_is_5g_supported(pHddCtx))
9334 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309335 wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9336 wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309337 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309338 if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309339 {
9340 hddLog(VOS_TRACE_LEVEL_ERROR,
9341 FL("Not enough memory to allocate channels"));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309342 vos_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
9343 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
Agrawal Ashish97dec502015-11-26 20:20:58 +05309344 return -ENOMEM;
9345 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309346 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309347 &hdd_channels_5_GHZ[0],
9348 sizeof(hdd_channels_5_GHZ));
9349 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309350
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309351 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309352 {
9353
9354 if (NULL == wiphy->bands[i])
9355 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309356 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309357 __func__, i);
9358 continue;
9359 }
9360
9361 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9362 {
9363 struct ieee80211_supported_band *band = wiphy->bands[i];
9364
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309365 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309366 {
9367 // Enable social channels for P2P
9368 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9369 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9370 else
9371 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9372 continue;
9373 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309374 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309375 {
9376 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9377 continue;
9378 }
9379 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009380 }
9381 /*Initialise the supported cipher suite details*/
9382 wiphy->cipher_suites = hdd_cipher_suites;
9383 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9384
9385 /*signal strength in mBm (100*dBm) */
9386 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9387
9388#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309389 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009390#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009391
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309392 hdd_add_channel_switch_support(wiphy);
Sunil Duttc69bccb2014-05-26 21:30:20 +05309393 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9394 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009395 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9396 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9397
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309398 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
9399
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309400 EXIT();
9401 return 0;
9402}
9403
9404/* In this function we are registering wiphy. */
9405int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9406{
9407 ENTER();
9408 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009409 if (0 > wiphy_register(wiphy))
9410 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309411 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009412 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9413 return -EIO;
9414 }
9415
9416 EXIT();
9417 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309418}
Jeff Johnson295189b2012-06-20 16:38:30 -07009419
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309420/* In this function we are updating channel list when,
9421 regulatory domain is FCC and country code is US.
9422 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9423 As per FCC smart phone is not a indoor device.
9424 GO should not opeate on indoor channels */
9425void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9426{
9427 int j;
9428 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9429 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9430 //Default counrtycode from NV at the time of wiphy initialization.
9431 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9432 &defaultCountryCode[0]))
9433 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009434 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309435 }
9436 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9437 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309438 if (NULL == wiphy->bands[HDD_NL80211_BAND_5GHZ])
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309439 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309440 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[HDD_NL80211_BAND_5GHZ] is NULL",__func__ );
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309441 return;
9442 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309443 for (j = 0; j < wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels; j++)
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309444 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309445 struct ieee80211_supported_band *band = wiphy->bands[HDD_NL80211_BAND_5GHZ];
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309446 // Mark UNII -1 band channel as passive
9447 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9448 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9449 }
9450 }
9451}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309452/* This function registers for all frame which supplicant is interested in */
9453void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009454{
Jeff Johnson295189b2012-06-20 16:38:30 -07009455 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9456 /* Register for all P2P action, public action etc frames */
9457 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009458 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309459 /* Register frame indication call back */
9460 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009461 /* Right now we are registering these frame when driver is getting
9462 initialized. Once we will move to 2.6.37 kernel, in which we have
9463 frame register ops, we will move this code as a part of that */
9464 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309465 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009466 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9467
9468 /* GAS Initial Response */
9469 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9470 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309471
Jeff Johnson295189b2012-06-20 16:38:30 -07009472 /* GAS Comeback Request */
9473 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9474 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9475
9476 /* GAS Comeback Response */
9477 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9478 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9479
9480 /* P2P Public Action */
9481 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309482 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009483 P2P_PUBLIC_ACTION_FRAME_SIZE );
9484
9485 /* P2P Action */
9486 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9487 (v_U8_t*)P2P_ACTION_FRAME,
9488 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009489
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309490 /* WNM BSS Transition Request frame */
9491 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9492 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9493 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009494
9495 /* WNM-Notification */
9496 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9497 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9498 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009499}
9500
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309501void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009502{
Jeff Johnson295189b2012-06-20 16:38:30 -07009503 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9504 /* Register for all P2P action, public action etc frames */
9505 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9506
Jeff Johnsone7245742012-09-05 17:12:55 -07009507 ENTER();
9508
Jeff Johnson295189b2012-06-20 16:38:30 -07009509 /* Right now we are registering these frame when driver is getting
9510 initialized. Once we will move to 2.6.37 kernel, in which we have
9511 frame register ops, we will move this code as a part of that */
9512 /* GAS Initial Request */
9513
9514 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9515 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9516
9517 /* GAS Initial Response */
9518 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9519 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309520
Jeff Johnson295189b2012-06-20 16:38:30 -07009521 /* GAS Comeback Request */
9522 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9523 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9524
9525 /* GAS Comeback Response */
9526 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9527 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9528
9529 /* P2P Public Action */
9530 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309531 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009532 P2P_PUBLIC_ACTION_FRAME_SIZE );
9533
9534 /* P2P Action */
9535 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9536 (v_U8_t*)P2P_ACTION_FRAME,
9537 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009538 /* WNM-Notification */
9539 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9540 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9541 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009542}
9543
9544#ifdef FEATURE_WLAN_WAPI
9545void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309546 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009547{
9548 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9549 tCsrRoamSetKey setKey;
9550 v_BOOL_t isConnected = TRUE;
9551 int status = 0;
9552 v_U32_t roamId= 0xFF;
9553 tANI_U8 *pKeyPtr = NULL;
9554 int n = 0;
9555
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309556 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9557 __func__, hdd_device_modetoString(pAdapter->device_mode),
9558 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009559
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309560 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009561 setKey.keyId = key_index; // Store Key ID
9562 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9563 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9564 setKey.paeRole = 0 ; // the PAE role
9565 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9566 {
9567 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9568 }
9569 else
9570 {
9571 isConnected = hdd_connIsConnected(pHddStaCtx);
9572 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9573 }
9574 setKey.keyLength = key_Len;
9575 pKeyPtr = setKey.Key;
9576 memcpy( pKeyPtr, key, key_Len);
9577
Arif Hussain6d2a3322013-11-17 19:50:10 -08009578 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009579 __func__, key_Len);
9580 for (n = 0 ; n < key_Len; n++)
9581 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9582 __func__,n,setKey.Key[n]);
9583
9584 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9585 if ( isConnected )
9586 {
9587 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9588 pAdapter->sessionId, &setKey, &roamId );
9589 }
9590 if ( status != 0 )
9591 {
9592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9593 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9594 __LINE__, status );
9595 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9596 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309597 /* Need to clear any trace of key value in the memory.
9598 * Thus zero out the memory even though it is local
9599 * variable.
9600 */
9601 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009602}
9603#endif /* FEATURE_WLAN_WAPI*/
9604
9605#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309606int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009607 beacon_data_t **ppBeacon,
9608 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009609#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309610int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009611 beacon_data_t **ppBeacon,
9612 struct cfg80211_beacon_data *params,
9613 int dtim_period)
9614#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309615{
Jeff Johnson295189b2012-06-20 16:38:30 -07009616 int size;
9617 beacon_data_t *beacon = NULL;
9618 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309619 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9620 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009621
Jeff Johnsone7245742012-09-05 17:12:55 -07009622 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009623 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309624 {
9625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9626 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009627 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309628 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009629
9630 old = pAdapter->sessionCtx.ap.beacon;
9631
9632 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309633 {
9634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9635 FL("session(%d) old and new heads points to NULL"),
9636 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009637 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309638 }
9639
9640 if (params->tail && !params->tail_len)
9641 {
9642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9643 FL("tail_len is zero but tail is not NULL"));
9644 return -EINVAL;
9645 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009646
Jeff Johnson295189b2012-06-20 16:38:30 -07009647#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9648 /* Kernel 3.0 is not updating dtim_period for set beacon */
9649 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309650 {
9651 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9652 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009653 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309654 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009655#endif
9656
Kapil Gupta137ef892016-12-13 19:38:00 +05309657 if (params->head)
9658 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009659 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309660 head = params->head;
9661 } else
9662 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009663 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309664 head = old->head;
9665 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009666
Kapil Gupta137ef892016-12-13 19:38:00 +05309667 if (params->tail || !old)
9668 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009669 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309670 tail = params->tail;
9671 } else
9672 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009673 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309674 tail = old->tail;
9675 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009676
Kapil Gupta137ef892016-12-13 19:38:00 +05309677 if (params->proberesp_ies || !old)
9678 {
9679 proberesp_ies_len = params->proberesp_ies_len;
9680 proberesp_ies = params->proberesp_ies;
9681 } else
9682 {
9683 proberesp_ies_len = old->proberesp_ies_len;
9684 proberesp_ies = old->proberesp_ies;
9685 }
9686
9687 if (params->assocresp_ies || !old)
9688 {
9689 assocresp_ies_len = params->assocresp_ies_len;
9690 assocresp_ies = params->assocresp_ies;
9691 } else
9692 {
9693 assocresp_ies_len = old->assocresp_ies_len;
9694 assocresp_ies = old->assocresp_ies;
9695 }
9696
9697 size = sizeof(beacon_data_t) + head_len + tail_len +
9698 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009699
9700 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009701 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309702 {
9703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9704 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009705 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309706 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009707
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009708#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309709 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009710 beacon->dtim_period = params->dtim_period;
9711 else
9712 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009713#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309714 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009715 beacon->dtim_period = dtim_period;
9716 else
9717 beacon->dtim_period = old->dtim_period;
9718#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309719
Jeff Johnson295189b2012-06-20 16:38:30 -07009720 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9721 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309722 beacon->proberesp_ies = beacon->tail + tail_len;
9723 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9724
Jeff Johnson295189b2012-06-20 16:38:30 -07009725 beacon->head_len = head_len;
9726 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309727 beacon->proberesp_ies_len = proberesp_ies_len;
9728 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009729
c_manjee527ecac2017-01-25 12:25:27 +05309730 if (head && head_len)
9731 memcpy(beacon->head, head, head_len);
9732 if (tail && tail_len)
9733 memcpy(beacon->tail, tail, tail_len);
9734 if (proberesp_ies && proberesp_ies_len)
9735 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9736 if (assocresp_ies && assocresp_ies_len)
9737 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009738
9739 *ppBeacon = beacon;
9740
9741 kfree(old);
9742
9743 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009744}
Jeff Johnson295189b2012-06-20 16:38:30 -07009745
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309746v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9747#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9748 const v_U8_t *pIes,
9749#else
9750 v_U8_t *pIes,
9751#endif
9752 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009753{
9754 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309755 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009756 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309757
Jeff Johnson295189b2012-06-20 16:38:30 -07009758 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309759 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009760 elem_id = ptr[0];
9761 elem_len = ptr[1];
9762 left -= 2;
9763 if(elem_len > left)
9764 {
9765 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009766 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009767 eid,elem_len,left);
9768 return NULL;
9769 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309770 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009771 {
9772 return ptr;
9773 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309774
Jeff Johnson295189b2012-06-20 16:38:30 -07009775 left -= elem_len;
9776 ptr += (elem_len + 2);
9777 }
9778 return NULL;
9779}
9780
Jeff Johnson295189b2012-06-20 16:38:30 -07009781/* Check if rate is 11g rate or not */
9782static int wlan_hdd_rate_is_11g(u8 rate)
9783{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009784 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009785 u8 i;
9786 for (i = 0; i < 8; i++)
9787 {
9788 if(rate == gRateArray[i])
9789 return TRUE;
9790 }
9791 return FALSE;
9792}
9793
9794/* Check for 11g rate and set proper 11g only mode */
9795static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9796 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9797{
9798 u8 i, num_rates = pIe[0];
9799
9800 pIe += 1;
9801 for ( i = 0; i < num_rates; i++)
9802 {
9803 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9804 {
9805 /* If rate set have 11g rate than change the mode to 11G */
9806 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9807 if (pIe[i] & BASIC_RATE_MASK)
9808 {
9809 /* If we have 11g rate as basic rate, it means mode
9810 is 11g only mode.
9811 */
9812 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9813 *pCheckRatesfor11g = FALSE;
9814 }
9815 }
9816 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9817 {
9818 *require_ht = TRUE;
9819 }
9820 }
9821 return;
9822}
9823
9824static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9825{
9826 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9827 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9828 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9829 u8 checkRatesfor11g = TRUE;
9830 u8 require_ht = FALSE;
9831 u8 *pIe=NULL;
9832
9833 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9834
9835 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9836 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9837 if (pIe != NULL)
9838 {
9839 pIe += 1;
9840 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9841 &pConfig->SapHw_mode);
9842 }
9843
9844 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9845 WLAN_EID_EXT_SUPP_RATES);
9846 if (pIe != NULL)
9847 {
9848
9849 pIe += 1;
9850 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9851 &pConfig->SapHw_mode);
9852 }
9853
9854 if( pConfig->channel > 14 )
9855 {
9856 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9857 }
9858
9859 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9860 WLAN_EID_HT_CAPABILITY);
9861
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309862 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009863 {
9864 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9865 if(require_ht)
9866 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9867 }
9868}
9869
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309870static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9871 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9872{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009873 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309874 v_U8_t *pIe = NULL;
9875 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9876
9877 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9878 pBeacon->tail, pBeacon->tail_len);
9879
9880 if (pIe)
9881 {
9882 ielen = pIe[1] + 2;
9883 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9884 {
9885 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9886 }
9887 else
9888 {
9889 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9890 return -EINVAL;
9891 }
9892 *total_ielen += ielen;
9893 }
9894 return 0;
9895}
9896
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009897static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9898 v_U8_t *genie, v_U8_t *total_ielen)
9899{
9900 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9901 int left = pBeacon->tail_len;
9902 v_U8_t *ptr = pBeacon->tail;
9903 v_U8_t elem_id, elem_len;
9904 v_U16_t ielen = 0;
9905
9906 if ( NULL == ptr || 0 == left )
9907 return;
9908
9909 while (left >= 2)
9910 {
9911 elem_id = ptr[0];
9912 elem_len = ptr[1];
9913 left -= 2;
9914 if (elem_len > left)
9915 {
9916 hddLog( VOS_TRACE_LEVEL_ERROR,
9917 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9918 elem_id, elem_len, left);
9919 return;
9920 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309921 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009922 {
9923 /* skipping the VSIE's which we don't want to include or
9924 * it will be included by existing code
9925 */
9926 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9927#ifdef WLAN_FEATURE_WFD
9928 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9929#endif
9930 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9931 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9932 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9933 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9934 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9935 {
9936 ielen = ptr[1] + 2;
9937 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9938 {
9939 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9940 *total_ielen += ielen;
9941 }
9942 else
9943 {
9944 hddLog( VOS_TRACE_LEVEL_ERROR,
9945 "IE Length is too big "
9946 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9947 elem_id, elem_len, *total_ielen);
9948 }
9949 }
9950 }
9951
9952 left -= elem_len;
9953 ptr += (elem_len + 2);
9954 }
9955 return;
9956}
9957
Kapil Gupta137ef892016-12-13 19:38:00 +05309958int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009959{
9960 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309961 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009962 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009963 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309964 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009965
9966 genie = vos_mem_malloc(MAX_GENIE_LEN);
9967
9968 if(genie == NULL) {
9969
9970 return -ENOMEM;
9971 }
9972
Kapil Gupta137ef892016-12-13 19:38:00 +05309973 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309974 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9975 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009976 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309977 hddLog(LOGE,
9978 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309979 ret = -EINVAL;
9980 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009981 }
9982
9983#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309984 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9985 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9986 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309987 hddLog(LOGE,
9988 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309989 ret = -EINVAL;
9990 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009991 }
9992#endif
9993
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309994 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9995 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009996 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309997 hddLog(LOGE,
9998 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309999 ret = -EINVAL;
10000 goto done;
10001 }
10002
10003 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
10004 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -070010005 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -070010006 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010007
10008 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10009 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
10010 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
10011 {
10012 hddLog(LOGE,
10013 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010014 ret = -EINVAL;
10015 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010016 }
10017
10018 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10019 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10020 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10021 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10022 ==eHAL_STATUS_FAILURE)
10023 {
10024 hddLog(LOGE,
10025 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010026 ret = -EINVAL;
10027 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010028 }
10029
10030 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +053010031 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010032 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010033 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -070010034 u8 probe_rsp_ie_len[3] = {0};
10035 u8 counter = 0;
10036 /* Check Probe Resp Length if it is greater then 255 then Store
10037 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
10038 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
10039 Store More then 255 bytes into One Variable.
10040 */
10041 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
10042 {
10043 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
10044 {
10045 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
10046 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
10047 }
10048 else
10049 {
10050 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
10051 rem_probe_resp_ie_len = 0;
10052 }
10053 }
10054
10055 rem_probe_resp_ie_len = 0;
10056
10057 if (probe_rsp_ie_len[0] > 0)
10058 {
10059 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10060 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +053010061 (tANI_U8*)&pBeacon->
10062 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010063 probe_rsp_ie_len[0], NULL,
10064 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10065 {
10066 hddLog(LOGE,
10067 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010068 ret = -EINVAL;
10069 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010070 }
10071 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10072 }
10073
10074 if (probe_rsp_ie_len[1] > 0)
10075 {
10076 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10077 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +053010078 (tANI_U8*)&pBeacon->
10079 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010080 probe_rsp_ie_len[1], NULL,
10081 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10082 {
10083 hddLog(LOGE,
10084 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010085 ret = -EINVAL;
10086 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010087 }
10088 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10089 }
10090
10091 if (probe_rsp_ie_len[2] > 0)
10092 {
10093 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10094 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +053010095 (tANI_U8*)&pBeacon->
10096 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010097 probe_rsp_ie_len[2], NULL,
10098 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10099 {
10100 hddLog(LOGE,
10101 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010102 ret = -EINVAL;
10103 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010104 }
10105 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10106 }
10107
10108 if (probe_rsp_ie_len[1] == 0 )
10109 {
10110 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10111 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10112 eANI_BOOLEAN_FALSE) )
10113 {
10114 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010115 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010116 }
10117 }
10118
10119 if (probe_rsp_ie_len[2] == 0 )
10120 {
10121 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10122 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10123 eANI_BOOLEAN_FALSE) )
10124 {
10125 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010126 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010127 }
10128 }
10129
10130 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10131 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10132 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10133 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10134 == eHAL_STATUS_FAILURE)
10135 {
10136 hddLog(LOGE,
10137 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010138 ret = -EINVAL;
10139 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010140 }
10141 }
10142 else
10143 {
10144 // Reset WNI_CFG_PROBE_RSP Flags
10145 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
10146
10147 hddLog(VOS_TRACE_LEVEL_INFO,
10148 "%s: No Probe Response IE received in set beacon",
10149 __func__);
10150 }
10151
10152 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +053010153 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010154 {
10155 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +053010156 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
10157 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -070010158 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10159 {
10160 hddLog(LOGE,
10161 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010162 ret = -EINVAL;
10163 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010164 }
10165
10166 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10167 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
10168 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10169 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10170 == eHAL_STATUS_FAILURE)
10171 {
10172 hddLog(LOGE,
10173 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010174 ret = -EINVAL;
10175 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010176 }
10177 }
10178 else
10179 {
10180 hddLog(VOS_TRACE_LEVEL_INFO,
10181 "%s: No Assoc Response IE received in set beacon",
10182 __func__);
10183
10184 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10185 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10186 eANI_BOOLEAN_FALSE) )
10187 {
10188 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010189 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010190 }
10191 }
10192
Jeff Johnsone7245742012-09-05 17:12:55 -070010193done:
Jeff Johnson295189b2012-06-20 16:38:30 -070010194 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010195 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010196}
Jeff Johnson295189b2012-06-20 16:38:30 -070010197
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010198/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010199 * FUNCTION: wlan_hdd_validate_operation_channel
10200 * called by wlan_hdd_cfg80211_start_bss() and
10201 * wlan_hdd_cfg80211_set_channel()
10202 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010203 * channel list.
10204 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -070010205VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010206{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010207
Jeff Johnson295189b2012-06-20 16:38:30 -070010208 v_U32_t num_ch = 0;
10209 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10210 u32 indx = 0;
10211 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010212 v_U8_t fValidChannel = FALSE, count = 0;
10213 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010214
Jeff Johnson295189b2012-06-20 16:38:30 -070010215 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10216
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010217 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010218 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010219 /* Validate the channel */
10220 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010221 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010222 if ( channel == rfChannels[count].channelNum )
10223 {
10224 fValidChannel = TRUE;
10225 break;
10226 }
10227 }
10228 if (fValidChannel != TRUE)
10229 {
10230 hddLog(VOS_TRACE_LEVEL_ERROR,
10231 "%s: Invalid Channel [%d]", __func__, channel);
10232 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010233 }
10234 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010235 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010236 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010237 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10238 valid_ch, &num_ch))
10239 {
10240 hddLog(VOS_TRACE_LEVEL_ERROR,
10241 "%s: failed to get valid channel list", __func__);
10242 return VOS_STATUS_E_FAILURE;
10243 }
10244 for (indx = 0; indx < num_ch; indx++)
10245 {
10246 if (channel == valid_ch[indx])
10247 {
10248 break;
10249 }
10250 }
10251
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010252 if (indx >= num_ch)
10253 {
10254 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10255 {
10256 eCsrBand band;
10257 unsigned int freq;
10258
10259 sme_GetFreqBand(hHal, &band);
10260
10261 if (eCSR_BAND_5G == band)
10262 {
10263#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10264 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10265 {
10266 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010267 HDD_NL80211_BAND_2GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010268 }
10269 else
10270 {
10271 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010272 HDD_NL80211_BAND_5GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010273 }
10274#else
10275 freq = ieee80211_channel_to_frequency(channel);
10276#endif
10277 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
10278 return VOS_STATUS_SUCCESS;
10279 }
10280 }
10281
10282 hddLog(VOS_TRACE_LEVEL_ERROR,
10283 "%s: Invalid Channel [%d]", __func__, channel);
10284 return VOS_STATUS_E_FAILURE;
10285 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010286 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010287
Jeff Johnson295189b2012-06-20 16:38:30 -070010288 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010289
Jeff Johnson295189b2012-06-20 16:38:30 -070010290}
10291
Viral Modi3a32cc52013-02-08 11:14:52 -080010292/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010293 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -080010294 * This function is used to set the channel number
10295 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010296static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -080010297 struct ieee80211_channel *chan,
10298 enum nl80211_channel_type channel_type
10299 )
10300{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010301 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -080010302 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -070010303 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -080010304 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010305 hdd_context_t *pHddCtx;
10306 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010307
10308 ENTER();
10309
10310 if( NULL == dev )
10311 {
10312 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010313 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010314 return -ENODEV;
10315 }
10316 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010317
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010318 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10319 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10320 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010321 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010322 "%s: device_mode = %s (%d) freq = %d", __func__,
10323 hdd_device_modetoString(pAdapter->device_mode),
10324 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010325
10326 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10327 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010328 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010329 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010330 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010331 }
10332
10333 /*
10334 * Do freq to chan conversion
10335 * TODO: for 11a
10336 */
10337
10338 channel = ieee80211_frequency_to_channel(freq);
10339
10340 /* Check freq range */
10341 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10342 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10343 {
10344 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010345 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010346 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10347 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10348 return -EINVAL;
10349 }
10350
10351 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10352
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010353 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10354 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010355 {
10356 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10357 {
10358 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010359 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010360 return -EINVAL;
10361 }
10362 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10363 "%s: set channel to [%d] for device mode =%d",
10364 __func__, channel,pAdapter->device_mode);
10365 }
10366 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010367 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010368 )
10369 {
10370 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10371 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10372 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10373
10374 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10375 {
10376 /* Link is up then return cant set channel*/
10377 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010378 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010379 return -EINVAL;
10380 }
10381
10382 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10383 pHddStaCtx->conn_info.operationChannel = channel;
10384 pRoamProfile->ChannelInfo.ChannelList =
10385 &pHddStaCtx->conn_info.operationChannel;
10386 }
10387 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010388 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010389 )
10390 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010391 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10392 {
10393 if(VOS_STATUS_SUCCESS !=
10394 wlan_hdd_validate_operation_channel(pAdapter,channel))
10395 {
10396 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010397 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010398 return -EINVAL;
10399 }
10400 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10401 }
10402 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010403 {
10404 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10405
10406 /* If auto channel selection is configured as enable/ 1 then ignore
10407 channel set by supplicant
10408 */
10409 if ( cfg_param->apAutoChannelSelection )
10410 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010411 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10412 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010413 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010414 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10415 __func__, hdd_device_modetoString(pAdapter->device_mode),
10416 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010417 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010418 else
10419 {
10420 if(VOS_STATUS_SUCCESS !=
10421 wlan_hdd_validate_operation_channel(pAdapter,channel))
10422 {
10423 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010424 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010425 return -EINVAL;
10426 }
10427 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10428 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010429 }
10430 }
10431 else
10432 {
10433 hddLog(VOS_TRACE_LEVEL_FATAL,
10434 "%s: Invalid device mode failed to set valid channel", __func__);
10435 return -EINVAL;
10436 }
10437 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010438 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010439}
10440
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010441static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10442 struct net_device *dev,
10443 struct ieee80211_channel *chan,
10444 enum nl80211_channel_type channel_type
10445 )
10446{
10447 int ret;
10448
10449 vos_ssr_protect(__func__);
10450 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10451 vos_ssr_unprotect(__func__);
10452
10453 return ret;
10454}
10455
Anurag Chouhan83026002016-12-13 22:46:21 +053010456#ifdef DHCP_SERVER_OFFLOAD
10457void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10458 VOS_STATUS status)
10459{
10460 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10461
10462 ENTER();
10463
10464 if (NULL == adapter)
10465 {
10466 hddLog(VOS_TRACE_LEVEL_ERROR,
10467 "%s: adapter is NULL",__func__);
10468 return;
10469 }
10470
10471 adapter->dhcp_status.dhcp_offload_status = status;
10472 vos_event_set(&adapter->dhcp_status.vos_event);
10473 return;
10474}
10475
10476/**
10477 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10478 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010479 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010480 *
10481 * Return: None
10482 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010483VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10484 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010485{
10486 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10487 sir_dhcp_srv_offload_info dhcp_srv_info;
10488 tANI_U8 num_entries = 0;
10489 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10490 tANI_U8 num;
10491 tANI_U32 temp;
10492 VOS_STATUS ret;
10493
10494 ENTER();
10495
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010496 if (!re_init) {
10497 ret = wlan_hdd_validate_context(hdd_ctx);
10498 if (0 != ret)
10499 return VOS_STATUS_E_INVAL;
10500 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010501
10502 /* Prepare the request to send to SME */
10503 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10504 if (NULL == dhcp_srv_info) {
10505 hddLog(VOS_TRACE_LEVEL_ERROR,
10506 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10507 return VOS_STATUS_E_NOMEM;
10508 }
10509
10510 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10511
10512 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10513 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10514 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10515 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10516 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10517 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10518
10519 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10520 srv_ip,
10521 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010522 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010523 if (num_entries != IPADDR_NUM_ENTRIES) {
10524 hddLog(VOS_TRACE_LEVEL_ERROR,
10525 "%s: incorrect IP address (%s) assigned for DHCP server!",
10526 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10527 vos_mem_free(dhcp_srv_info);
10528 return VOS_STATUS_E_FAILURE;
10529 }
10530
10531 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10532 hddLog(VOS_TRACE_LEVEL_ERROR,
10533 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10534 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10535 vos_mem_free(dhcp_srv_info);
10536 return VOS_STATUS_E_FAILURE;
10537 }
10538
10539 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10540 hddLog(VOS_TRACE_LEVEL_ERROR,
10541 "%s: invalid IP address (%s)! The last field must be less than 100!",
10542 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10543 vos_mem_free(dhcp_srv_info);
10544 return VOS_STATUS_E_FAILURE;
10545 }
10546
10547 for (num = 0; num < num_entries; num++) {
10548 temp = srv_ip[num];
10549 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10550 }
10551
10552 if (eHAL_STATUS_SUCCESS !=
10553 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10554 hddLog(VOS_TRACE_LEVEL_ERROR,
10555 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10556 vos_mem_free(dhcp_srv_info);
10557 return VOS_STATUS_E_FAILURE;
10558 }
10559
10560 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10561 "%s: enable DHCP Server offload successfully!", __func__);
10562
10563 vos_mem_free(dhcp_srv_info);
10564 return 0;
10565}
10566#endif /* DHCP_SERVER_OFFLOAD */
10567
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010568/*
10569 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10570 * @wiphy_chan: wiphy channel number
10571 * @rfChannel: channel hw value
10572 * @disable: Disable/enable the flags
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010573 * @hdd_ctx: The HDD context handler
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010574 *
10575 * Modify wiphy flags and cds state if channel is indoor.
10576 *
10577 * Return: void
10578 */
10579void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010580 v_U32_t rfChannel, bool disable, hdd_context_t *hdd_ctx)
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010581{
10582 v_U32_t channelLoop;
10583 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10584
10585 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10586
10587 if (rfChannels[channelLoop].channelNum == rfChannel) {
10588 channelEnum = (eRfChannels)channelLoop;
10589 break;
10590 }
10591 }
10592
10593 if (INVALID_RF_CHANNEL == channelEnum)
10594 return;
10595
10596 if (disable) {
10597 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10598 wiphy_chan->flags |=
10599 IEEE80211_CHAN_DISABLED;
10600 regChannels[channelEnum].enabled =
10601 NV_CHANNEL_DISABLE;
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010602 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as DISABLE",
10603 channelEnum);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010604 }
10605 } else {
10606 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10607 wiphy_chan->flags &=
10608 ~IEEE80211_CHAN_DISABLED;
10609 /*
10610 * Indoor channels are marked as DFS
10611 * during regulatory processing
10612 */
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010613 if ((wiphy_chan->flags & (IEEE80211_CHAN_RADAR |
10614 IEEE80211_CHAN_PASSIVE_SCAN)) ||
10615 ((hdd_ctx->cfg_ini->indoor_channel_support == false)
10616 && (wiphy_chan->flags &
10617 IEEE80211_CHAN_INDOOR_ONLY))) {
10618 regChannels[channelEnum].enabled = NV_CHANNEL_DFS;
10619 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as DFS",
10620 channelEnum);
10621 } else {
10622 regChannels[channelEnum].enabled =
10623 NV_CHANNEL_ENABLE;
10624 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as ENABLE",
10625 channelEnum);
10626 }
10627 }
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010628
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010629 }
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010630}
10631
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010632void hdd_update_indoor_channel(hdd_context_t *hdd_ctx, bool disable)
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010633{
10634 int band_num;
10635 int chan_num;
10636 v_U32_t rfChannel;
10637 struct ieee80211_channel *wiphy_chan;
10638 struct wiphy *wiphy;
10639
10640 ENTER();
10641 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10642
10643 wiphy = hdd_ctx->wiphy;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010644 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010645
10646 if (wiphy->bands[band_num] == NULL)
10647 continue;
10648
10649 for (chan_num = 0;
10650 chan_num < wiphy->bands[band_num]->n_channels;
10651 chan_num++) {
10652
10653 wiphy_chan =
10654 &(wiphy->bands[band_num]->channels[chan_num]);
10655 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10656
10657 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010658 disable, hdd_ctx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010659 }
10660 }
10661 EXIT();
10662}
10663
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010664int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10665{
Dundi Raviteja49de66b2018-07-27 12:22:57 +053010666 eHalStatus status;
10667 int result = 0;
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010668 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10669 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10670 long ret;
10671 eConnectionState prev_conn_state;
10672 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
10673
10674 ENTER();
10675
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010676 /* Indicate sme of disconnect so that in progress connection or preauth
10677 * can be aborted
10678 */
10679 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10680 pAdapter->sessionId);
10681 pHddCtx->isAmpAllowed = VOS_TRUE;
10682
10683 /* Need to apply spin lock before decreasing active sessions
10684 * as there can be chance for double decrement if context switch
10685 * Calls hdd_DisConnectHandler.
10686 */
10687
10688 prev_conn_state = pHddStaCtx->conn_info.connState;
10689
10690 spin_lock_bh(&pAdapter->lock_for_active_session);
10691 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10692 {
10693 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10694 }
10695 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10696 spin_unlock_bh(&pAdapter->lock_for_active_session);
10697 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
10698
10699 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10700 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10701
10702 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10703
10704 /*
10705 * stop tx queues before deleting STA/BSS context from the firmware.
10706 * tx has to be disabled because the firmware can get busy dropping
10707 * the tx frames after BSS/STA has been deleted and will not send
10708 * back a response resulting in WDI timeout
10709 */
10710 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10711 netif_tx_disable(pAdapter->dev);
10712 netif_carrier_off(pAdapter->dev);
10713
10714 wlan_hdd_check_and_stop_mon(pAdapter, true);
10715
10716 /*issue disconnect*/
10717 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10718 pAdapter->sessionId, reason);
10719 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
10720 prev_conn_state != eConnectionState_Connecting)
10721 {
10722 hddLog(LOG1,
10723 FL("status = %d, already disconnected"), status);
10724 result = 0;
10725 /*
10726 * Wait here instead of returning directly. This will block the
10727 * next connect command and allow processing of the disconnect
10728 * in SME else we might hit some race conditions leading to SME
10729 * and HDD out of sync. As disconnect is already in progress,
10730 * wait here for 1 sec instead of 5 sec.
10731 */
10732 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
10733 goto wait_for_disconnect;
10734 }
10735 /*
10736 * Wait here instead of returning directly, this will block the next
10737 * connect command and allow processing of the scan for ssid and
10738 * the previous connect command in CSR. Else we might hit some
10739 * race conditions leading to SME and HDD out of sync.
10740 */
10741 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10742 {
10743 hddLog(LOG1,
10744 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
10745 }
10746 else if ( 0 != status )
10747 {
10748 hddLog(LOGE,
10749 FL("csrRoamDisconnect failure, returned %d"),
10750 (int)status);
10751 result = -EINVAL;
10752 goto disconnected;
10753 }
10754wait_for_disconnect:
10755 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
10756 msecs_to_jiffies(wait_time));
10757 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
10758 {
10759 hddLog(LOGE,
10760 "%s: Failed to disconnect, timed out", __func__);
10761 result = -ETIMEDOUT;
10762 }
10763disconnected:
10764 hddLog(LOG1,
10765 FL("Set HDD connState to eConnectionState_NotConnected"));
10766 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10767#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
10768 /* Sending disconnect event to userspace for kernel version < 3.11
10769 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
10770 */
10771 hddLog(LOG1, FL("Send disconnected event to userspace"));
10772
10773 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
10774 WLAN_REASON_UNSPECIFIED);
10775#endif
10776
10777 EXIT();
10778 return result;
10779}
10780
10781/*
10782 * hdd_check_and_disconnect_sta_on_invalid_channel() - Disconnect STA if it is
10783 * on indoor channel
10784 * @hdd_ctx: pointer to hdd context
10785 *
10786 * STA should be disconnected before starting the SAP if it is on indoor
10787 * channel.
10788 *
10789 * Return: void
10790 */
10791void hdd_check_and_disconnect_sta_on_invalid_channel(hdd_context_t *hdd_ctx)
10792{
10793
10794 hdd_adapter_t *sta_adapter;
10795 tANI_U8 sta_chan;
10796
10797 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
10798
10799 if (!sta_chan) {
10800 hddLog(LOG1, FL("STA not connected"));
10801 return;
10802 }
10803
10804 hddLog(LOG1, FL("STA connected on chan %hu"), sta_chan);
10805
10806 if (sme_IsChannelValid(hdd_ctx->hHal, sta_chan)) {
10807 hddLog(LOG1, FL("STA connected on chan %hu and it is valid"),
10808 sta_chan);
10809 return;
10810 }
10811
10812 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
10813
10814 if (!sta_adapter) {
10815 hddLog(LOG1, FL("STA adapter doesn't exist"));
10816 return;
10817 }
10818
10819 hddLog(LOG1, FL("chan %hu not valid, issue disconnect"), sta_chan);
10820 /* Issue Disconnect request */
10821 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10822}
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010823
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010824int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx)
10825{
10826 struct hdd_cache_channels *cache_chann;
10827 struct wiphy *wiphy;
10828 int freq, status, rfChannel;
10829 int i, band_num, channel_num;
10830 struct ieee80211_channel *wiphy_channel;
10831
10832 ENTER();
10833
10834 if (!hdd_ctx) {
10835 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10836 return -EINVAL;
10837 }
10838
10839 wiphy = hdd_ctx->wiphy;
10840
10841 mutex_lock(&hdd_ctx->cache_channel_lock);
10842
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010843 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010844
10845 if (!cache_chann || !cache_chann->num_channels) {
10846 hddLog(VOS_TRACE_LEVEL_INFO,
10847 "%s channel list is NULL or num channels are zero",
10848 __func__);
10849 mutex_unlock(&hdd_ctx->cache_channel_lock);
10850 return -EINVAL;
10851 }
10852
10853 for (i = 0; i < cache_chann->num_channels; i++) {
10854 status = hdd_wlan_get_freq(
10855 cache_chann->channel_info[i].channel_num,
10856 &freq);
10857
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010858 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
10859 band_num++) {
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010860 for (channel_num = 0; channel_num <
10861 wiphy->bands[band_num]->n_channels;
10862 channel_num++) {
10863 wiphy_channel = &(wiphy->bands[band_num]->
10864 channels[channel_num]);
10865 if (wiphy_channel->center_freq == freq) {
10866 rfChannel = wiphy_channel->hw_value;
10867 /*
10868 *Restore the orginal states
10869 *of the channels
10870 */
10871 vos_nv_set_channel_state(
10872 rfChannel,
10873 cache_chann->
10874 channel_info[i].reg_status);
10875 wiphy_channel->flags =
10876 cache_chann->
10877 channel_info[i].wiphy_status;
10878 break;
10879 }
10880 }
10881 if (channel_num < wiphy->bands[band_num]->n_channels)
10882 break;
10883 }
10884 }
10885
10886 mutex_unlock(&hdd_ctx->cache_channel_lock);
10887
10888 status = sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10889 if (status)
10890 hddLog(VOS_TRACE_LEVEL_ERROR, "Can't Restore channel list");
10891 EXIT();
10892
10893 return 0;
10894}
10895
10896/*
10897 * wlan_hdd_disable_channels() - Cache the the channels
10898 * and current state of the channels from the channel list
10899 * received in the command and disable the channels on the
10900 * wiphy and NV table.
10901 * @hdd_ctx: Pointer to hdd context
10902 *
10903 * @return: 0 on success, Error code on failure
10904 */
10905
10906static int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx)
10907{
10908 struct hdd_cache_channels *cache_chann;
10909 struct wiphy *wiphy;
10910 int freq, status, rfChannel;
10911 int i, band_num, band_ch_num;
10912 struct ieee80211_channel *wiphy_channel;
10913
10914 if (!hdd_ctx) {
10915 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10916 return -EINVAL;
10917 }
10918
10919 wiphy = hdd_ctx->wiphy;
10920
10921 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010922 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010923
10924 if (!cache_chann || !cache_chann->num_channels) {
10925 hddLog(VOS_TRACE_LEVEL_INFO,
10926 "%s channel list is NULL or num channels are zero",
10927 __func__);
10928 mutex_unlock(&hdd_ctx->cache_channel_lock);
10929 return -EINVAL;
10930 }
10931
10932 for (i = 0; i < cache_chann->num_channels; i++) {
10933 status = hdd_wlan_get_freq(
10934 cache_chann->channel_info[i].channel_num,
10935 &freq);
10936
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010937 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010938 band_num++) {
10939 for (band_ch_num = 0; band_ch_num <
10940 wiphy->bands[band_num]->n_channels;
10941 band_ch_num++) {
10942 wiphy_channel = &(wiphy->bands[band_num]->
10943 channels[band_ch_num]);
10944 if (wiphy_channel->center_freq == freq) {
10945 rfChannel = wiphy_channel->hw_value;
10946 /*
10947 * Cache the current states of
10948 * the channels
10949 */
10950 cache_chann->
10951 channel_info[i].reg_status =
10952 vos_nv_getChannelEnabledState(
10953 rfChannel);
10954
10955 cache_chann->
10956 channel_info[i].wiphy_status =
10957 wiphy_channel->flags;
10958 hddLog(VOS_TRACE_LEVEL_INFO,
10959 "Disable channel %d reg_stat %d wiphy_stat 0x%x",
10960 cache_chann->
10961 channel_info[i].channel_num,
10962 cache_chann->
10963 channel_info[i].reg_status,
10964 wiphy_channel->flags);
10965
10966 vos_nv_set_channel_state(
10967 rfChannel,
10968 NV_CHANNEL_DISABLE);
10969 wiphy_channel->flags |=
10970 IEEE80211_CHAN_DISABLED;
10971 break;
10972 }
10973 }
10974 if (band_ch_num < wiphy->bands[band_num]->n_channels)
10975 break;
10976 }
10977 }
10978
10979 mutex_unlock(&hdd_ctx->cache_channel_lock);
10980 sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10981 return 0;
10982}
10983
Jeff Johnson295189b2012-06-20 16:38:30 -070010984#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10985static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10986 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010987#else
10988static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10989 struct cfg80211_beacon_data *params,
10990 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010991 enum nl80211_hidden_ssid hidden_ssid,
10992 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010993#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010994{
10995 tsap_Config_t *pConfig;
10996 beacon_data_t *pBeacon = NULL;
10997 struct ieee80211_mgmt *pMgmt_frame;
10998 v_U8_t *pIe=NULL;
10999 v_U16_t capab_info;
11000 eCsrAuthType RSNAuthType;
11001 eCsrEncryptionType RSNEncryptType;
11002 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011003 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011004 tpWLAN_SAPEventCB pSapEventCallback;
11005 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070011006 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011007 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011008 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011009 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070011010 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080011011 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Vignesh Viswanathan36575f82018-06-14 16:52:21 +053011012 hdd_adapter_t *sta_adapter;
Peng Xu2446a892014-09-05 17:21:18 +053011013 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070011014 v_BOOL_t MFPCapable = VOS_FALSE;
11015 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011016 v_BOOL_t sapEnable11AC =
11017 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053011018 u_int16_t prev_rsn_length = 0;
11019
Jeff Johnson295189b2012-06-20 16:38:30 -070011020 ENTER();
11021
Nitesh Shah9b066282017-06-06 18:05:52 +053011022 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Vignesh Viswanathan36575f82018-06-14 16:52:21 +053011023
11024 /*
11025 * For STA+SAP concurrency support from GUI, first STA connection gets
11026 * triggered and while it is in progress, SAP start also comes up.
11027 * Once STA association is successful, STA connect event is sent to
11028 * kernel which gets queued in kernel workqueue and supplicant won't
11029 * process M1 received from AP and send M2 until this NL80211_CONNECT
11030 * event is received. Workqueue is not scheduled as RTNL lock is already
11031 * taken by hostapd thread which has issued start_bss command to driver.
11032 * Driver cannot complete start_bss as the pending command at the head
11033 * of the SME command pending list is hw_mode_update for STA session
11034 * which cannot be processed as SME is in WAITforKey state for STA
11035 * interface. The start_bss command for SAP interface is queued behind
11036 * the hw_mode_update command and so it cannot be processed until
11037 * hw_mode_update command is processed. This is causing a deadlock so
11038 * disconnect the STA interface first if connection or key exchange is
11039 * in progress and then start SAP interface.
11040 */
11041 sta_adapter = hdd_get_sta_connection_in_progress(pHddCtx);
11042 if (sta_adapter) {
11043 hddLog(LOG1, FL("Disconnecting STA with session id: %d"),
11044 sta_adapter->sessionId);
11045 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
11046 }
11047
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011048 iniConfig = pHddCtx->cfg_ini;
11049
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011050 /* Mark the indoor channel (passive) to disable */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011051 if (iniConfig->disable_indoor_channel &&
11052 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011053 hdd_update_indoor_channel(pHddCtx, true);
11054
11055 if (!VOS_IS_STATUS_SUCCESS(
11056 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
11057 hdd_update_indoor_channel(pHddCtx, false);
11058 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
11059 FL("Can't start BSS: update channel list failed"));
Bala Venkatesh5c06a252018-07-12 16:08:04 +053011060 ret = eHAL_STATUS_FAILURE;
11061 goto tdls_enable;
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011062 }
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053011063
11064 /* check if STA is on indoor channel */
11065 if (hdd_is_sta_sap_scc_allowed_on_dfs_chan(pHddCtx))
11066 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011067 }
11068
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011069 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
11070 /* Disable the channels received in command SET_DISABLE_CHANNEL_LIST*/
11071 wlan_hdd_disable_channels(pHddCtx);
11072 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
11073 }
11074
Jeff Johnson295189b2012-06-20 16:38:30 -070011075 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
11076
11077 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
11078
11079 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
11080
11081 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
11082
11083 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
11084
11085 //channel is already set in the set_channel Call back
11086 //pConfig->channel = pCommitConfig->channel;
11087
11088 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011089 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070011090 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
11091
11092 pConfig->dtim_period = pBeacon->dtim_period;
11093
Arif Hussain6d2a3322013-11-17 19:50:10 -080011094 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070011095 pConfig->dtim_period);
11096
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080011097 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070011098 {
11099 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011100 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053011101 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
11102 {
11103 tANI_BOOLEAN restartNeeded;
11104 pConfig->ieee80211d = 1;
11105 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
11106 sme_setRegInfo(hHal, pConfig->countryCode);
11107 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
11108 }
11109 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070011110 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070011111 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070011112 pConfig->ieee80211d = 1;
11113 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
11114 sme_setRegInfo(hHal, pConfig->countryCode);
11115 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070011116 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011117 else
11118 {
11119 pConfig->ieee80211d = 0;
11120 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011121 /*
11122 * If auto channel is configured i.e. channel is 0,
11123 * so skip channel validation.
11124 */
11125 if( AUTO_CHANNEL_SELECT != pConfig->channel )
11126 {
11127 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
11128 {
11129 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011130 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011131 ret = -EINVAL;
11132 goto error;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011133 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011134 pConfig->user_config_channel = pConfig->channel;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011135 }
11136 else
11137 {
11138 if(1 != pHddCtx->is_dynamic_channel_range_set)
11139 {
11140 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
11141 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
11142 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
11143 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011144 pHddCtx->is_dynamic_channel_range_set = 0;
11145 pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011146 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011147 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011148 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011149 {
11150 pConfig->ieee80211d = 0;
11151 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011152
11153#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11154 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11155 pConfig->authType = eSAP_OPEN_SYSTEM;
11156 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11157 pConfig->authType = eSAP_SHARED_KEY;
11158 else
11159 pConfig->authType = eSAP_AUTO_SWITCH;
11160#else
11161 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11162 pConfig->authType = eSAP_OPEN_SYSTEM;
11163 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11164 pConfig->authType = eSAP_SHARED_KEY;
11165 else
11166 pConfig->authType = eSAP_AUTO_SWITCH;
11167#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011168
11169 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011170
11171 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070011172 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053011173#ifdef SAP_AUTH_OFFLOAD
11174 /* In case of sap offload, hostapd.conf is configuted with open mode and
11175 * security is configured from ini file. Due to open mode in hostapd.conf
11176 * privacy bit is set to false which will result in not sending,
11177 * data packets as encrypted.
11178 * If enable_sap_auth_offload is enabled in ini and
11179 * sap_auth_offload_sec_type is type of WPA2-PSK,
11180 * driver will set privacy bit to 1.
11181 */
11182 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
11183 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
11184 pConfig->privacy = VOS_TRUE;
11185#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011186
11187 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
11188
11189 /*Set wps station to configured*/
11190 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
11191
11192 if(pIe)
11193 {
11194 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
11195 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011196 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011197 ret = -EINVAL;
11198 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011199 }
11200 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
11201 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070011202 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070011203 /* Check 15 bit of WPS IE as it contain information for wps state
11204 * WPS state
11205 */
11206 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
11207 {
11208 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
11209 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
11210 {
11211 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
11212 }
11213 }
11214 }
11215 else
11216 {
11217 pConfig->wps_state = SAP_WPS_DISABLED;
11218 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011219 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070011220
c_hpothufe599e92014-06-16 11:38:55 +053011221 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11222 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11223 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
11224 eCSR_ENCRYPT_TYPE_NONE;
11225
Jeff Johnson295189b2012-06-20 16:38:30 -070011226 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053011227 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011228 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011229 WLAN_EID_RSN);
11230 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011231 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011232 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011233 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11234 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11235 pConfig->RSNWPAReqIELength);
11236 else
11237 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11238 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011239 /* The actual processing may eventually be more extensive than
11240 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070011241 * by the app.
11242 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011243 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011244 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11245 &RSNEncryptType,
11246 &mcRSNEncryptType,
11247 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011248 &MFPCapable,
11249 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011250 pConfig->RSNWPAReqIE[1]+2,
11251 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011252
11253 if( VOS_STATUS_SUCCESS == status )
11254 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011255 /* Now copy over all the security attributes you have
11256 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011257 * */
11258 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11259 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11260 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11261 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011262 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011263 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011264 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11265 }
11266 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011267
Jeff Johnson295189b2012-06-20 16:38:30 -070011268 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11269 pBeacon->tail, pBeacon->tail_len);
11270
11271 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
11272 {
Kapil Gupta137ef892016-12-13 19:38:00 +053011273 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011274 {
11275 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053011276 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070011277 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011278 if (pConfig->RSNWPAReqIELength <=
11279 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
11280 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
11281 pIe[1] + 2);
11282 else
11283 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11284 pConfig->RSNWPAReqIELength);
11285
Jeff Johnson295189b2012-06-20 16:38:30 -070011286 }
11287 else
11288 {
11289 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011290 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11291 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11292 pConfig->RSNWPAReqIELength);
11293 else
11294 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11295 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011296 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011297 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11298 &RSNEncryptType,
11299 &mcRSNEncryptType,
11300 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011301 &MFPCapable,
11302 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011303 pConfig->RSNWPAReqIE[1]+2,
11304 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011305
11306 if( VOS_STATUS_SUCCESS == status )
11307 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011308 /* Now copy over all the security attributes you have
11309 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011310 * */
11311 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11312 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11313 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11314 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011315 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011316 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011317 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11318 }
11319 }
11320 }
11321
Kapil Gupta137ef892016-12-13 19:38:00 +053011322 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070011323 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011324 ret = -EINVAL;
11325 goto error;
Jeff Johnson4416a782013-03-25 14:17:50 -070011326 }
11327
Jeff Johnson295189b2012-06-20 16:38:30 -070011328 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
11329
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011330#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011331 if (params->ssid != NULL)
11332 {
11333 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
11334 pConfig->SSIDinfo.ssid.length = params->ssid_len;
11335 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11336 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11337 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011338#else
11339 if (ssid != NULL)
11340 {
11341 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
11342 pConfig->SSIDinfo.ssid.length = ssid_len;
11343 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11344 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11345 }
11346#endif
11347
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011348 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070011349 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011350
Jeff Johnson295189b2012-06-20 16:38:30 -070011351 /* default value */
11352 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
11353 pConfig->num_accept_mac = 0;
11354 pConfig->num_deny_mac = 0;
11355
11356 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11357 pBeacon->tail, pBeacon->tail_len);
11358
11359 /* pIe for black list is following form:
11360 type : 1 byte
11361 length : 1 byte
11362 OUI : 4 bytes
11363 acl type : 1 byte
11364 no of mac addr in black list: 1 byte
11365 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011366 */
11367 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011368 {
11369 pConfig->SapMacaddr_acl = pIe[6];
11370 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011371 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011372 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011373 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
11374 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011375 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11376 for (i = 0; i < pConfig->num_deny_mac; i++)
11377 {
11378 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11379 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011380 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011381 }
11382 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11383 pBeacon->tail, pBeacon->tail_len);
11384
11385 /* pIe for white list is following form:
11386 type : 1 byte
11387 length : 1 byte
11388 OUI : 4 bytes
11389 acl type : 1 byte
11390 no of mac addr in white list: 1 byte
11391 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011392 */
11393 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011394 {
11395 pConfig->SapMacaddr_acl = pIe[6];
11396 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011397 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011398 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011399 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
11400 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011401 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11402 for (i = 0; i < pConfig->num_accept_mac; i++)
11403 {
11404 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11405 acl_entry++;
11406 }
11407 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011408
Jeff Johnson295189b2012-06-20 16:38:30 -070011409 wlan_hdd_set_sapHwmode(pHostapdAdapter);
11410
Jeff Johnsone7245742012-09-05 17:12:55 -070011411#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011412 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011413 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
11414 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053011415 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
11416 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011417 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
11418 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011419 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
11420 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070011421 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011422 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070011423 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011424 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011425
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011426 /* If ACS disable and selected channel <= 14
11427 * OR
11428 * ACS enabled and ACS operating band is choosen as 2.4
11429 * AND
11430 * VHT in 2.4G Disabled
11431 * THEN
11432 * Fallback to 11N mode
11433 */
11434 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
11435 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053011436 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011437 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011438 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011439 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
11440 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011441 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
11442 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011443 }
11444#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011445
Jeff Johnson295189b2012-06-20 16:38:30 -070011446 // ht_capab is not what the name conveys,this is used for protection bitmap
11447 pConfig->ht_capab =
11448 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
11449
Kapil Gupta137ef892016-12-13 19:38:00 +053011450 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070011451 {
11452 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011453 ret = -EINVAL;
11454 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011455 }
11456
11457 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011458 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070011459 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
11460 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011461 pConfig->obssProtEnabled =
11462 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070011463
Chet Lanctot8cecea22014-02-11 19:09:36 -080011464#ifdef WLAN_FEATURE_11W
11465 pConfig->mfpCapable = MFPCapable;
11466 pConfig->mfpRequired = MFPRequired;
11467 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
11468 pConfig->mfpCapable, pConfig->mfpRequired);
11469#endif
11470
Arif Hussain6d2a3322013-11-17 19:50:10 -080011471 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070011472 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011473 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
11474 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
11475 (int)pConfig->channel);
11476 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
11477 pConfig->SapHw_mode, pConfig->privacy,
11478 pConfig->authType);
11479 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
11480 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
11481 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
11482 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070011483
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011484 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070011485 {
11486 //Bss already started. just return.
11487 //TODO Probably it should update some beacon params.
11488 hddLog( LOGE, "Bss Already started...Ignore the request");
11489 EXIT();
11490 return 0;
11491 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011492
Agarwal Ashish51325b52014-06-16 16:50:49 +053011493 if (vos_max_concurrent_connections_reached()) {
11494 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011495 ret = -EINVAL;
11496 goto error;
Agarwal Ashish51325b52014-06-16 16:50:49 +053011497 }
11498
Jeff Johnson295189b2012-06-20 16:38:30 -070011499 pConfig->persona = pHostapdAdapter->device_mode;
11500
Peng Xu2446a892014-09-05 17:21:18 +053011501 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
11502 if ( NULL != psmeConfig)
11503 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011504 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053011505 sme_GetConfigParam(hHal, psmeConfig);
11506 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011507#ifdef WLAN_FEATURE_AP_HT40_24G
11508 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11509 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
11510 && pHddCtx->cfg_ini->apHT40_24GEnabled)
11511 {
11512 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
11513 sme_UpdateConfig (hHal, psmeConfig);
11514 }
11515#endif
Peng Xu2446a892014-09-05 17:21:18 +053011516 vos_mem_free(psmeConfig);
11517 }
Peng Xuafc34e32014-09-25 13:23:55 +053011518 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053011519
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011520 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -070011521 pSapEventCallback = hdd_hostapd_SAPEventCB;
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011522
11523 vos_event_reset(&pHostapdState->vosEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -070011524 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
11525 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
11526 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011527 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011528 ret = -EINVAL;
11529 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011530 }
11531
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011532 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070011533 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
11534
11535 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011536
Jeff Johnson295189b2012-06-20 16:38:30 -070011537 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011538 {
11539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011540 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070011541 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011542 VOS_ASSERT(0);
11543 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011544
Jeff Johnson295189b2012-06-20 16:38:30 -070011545 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053011546 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
11547 VOS_STATUS_SUCCESS)
11548 {
11549 hddLog(LOGE,FL("Fail to get Softap sessionID"));
11550 VOS_ASSERT(0);
11551 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053011552 /* Initialize WMM configuation */
11553 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011554 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011555
Anurag Chouhan83026002016-12-13 22:46:21 +053011556#ifdef DHCP_SERVER_OFFLOAD
11557 /* set dhcp server offload */
11558 if (iniConfig->enable_dhcp_srv_offload &&
11559 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011560 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053011561 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053011562 if (!VOS_IS_STATUS_SUCCESS(status))
11563 {
11564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11565 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011566 vos_event_reset(&pHostapdState->vosEvent);
11567 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11568 status = vos_wait_single_event(&pHostapdState->vosEvent,
11569 10000);
11570 if (!VOS_IS_STATUS_SUCCESS(status)) {
11571 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011572 ret = -EINVAL;
11573 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011574 }
11575 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011576 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011577 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
11578 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
11579 {
11580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11581 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
11582 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011583 vos_event_reset(&pHostapdState->vosEvent);
11584 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11585 status = vos_wait_single_event(&pHostapdState->vosEvent,
11586 10000);
11587 if (!VOS_IS_STATUS_SUCCESS(status)) {
11588 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011589 ret = -EINVAL;
11590 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011591 }
11592 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011593 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011594#ifdef MDNS_OFFLOAD
11595 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011596 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011597 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
11598 if (VOS_IS_STATUS_SUCCESS(status))
11599 {
11600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11601 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011602 vos_event_reset(&pHostapdState->vosEvent);
11603 if (VOS_STATUS_SUCCESS ==
11604 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11605 status = vos_wait_single_event(&pHostapdState->vosEvent,
11606 10000);
11607 if (!VOS_IS_STATUS_SUCCESS(status)) {
11608 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011609 ret = -EINVAL;
11610 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011611 }
11612 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011613 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011614 status = vos_wait_single_event(&pHostapdAdapter->
11615 mdns_status.vos_event, 2000);
11616 if (!VOS_IS_STATUS_SUCCESS(status) ||
11617 pHostapdAdapter->mdns_status.mdns_enable_status ||
11618 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
11619 pHostapdAdapter->mdns_status.mdns_resp_status)
11620 {
11621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11622 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
11623 pHostapdAdapter->mdns_status.mdns_enable_status,
11624 pHostapdAdapter->mdns_status.mdns_fqdn_status,
11625 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011626 vos_event_reset(&pHostapdState->vosEvent);
11627 if (VOS_STATUS_SUCCESS ==
11628 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11629 status = vos_wait_single_event(&pHostapdState->vosEvent,
11630 10000);
11631 if (!VOS_IS_STATUS_SUCCESS(status)) {
11632 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011633 ret = -EINVAL;
11634 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011635 }
11636 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011637 }
11638 }
11639#endif /* MDNS_OFFLOAD */
11640 } else {
11641 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11642 ("DHCP Disabled ini %d, FW %d"),
11643 iniConfig->enable_dhcp_srv_offload,
11644 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053011645 }
11646#endif /* DHCP_SERVER_OFFLOAD */
11647
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011648#ifdef WLAN_FEATURE_P2P_DEBUG
11649 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
11650 {
11651 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
11652 {
11653 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11654 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011655 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011656 }
11657 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
11658 {
11659 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11660 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011661 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011662 }
11663 }
11664#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053011665 /* Check and restart SAP if it is on Unsafe channel */
11666 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011667
Jeff Johnson295189b2012-06-20 16:38:30 -070011668 pHostapdState->bCommit = TRUE;
11669 EXIT();
11670
11671 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011672error:
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011673 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11674 wlan_hdd_restore_channels(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011675 /* Revert the indoor to passive marking if START BSS fails */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011676 if (iniConfig->disable_indoor_channel &&
11677 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011678 hdd_update_indoor_channel(pHddCtx, false);
11679 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
11680 }
11681
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011682 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
Bala Venkatesh5c06a252018-07-12 16:08:04 +053011683
11684tdls_enable:
11685 if (ret != eHAL_STATUS_SUCCESS)
11686 wlan_hdd_tdls_reenable(pHddCtx);
11687
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011688 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011689}
11690
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011691#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011692static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011693 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011694 struct beacon_parameters *params)
11695{
11696 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011697 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011698 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011699
11700 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011701
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011702 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11703 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11704 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011705 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11706 hdd_device_modetoString(pAdapter->device_mode),
11707 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011708
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011709 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11710 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011711 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011712 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011713 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011714 }
11715
Agarwal Ashish51325b52014-06-16 16:50:49 +053011716 if (vos_max_concurrent_connections_reached()) {
11717 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11718 return -EINVAL;
11719 }
11720
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011721 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011722 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011723 )
11724 {
11725 beacon_data_t *old,*new;
11726
11727 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011728
Jeff Johnson295189b2012-06-20 16:38:30 -070011729 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011730 {
11731 hddLog(VOS_TRACE_LEVEL_WARN,
11732 FL("already beacon info added to session(%d)"),
11733 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011734 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011735 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011736
11737 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11738
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011739 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011740 {
11741 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011742 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011743 return -EINVAL;
11744 }
11745
11746 pAdapter->sessionCtx.ap.beacon = new;
11747
11748 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11749 }
11750
11751 EXIT();
11752 return status;
11753}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011754
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011755static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11756 struct net_device *dev,
11757 struct beacon_parameters *params)
11758{
11759 int ret;
11760
11761 vos_ssr_protect(__func__);
11762 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11763 vos_ssr_unprotect(__func__);
11764
11765 return ret;
11766}
11767
11768static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011769 struct net_device *dev,
11770 struct beacon_parameters *params)
11771{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011772 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011773 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11774 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011775 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011776
11777 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011778
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011779 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11780 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11781 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11782 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11783 __func__, hdd_device_modetoString(pAdapter->device_mode),
11784 pAdapter->device_mode);
11785
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011786 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11787 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011788 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011789 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011790 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011791 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011792
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011793 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011794 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011795 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011796 {
11797 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011798
Jeff Johnson295189b2012-06-20 16:38:30 -070011799 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011800
Jeff Johnson295189b2012-06-20 16:38:30 -070011801 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011802 {
11803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11804 FL("session(%d) old and new heads points to NULL"),
11805 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011806 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011807 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011808
11809 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11810
11811 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011812 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011813 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011814 return -EINVAL;
11815 }
11816
11817 pAdapter->sessionCtx.ap.beacon = new;
11818
11819 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11820 }
11821
11822 EXIT();
11823 return status;
11824}
11825
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011826static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11827 struct net_device *dev,
11828 struct beacon_parameters *params)
11829{
11830 int ret;
11831
11832 vos_ssr_protect(__func__);
11833 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11834 vos_ssr_unprotect(__func__);
11835
11836 return ret;
11837}
11838
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011839#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11840
11841#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011842static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011843 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011844#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011845static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011846 struct net_device *dev)
11847#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011848{
11849 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Vignesh Viswanathan5caacc22018-06-14 17:14:20 +053011850 hdd_adapter_t *staAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011851 hdd_context_t *pHddCtx = NULL;
11852 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011853 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011854 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011855
11856 ENTER();
11857
11858 if (NULL == pAdapter)
11859 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011861 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011862 return -ENODEV;
11863 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011864
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011865 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11866 TRACE_CODE_HDD_CFG80211_STOP_AP,
11867 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011868 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11869 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011870 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011871 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011872 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011873 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011874
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011875 pScanInfo = &pHddCtx->scan_info;
11876
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011877 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11878 __func__, hdd_device_modetoString(pAdapter->device_mode),
11879 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011880
Vignesh Viswanathan5caacc22018-06-14 17:14:20 +053011881 /*
11882 * if a sta connection is in progress in another adapter, disconnect
11883 * the sta and complete the sap operation. sta will reconnect
11884 * after sap stop is done.
11885 */
11886 staAdapter = hdd_get_sta_connection_in_progress(pHddCtx);
11887 if (staAdapter) {
11888 hddLog(LOG1, FL("disconnecting sta with session id: %d"),
11889 staAdapter->sessionId);
11890 wlan_hdd_disconnect(staAdapter, eCSR_DISCONNECT_REASON_DEAUTH);
11891 }
11892
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011893 ret = wlan_hdd_scan_abort(pAdapter);
11894
Girish Gowli4bf7a632014-06-12 13:42:11 +053011895 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011896 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011897 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11898 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011899
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011900 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011901 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11903 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011904
Jeff Johnsone7245742012-09-05 17:12:55 -070011905 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011906 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011907 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011908 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011909 }
11910
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011911 /* Delete all associated STAs before stopping AP/P2P GO */
11912 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011913 hdd_hostapd_stop(dev);
11914
Jeff Johnson295189b2012-06-20 16:38:30 -070011915 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011916 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011917 )
11918 {
11919 beacon_data_t *old;
11920
11921 old = pAdapter->sessionCtx.ap.beacon;
11922
11923 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011924 {
11925 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11926 FL("session(%d) beacon data points to NULL"),
11927 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011928 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011929 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011930
Jeff Johnson295189b2012-06-20 16:38:30 -070011931 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011932
11933 mutex_lock(&pHddCtx->sap_lock);
11934 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11935 {
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011936 hdd_hostapd_state_t *pHostapdState =
11937 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11938
Abhishek Singh10e17cf2018-03-12 14:34:22 +053011939 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
11940 hdd_wait_for_ecsa_complete(pHddCtx);
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011941 vos_event_reset(&pHostapdState->vosEvent);
11942
Jeff Johnson4416a782013-03-25 14:17:50 -070011943 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011944 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011945 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11946
11947 if (!VOS_IS_STATUS_SUCCESS(status))
11948 {
11949 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011950 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011951 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011952 }
11953 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011954 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011955 /* BSS stopped, clear the active sessions for this device mode */
11956 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011957 }
11958 mutex_unlock(&pHddCtx->sap_lock);
11959
11960 if(status != VOS_STATUS_SUCCESS)
11961 {
11962 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011963 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011964 return -EINVAL;
11965 }
11966
Jeff Johnson4416a782013-03-25 14:17:50 -070011967 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011968 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11969 ==eHAL_STATUS_FAILURE)
11970 {
11971 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011972 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011973 }
11974
Jeff Johnson4416a782013-03-25 14:17:50 -070011975 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011976 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11977 eANI_BOOLEAN_FALSE) )
11978 {
11979 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011980 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011981 }
11982
11983 // Reset WNI_CFG_PROBE_RSP Flags
11984 wlan_hdd_reset_prob_rspies(pAdapter);
11985
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011986 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11987
Jeff Johnson295189b2012-06-20 16:38:30 -070011988 pAdapter->sessionCtx.ap.beacon = NULL;
11989 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011990#ifdef WLAN_FEATURE_P2P_DEBUG
11991 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11992 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11993 {
11994 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11995 "GO got removed");
11996 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11997 }
11998#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011999 }
12000 EXIT();
12001 return status;
12002}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012003
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012004#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
12005static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
12006 struct net_device *dev)
12007{
12008 int ret;
12009
12010 vos_ssr_protect(__func__);
12011 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
12012 vos_ssr_unprotect(__func__);
12013
12014 return ret;
12015}
12016#else
12017static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
12018 struct net_device *dev)
12019{
12020 int ret;
12021
12022 vos_ssr_protect(__func__);
12023 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
12024 vos_ssr_unprotect(__func__);
12025
12026 return ret;
12027}
12028#endif
12029
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012030#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
12031
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012032static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012033 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012034 struct cfg80211_ap_settings *params)
12035{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012036 hdd_adapter_t *pAdapter;
12037 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012038 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012039
12040 ENTER();
12041
Girish Gowlib143d7a2015-02-18 19:39:55 +053012042 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012043 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053012045 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012046 return -ENODEV;
12047 }
12048
12049 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12050 if (NULL == pAdapter)
12051 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012053 "%s: HDD adapter is Null", __func__);
12054 return -ENODEV;
12055 }
12056
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012057 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12058 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
12059 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012060 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
12061 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012063 "%s: HDD adapter magic is invalid", __func__);
12064 return -ENODEV;
12065 }
12066
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053012067 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
12068
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012069 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012070 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012071 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012072 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012073 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012074 }
12075
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012076 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
12077 __func__, hdd_device_modetoString(pAdapter->device_mode),
12078 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012079
12080 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012081 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012082 )
12083 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012084 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012085
12086 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012087
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012088 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012089 {
12090 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12091 FL("already beacon info added to session(%d)"),
12092 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012093 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012094 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012095
Girish Gowlib143d7a2015-02-18 19:39:55 +053012096#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
12097 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12098 &new,
12099 &params->beacon);
12100#else
12101 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12102 &new,
12103 &params->beacon,
12104 params->dtim_period);
12105#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012106
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012107 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012108 {
12109 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012110 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012111 return -EINVAL;
12112 }
12113 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080012114#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070012115 wlan_hdd_cfg80211_set_channel(wiphy, dev,
12116#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
12117 params->channel, params->channel_type);
12118#else
12119 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
12120#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080012121#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012122 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012123 params->ssid_len, params->hidden_ssid,
12124 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012125 }
12126
12127 EXIT();
12128 return status;
12129}
12130
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012131static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
12132 struct net_device *dev,
12133 struct cfg80211_ap_settings *params)
12134{
12135 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012136
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012137 vos_ssr_protect(__func__);
12138 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
12139 vos_ssr_unprotect(__func__);
12140
12141 return ret;
12142}
12143
12144static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012145 struct net_device *dev,
12146 struct cfg80211_beacon_data *params)
12147{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012148 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012149 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012150 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012151
12152 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012153
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012154 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12155 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
12156 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080012157 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012158 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012159
12160 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12161 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012162 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012163 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012164 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012165 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012166
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012167 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012168 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012169 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012170 {
12171 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012172
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012173 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012174
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012175 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012176 {
12177 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12178 FL("session(%d) beacon data points to NULL"),
12179 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012180 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012181 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012182
12183 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
12184
12185 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012186 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012187 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012188 return -EINVAL;
12189 }
12190
12191 pAdapter->sessionCtx.ap.beacon = new;
12192
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012193 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
12194 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012195 }
12196
12197 EXIT();
12198 return status;
12199}
12200
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012201static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
12202 struct net_device *dev,
12203 struct cfg80211_beacon_data *params)
12204{
12205 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012206
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012207 vos_ssr_protect(__func__);
12208 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
12209 vos_ssr_unprotect(__func__);
12210
12211 return ret;
12212}
12213
12214#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070012215
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012216static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012217 struct net_device *dev,
12218 struct bss_parameters *params)
12219{
12220 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012221 hdd_context_t *pHddCtx;
12222 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012223
12224 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012225
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012226 if (NULL == pAdapter)
12227 {
12228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12229 "%s: HDD adapter is Null", __func__);
12230 return -ENODEV;
12231 }
12232 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012233 ret = wlan_hdd_validate_context(pHddCtx);
12234 if (0 != ret)
12235 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012236 return ret;
12237 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012238 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12239 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
12240 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012241 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12242 __func__, hdd_device_modetoString(pAdapter->device_mode),
12243 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012244
12245 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012246 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012247 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012248 {
12249 /* ap_isolate == -1 means that in change bss, upper layer doesn't
12250 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012251 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070012252 {
12253 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012254 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012255 }
12256
12257 EXIT();
12258 return 0;
12259}
12260
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012261static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
12262 struct net_device *dev,
12263 struct bss_parameters *params)
12264{
12265 int ret;
12266
12267 vos_ssr_protect(__func__);
12268 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
12269 vos_ssr_unprotect(__func__);
12270
12271 return ret;
12272}
Kiet Lam10841362013-11-01 11:36:50 +053012273/* FUNCTION: wlan_hdd_change_country_code_cd
12274* to wait for contry code completion
12275*/
12276void* wlan_hdd_change_country_code_cb(void *pAdapter)
12277{
12278 hdd_adapter_t *call_back_pAdapter = pAdapter;
12279 complete(&call_back_pAdapter->change_country_code);
12280 return NULL;
12281}
12282
Jeff Johnson295189b2012-06-20 16:38:30 -070012283/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012284 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070012285 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
12286 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012287int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012288 struct net_device *ndev,
12289 enum nl80211_iftype type,
12290 u32 *flags,
12291 struct vif_params *params
12292 )
12293{
12294 struct wireless_dev *wdev;
12295 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012296 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070012297 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012298 tCsrRoamProfile *pRoamProfile = NULL;
12299 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012300 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012301 eMib_dot11DesiredBssType connectedBssType;
12302 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012303 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012304
12305 ENTER();
12306
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012307 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012308 {
12309 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12310 "%s: Adapter context is null", __func__);
12311 return VOS_STATUS_E_FAILURE;
12312 }
12313
12314 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12315 if (!pHddCtx)
12316 {
12317 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12318 "%s: HDD context is null", __func__);
12319 return VOS_STATUS_E_FAILURE;
12320 }
12321
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012322 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12323 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
12324 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012325 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012326 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012327 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012328 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012329 }
12330
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012331 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12332 __func__, hdd_device_modetoString(pAdapter->device_mode),
12333 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012334
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012335 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
12336 hddLog(VOS_TRACE_LEVEL_FATAL,
12337 "%s: STA + MON is in progress, cannot change interface",
12338 __func__);
12339 }
12340
Agarwal Ashish51325b52014-06-16 16:50:49 +053012341 if (vos_max_concurrent_connections_reached()) {
12342 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12343 return -EINVAL;
12344 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012345 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012346 wdev = ndev->ieee80211_ptr;
12347
12348#ifdef WLAN_BTAMP_FEATURE
12349 if((NL80211_IFTYPE_P2P_CLIENT == type)||
12350 (NL80211_IFTYPE_ADHOC == type)||
12351 (NL80211_IFTYPE_AP == type)||
12352 (NL80211_IFTYPE_P2P_GO == type))
12353 {
12354 pHddCtx->isAmpAllowed = VOS_FALSE;
12355 // stop AMP traffic
12356 status = WLANBAP_StopAmp();
12357 if(VOS_STATUS_SUCCESS != status )
12358 {
12359 pHddCtx->isAmpAllowed = VOS_TRUE;
12360 hddLog(VOS_TRACE_LEVEL_FATAL,
12361 "%s: Failed to stop AMP", __func__);
12362 return -EINVAL;
12363 }
12364 }
12365#endif //WLAN_BTAMP_FEATURE
12366 /* Reset the current device mode bit mask*/
12367 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
12368
Bala Venkatesh5c06a252018-07-12 16:08:04 +053012369 if (((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
12370 (type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO)) ||
12371 type == NL80211_IFTYPE_AP)
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053012372 {
12373 /* Notify Mode change in case of concurrency.
12374 * Below function invokes TDLS teardown Functionality Since TDLS is
12375 * not Supported in case of concurrency i.e Once P2P session
12376 * is detected disable offchannel and teardown TDLS links
12377 */
12378 hddLog(LOG1,
12379 FL("Device mode = %d Interface type = %d"),
12380 pAdapter->device_mode, type);
12381 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
12382 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053012383
Jeff Johnson295189b2012-06-20 16:38:30 -070012384 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012385 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070012386 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012387 )
12388 {
12389 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012390 if (!pWextState)
12391 {
12392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12393 "%s: pWextState is null", __func__);
12394 return VOS_STATUS_E_FAILURE;
12395 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012396 pRoamProfile = &pWextState->roamProfile;
12397 LastBSSType = pRoamProfile->BSSType;
12398
12399 switch (type)
12400 {
12401 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012402 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012403 hddLog(VOS_TRACE_LEVEL_INFO,
12404 "%s: setting interface Type to INFRASTRUCTURE", __func__);
12405 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012406#ifdef WLAN_FEATURE_11AC
12407 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
12408 {
12409 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
12410 }
12411#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012412 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070012413 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012414 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012415 //Check for sub-string p2p to confirm its a p2p interface
12416 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012417 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053012418#ifdef FEATURE_WLAN_TDLS
12419 mutex_lock(&pHddCtx->tdls_lock);
12420 wlan_hdd_tdls_exit(pAdapter, TRUE);
12421 mutex_unlock(&pHddCtx->tdls_lock);
12422#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012423 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12424 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12425 }
12426 else
12427 {
12428 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012429 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012430 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012431 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053012432
Jeff Johnson295189b2012-06-20 16:38:30 -070012433 case NL80211_IFTYPE_ADHOC:
12434 hddLog(VOS_TRACE_LEVEL_INFO,
12435 "%s: setting interface Type to ADHOC", __func__);
12436 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
12437 pRoamProfile->phyMode =
12438 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070012439 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012440 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053012441 hdd_set_ibss_ops( pAdapter );
12442 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053012443
12444 status = hdd_sta_id_hash_attach(pAdapter);
12445 if (VOS_STATUS_SUCCESS != status) {
12446 hddLog(VOS_TRACE_LEVEL_ERROR,
12447 FL("Failed to initialize hash for IBSS"));
12448 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012449 break;
12450
12451 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012452 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012453 {
12454 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12455 "%s: setting interface Type to %s", __func__,
12456 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
12457
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012458 //Cancel any remain on channel for GO mode
12459 if (NL80211_IFTYPE_P2P_GO == type)
12460 {
12461 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
12462 }
Mohit Khanna0f232092012-09-11 14:46:08 -070012463 if (NL80211_IFTYPE_AP == type)
12464 {
12465 /* As Loading WLAN Driver one interface being created for p2p device
12466 * address. This will take one HW STA and the max number of clients
12467 * that can connect to softAP will be reduced by one. so while changing
12468 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
12469 * interface as it is not required in SoftAP mode.
12470 */
12471
12472 // Get P2P Adapter
12473 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
12474
12475 if (pP2pAdapter)
12476 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053012477 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053012478 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070012479 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12480 }
12481 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053012482 //Disable IMPS & BMPS for SAP/GO
12483 if(VOS_STATUS_E_FAILURE ==
12484 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
12485 {
12486 //Fail to Exit BMPS
12487 VOS_ASSERT(0);
12488 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053012489
12490 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
12491
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012492#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070012493
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012494 /* A Mutex Lock is introduced while changing the mode to
12495 * protect the concurrent access for the Adapters by TDLS
12496 * module.
12497 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012498 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012499#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012500 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053012501 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012502 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070012503 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12504 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012505#ifdef FEATURE_WLAN_TDLS
12506 mutex_unlock(&pHddCtx->tdls_lock);
12507#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012508 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
12509 (pConfig->apRandomBssidEnabled))
12510 {
12511 /* To meet Android requirements create a randomized
12512 MAC address of the form 02:1A:11:Fx:xx:xx */
12513 get_random_bytes(&ndev->dev_addr[3], 3);
12514 ndev->dev_addr[0] = 0x02;
12515 ndev->dev_addr[1] = 0x1A;
12516 ndev->dev_addr[2] = 0x11;
12517 ndev->dev_addr[3] |= 0xF0;
12518 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
12519 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080012520 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
12521 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012522 }
12523
Jeff Johnson295189b2012-06-20 16:38:30 -070012524 hdd_set_ap_ops( pAdapter->dev );
12525
Kiet Lam10841362013-11-01 11:36:50 +053012526 /* This is for only SAP mode where users can
12527 * control country through ini.
12528 * P2P GO follows station country code
12529 * acquired during the STA scanning. */
12530 if((NL80211_IFTYPE_AP == type) &&
12531 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
12532 {
12533 int status = 0;
12534 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
12535 "%s: setting country code from INI ", __func__);
12536 init_completion(&pAdapter->change_country_code);
12537 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
12538 (void *)(tSmeChangeCountryCallback)
12539 wlan_hdd_change_country_code_cb,
12540 pConfig->apCntryCode, pAdapter,
12541 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012542 eSIR_FALSE,
12543 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053012544 if (eHAL_STATUS_SUCCESS == status)
12545 {
12546 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012547 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053012548 &pAdapter->change_country_code,
12549 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012550 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053012551 {
12552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012553 FL("SME Timed out while setting country code %ld"),
12554 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080012555
12556 if (pHddCtx->isLogpInProgress)
12557 {
12558 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12559 "%s: LOGP in Progress. Ignore!!!", __func__);
12560 return -EAGAIN;
12561 }
Kiet Lam10841362013-11-01 11:36:50 +053012562 }
12563 }
12564 else
12565 {
12566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012567 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053012568 return -EINVAL;
12569 }
12570 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053012571 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070012572 if(status != VOS_STATUS_SUCCESS)
12573 {
12574 hddLog(VOS_TRACE_LEVEL_FATAL,
12575 "%s: Error initializing the ap mode", __func__);
12576 return -EINVAL;
12577 }
12578 hdd_set_conparam(1);
12579
Nirav Shah7e3c8132015-06-22 23:51:42 +053012580 status = hdd_sta_id_hash_attach(pAdapter);
12581 if (VOS_STATUS_SUCCESS != status)
12582 {
12583 hddLog(VOS_TRACE_LEVEL_ERROR,
12584 FL("Failed to initialize hash for AP"));
12585 return -EINVAL;
12586 }
12587
Jeff Johnson295189b2012-06-20 16:38:30 -070012588 /*interface type changed update in wiphy structure*/
12589 if(wdev)
12590 {
12591 wdev->iftype = type;
12592 pHddCtx->change_iface = type;
12593 }
12594 else
12595 {
12596 hddLog(VOS_TRACE_LEVEL_ERROR,
12597 "%s: ERROR !!!! Wireless dev is NULL", __func__);
12598 return -EINVAL;
12599 }
12600 goto done;
12601 }
12602
12603 default:
12604 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12605 __func__);
12606 return -EOPNOTSUPP;
12607 }
12608 }
12609 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012610 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070012611 )
12612 {
12613 switch(type)
12614 {
12615 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012616 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012617 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053012618
12619 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012620#ifdef FEATURE_WLAN_TDLS
12621
12622 /* A Mutex Lock is introduced while changing the mode to
12623 * protect the concurrent access for the Adapters by TDLS
12624 * module.
12625 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012626 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012627#endif
c_hpothu002231a2015-02-05 14:58:51 +053012628 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012629 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012630 //Check for sub-string p2p to confirm its a p2p interface
12631 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012632 {
12633 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12634 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12635 }
12636 else
12637 {
12638 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012639 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012640 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053012641
12642 /* set con_mode to STA only when no SAP concurrency mode */
12643 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
12644 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012645 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012646 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
12647 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012648#ifdef FEATURE_WLAN_TDLS
12649 mutex_unlock(&pHddCtx->tdls_lock);
12650#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053012651 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070012652 if( VOS_STATUS_SUCCESS != status )
12653 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070012654 /* In case of JB, for P2P-GO, only change interface will be called,
12655 * This is the right place to enable back bmps_imps()
12656 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012657 if (pHddCtx->hdd_wlan_suspended)
12658 {
12659 hdd_set_pwrparams(pHddCtx);
12660 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012661 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012662 goto done;
12663 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012664 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012665 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012666 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12667 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012668 goto done;
12669 default:
12670 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12671 __func__);
12672 return -EOPNOTSUPP;
12673
12674 }
12675
12676 }
12677 else
12678 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012679 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
12680 __func__, hdd_device_modetoString(pAdapter->device_mode),
12681 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012682 return -EOPNOTSUPP;
12683 }
12684
12685
12686 if(pRoamProfile)
12687 {
12688 if ( LastBSSType != pRoamProfile->BSSType )
12689 {
12690 /*interface type changed update in wiphy structure*/
12691 wdev->iftype = type;
12692
12693 /*the BSS mode changed, We need to issue disconnect
12694 if connected or in IBSS disconnect state*/
12695 if ( hdd_connGetConnectedBssType(
12696 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
12697 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
12698 {
12699 /*need to issue a disconnect to CSR.*/
12700 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12701 if( eHAL_STATUS_SUCCESS ==
12702 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12703 pAdapter->sessionId,
12704 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12705 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012706 ret = wait_for_completion_interruptible_timeout(
12707 &pAdapter->disconnect_comp_var,
12708 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12709 if (ret <= 0)
12710 {
12711 hddLog(VOS_TRACE_LEVEL_ERROR,
12712 FL("wait on disconnect_comp_var failed %ld"), ret);
12713 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012714 }
12715 }
12716 }
12717 }
12718
12719done:
12720 /*set bitmask based on updated value*/
12721 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012722
12723 /* Only STA mode support TM now
12724 * all other mode, TM feature should be disabled */
12725 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12726 (~VOS_STA & pHddCtx->concurrency_mode) )
12727 {
12728 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12729 }
12730
Jeff Johnson295189b2012-06-20 16:38:30 -070012731#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012732 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012733 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012734 {
12735 //we are ok to do AMP
12736 pHddCtx->isAmpAllowed = VOS_TRUE;
12737 }
12738#endif //WLAN_BTAMP_FEATURE
12739 EXIT();
12740 return 0;
12741}
12742
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012743/*
12744 * FUNCTION: wlan_hdd_cfg80211_change_iface
12745 * wrapper function to protect the actual implementation from SSR.
12746 */
12747int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12748 struct net_device *ndev,
12749 enum nl80211_iftype type,
12750 u32 *flags,
12751 struct vif_params *params
12752 )
12753{
12754 int ret;
12755
12756 vos_ssr_protect(__func__);
12757 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12758 vos_ssr_unprotect(__func__);
12759
12760 return ret;
12761}
12762
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012763#ifdef FEATURE_WLAN_TDLS
12764static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012765 struct net_device *dev,
12766#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12767 const u8 *mac,
12768#else
12769 u8 *mac,
12770#endif
12771 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012772{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012773 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012774 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012775 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012776 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012777 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012778 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012779
12780 ENTER();
12781
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012782 if (!dev) {
12783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12784 return -EINVAL;
12785 }
12786
12787 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12788 if (!pAdapter) {
12789 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12790 return -EINVAL;
12791 }
12792
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012793 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012794 {
12795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12796 "Invalid arguments");
12797 return -EINVAL;
12798 }
Hoonki Lee27511902013-03-14 18:19:06 -070012799
12800 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12801 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12802 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012804 "%s: TDLS mode is disabled OR not enabled in FW."
12805 MAC_ADDRESS_STR " Request declined.",
12806 __func__, MAC_ADDR_ARRAY(mac));
12807 return -ENOTSUPP;
12808 }
12809
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012810 if (pHddCtx->isLogpInProgress)
12811 {
12812 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12813 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012814 wlan_hdd_tdls_set_link_status(pAdapter,
12815 mac,
12816 eTDLS_LINK_IDLE,
12817 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012818 return -EBUSY;
12819 }
12820
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012821 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012822 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012823
12824 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012826 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12827 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012828 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012829 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012830 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012831
12832 /* in add station, we accept existing valid staId if there is */
12833 if ((0 == update) &&
12834 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12835 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012836 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012837 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012838 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012839 " link_status %d. staId %d. add station ignored.",
12840 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012841 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012842 return 0;
12843 }
12844 /* in change station, we accept only when staId is valid */
12845 if ((1 == update) &&
12846 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12847 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12848 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012849 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012850 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012851 "%s: " MAC_ADDRESS_STR
12852 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012853 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12854 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12855 mutex_unlock(&pHddCtx->tdls_lock);
12856 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012857 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012858 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012859
12860 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012861 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012862 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12864 "%s: " MAC_ADDRESS_STR
12865 " TDLS setup is ongoing. Request declined.",
12866 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012867 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012868 }
12869
12870 /* first to check if we reached to maximum supported TDLS peer.
12871 TODO: for now, return -EPERM looks working fine,
12872 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012873 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12874 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012875 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12877 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012878 " TDLS Max peer already connected. Request declined."
12879 " Num of peers (%d), Max allowed (%d).",
12880 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12881 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012882 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012883 }
12884 else
12885 {
12886 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012887 mutex_lock(&pHddCtx->tdls_lock);
12888 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012889 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012890 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012891 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012892 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12893 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12894 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012895 return -EPERM;
12896 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012897 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012898 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012899 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012900 wlan_hdd_tdls_set_link_status(pAdapter,
12901 mac,
12902 eTDLS_LINK_CONNECTING,
12903 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012904
Jeff Johnsond75fe012013-04-06 10:53:06 -070012905 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012906 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012907 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012909 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012910 if(StaParams->htcap_present)
12911 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012912 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012913 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012915 "ht_capa->extended_capabilities: %0x",
12916 StaParams->HTCap.extendedHtCapInfo);
12917 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012919 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012920 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012921 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012922 if(StaParams->vhtcap_present)
12923 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012924 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012925 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12926 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12927 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12928 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012929 {
12930 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012931 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012932 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012933 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012934 "[%d]: %x ", i, StaParams->supported_rates[i]);
12935 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012936 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012937 else if ((1 == update) && (NULL == StaParams))
12938 {
12939 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12940 "%s : update is true, but staParams is NULL. Error!", __func__);
12941 return -EPERM;
12942 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012943
12944 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12945
12946 if (!update)
12947 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012948 /*Before adding sta make sure that device exited from BMPS*/
12949 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12950 {
12951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12952 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12953 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12954 if (status != VOS_STATUS_SUCCESS) {
12955 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12956 }
12957 }
12958
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012959 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012960 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012961 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012962 hddLog(VOS_TRACE_LEVEL_ERROR,
12963 FL("Failed to add TDLS peer STA. Enable Bmps"));
12964 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012965 return -EPERM;
12966 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012967 }
12968 else
12969 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012970 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012971 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012972 if (ret != eHAL_STATUS_SUCCESS) {
12973 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12974 return -EPERM;
12975 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012976 }
12977
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012978 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012979 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12980
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012981 mutex_lock(&pHddCtx->tdls_lock);
12982 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12983
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012984 if ((pTdlsPeer != NULL) &&
12985 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012986 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012987 hddLog(VOS_TRACE_LEVEL_ERROR,
12988 FL("peer link status %u"), pTdlsPeer->link_status);
12989 mutex_unlock(&pHddCtx->tdls_lock);
12990 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012991 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012992 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012993
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012994 if (ret <= 0)
12995 {
12996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12997 "%s: timeout waiting for tdls add station indication %ld",
12998 __func__, ret);
12999 goto error;
13000 }
13001
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013002 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
13003 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013004 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013005 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013006 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013007 }
13008
13009 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070013010
13011error:
Atul Mittal115287b2014-07-08 13:26:33 +053013012 wlan_hdd_tdls_set_link_status(pAdapter,
13013 mac,
13014 eTDLS_LINK_IDLE,
13015 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013016 return -EPERM;
13017
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013018}
13019#endif
13020
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013021VOS_STATUS wlan_hdd_send_sta_authorized_event(
13022 hdd_adapter_t *adapter,
13023 hdd_context_t *hdd_ctx,
13024 const v_MACADDR_t *mac_addr)
13025{
13026 struct sk_buff *vendor_event;
13027 uint32_t sta_flags = 0;
13028 VOS_STATUS status;
13029
13030 ENTER();
13031
13032 if (!hdd_ctx) {
13033 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null"));
13034 return -EINVAL;
13035 }
13036
13037 vendor_event =
13038 cfg80211_vendor_event_alloc(
Ashish Kumar Dhanotiyac99fbef2018-04-11 12:23:32 +053013039 hdd_ctx->wiphy,
13040#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
13041 &adapter->wdev,
13042#endif
13043 sizeof(sta_flags) +
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013044 VOS_MAC_ADDR_SIZE + NLMSG_HDRLEN,
13045 QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX,
13046 GFP_KERNEL);
13047 if (!vendor_event) {
13048 hddLog(VOS_TRACE_LEVEL_ERROR,
13049 FL("cfg80211_vendor_event_alloc failed"));
13050 return -EINVAL;
13051 }
13052
13053 sta_flags |= BIT(NL80211_STA_FLAG_AUTHORIZED);
13054
13055 status = nla_put_u32(vendor_event,
13056 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS,
13057 sta_flags);
13058 if (status) {
13059 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA flag put fails"));
13060 kfree_skb(vendor_event);
13061 return VOS_STATUS_E_FAILURE;
13062 }
13063 status = nla_put(vendor_event,
13064 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_MAC,
13065 VOS_MAC_ADDR_SIZE, mac_addr->bytes);
13066 if (status) {
13067 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA MAC put fails"));
13068 kfree_skb(vendor_event);
13069 return VOS_STATUS_E_FAILURE;
13070 }
13071
13072 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
13073
13074 EXIT();
13075 return 0;
13076}
13077
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013078static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013079 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013080#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13081 const u8 *mac,
13082#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013083 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013084#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013085 struct station_parameters *params)
13086{
13087 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013088 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013089 hdd_context_t *pHddCtx;
13090 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013091 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013092 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013093#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013094 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013095 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013096 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013097 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013098#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013099
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013100 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013101
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013102 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013103 if ((NULL == pAdapter))
13104 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013106 "invalid adapter ");
13107 return -EINVAL;
13108 }
13109
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013110 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13111 TRACE_CODE_HDD_CHANGE_STATION,
13112 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053013113 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013114
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013115 ret = wlan_hdd_validate_context(pHddCtx);
13116 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053013117 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013118 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013119 }
13120
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013121 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13122
13123 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013124 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013125 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13126 "invalid HDD station context");
13127 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013128 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013129 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
13130
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013131 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
13132 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070013133 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013134 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070013135 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013136 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070013137 WLANTL_STA_AUTHENTICATED);
13138
Gopichand Nakkala29149562013-05-10 21:43:41 +053013139 if (status != VOS_STATUS_SUCCESS)
13140 {
13141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13142 "%s: Not able to change TL state to AUTHENTICATED", __func__);
13143 return -EINVAL;
13144 }
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013145 status = wlan_hdd_send_sta_authorized_event(pAdapter, pHddCtx,
13146 &STAMacAddress);
13147 if (status != VOS_STATUS_SUCCESS)
13148 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013149 }
13150 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070013151 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
13152 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013153#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013154 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13155 StaParams.capability = params->capability;
13156 StaParams.uapsd_queues = params->uapsd_queues;
13157 StaParams.max_sp = params->max_sp;
13158
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013159 /* Convert (first channel , number of channels) tuple to
13160 * the total list of channels. This goes with the assumption
13161 * that if the first channel is < 14, then the next channels
13162 * are an incremental of 1 else an incremental of 4 till the number
13163 * of channels.
13164 */
13165 if (0 != params->supported_channels_len) {
13166 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013167 for ( i = 0 ; i < params->supported_channels_len
13168 && j < SIR_MAC_MAX_SUPP_CHANNELS; i+=2)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013169 {
13170 int wifi_chan_index;
13171 StaParams.supported_channels[j] = params->supported_channels[i];
13172 wifi_chan_index =
13173 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
13174 no_of_channels = params->supported_channels[i+1];
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013175 for(k=1; k <= no_of_channels
13176 && j < SIR_MAC_MAX_SUPP_CHANNELS - 1; k++)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013177 {
13178 StaParams.supported_channels[j+1] =
13179 StaParams.supported_channels[j] + wifi_chan_index;
13180 j+=1;
13181 }
13182 }
13183 StaParams.supported_channels_len = j;
13184 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053013185 if (params->supported_oper_classes_len >
13186 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
13187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13188 "received oper classes:%d, resetting it to max supported %d",
13189 params->supported_oper_classes_len,
13190 SIR_MAC_MAX_SUPP_OPER_CLASSES);
13191 params->supported_oper_classes_len =
13192 SIR_MAC_MAX_SUPP_OPER_CLASSES;
13193 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013194 vos_mem_copy(StaParams.supported_oper_classes,
13195 params->supported_oper_classes,
13196 params->supported_oper_classes_len);
13197 StaParams.supported_oper_classes_len =
13198 params->supported_oper_classes_len;
13199
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013200 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
13201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13202 "received extn capabilities:%d, resetting it to max supported",
13203 params->ext_capab_len);
13204 params->ext_capab_len = sizeof(StaParams.extn_capability);
13205 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013206 if (0 != params->ext_capab_len)
13207 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013208 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013209
13210 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013211 {
13212 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013213 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013214 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013215
13216 StaParams.supported_rates_len = params->supported_rates_len;
13217
13218 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
13219 * The supported_rates array , for all the structures propogating till Add Sta
13220 * to the firmware has to be modified , if the supplicant (ieee80211) is
13221 * modified to send more rates.
13222 */
13223
13224 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
13225 */
13226 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
13227 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
13228
13229 if (0 != StaParams.supported_rates_len) {
13230 int i = 0;
13231 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
13232 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013233 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013234 "Supported Rates with Length %d", StaParams.supported_rates_len);
13235 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013236 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013237 "[%d]: %0x", i, StaParams.supported_rates[i]);
13238 }
13239
13240 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013241 {
13242 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013243 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013244 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013245
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013246 if (0 != params->ext_capab_len ) {
13247 /*Define A Macro : TODO Sunil*/
13248 if ((1<<4) & StaParams.extn_capability[3]) {
13249 isBufSta = 1;
13250 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013251 /* TDLS Channel Switching Support */
13252 if ((1<<6) & StaParams.extn_capability[3]) {
13253 isOffChannelSupported = 1;
13254 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013255 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013256
13257 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053013258 (params->ht_capa || params->vht_capa ||
13259 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013260 /* TDLS Peer is WME/QoS capable */
13261 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013262
13263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13264 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
13265 __func__, isQosWmmSta, StaParams.htcap_present);
13266
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013267 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
13268 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013269 isOffChannelSupported,
13270 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013271
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013272 if (VOS_STATUS_SUCCESS != status) {
13273 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13274 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
13275 return -EINVAL;
13276 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013277 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
13278
13279 if (VOS_STATUS_SUCCESS != status) {
13280 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13281 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
13282 return -EINVAL;
13283 }
13284 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013285#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053013286 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013287 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013288 return status;
13289}
13290
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013291#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13292static int wlan_hdd_change_station(struct wiphy *wiphy,
13293 struct net_device *dev,
13294 const u8 *mac,
13295 struct station_parameters *params)
13296#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013297static int wlan_hdd_change_station(struct wiphy *wiphy,
13298 struct net_device *dev,
13299 u8 *mac,
13300 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013301#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013302{
13303 int ret;
13304
13305 vos_ssr_protect(__func__);
13306 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
13307 vos_ssr_unprotect(__func__);
13308
13309 return ret;
13310}
13311
Jeff Johnson295189b2012-06-20 16:38:30 -070013312/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013313 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013314 * This function is used to initialize the key information
13315 */
13316#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013317static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013318 struct net_device *ndev,
13319 u8 key_index, bool pairwise,
13320 const u8 *mac_addr,
13321 struct key_params *params
13322 )
13323#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013324static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013325 struct net_device *ndev,
13326 u8 key_index, const u8 *mac_addr,
13327 struct key_params *params
13328 )
13329#endif
13330{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013331 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013332 tCsrRoamSetKey setKey;
13333 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013334 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013335 v_U32_t roamId= 0xFF;
13336 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013337 hdd_hostapd_state_t *pHostapdState;
13338 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013339 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013340 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013341 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013342 v_MACADDR_t *peerMacAddr;
13343 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013344 uint8_t staid = HDD_MAX_STA_COUNT;
13345 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013346
13347 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013348
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013349 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13350 TRACE_CODE_HDD_CFG80211_ADD_KEY,
13351 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013352 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13353 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013354 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013355 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013356 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013357 }
13358
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013359 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13360 __func__, hdd_device_modetoString(pAdapter->device_mode),
13361 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013362
13363 if (CSR_MAX_NUM_KEY <= key_index)
13364 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013365 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013366 key_index);
13367
13368 return -EINVAL;
13369 }
13370
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013371 if (CSR_MAX_KEY_LEN < params->key_len)
13372 {
13373 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
13374 params->key_len);
13375
13376 return -EINVAL;
13377 }
13378
Jingxiang Gec438aea2017-10-26 16:44:00 +080013379 if (CSR_MAX_RSC_LEN < params->seq_len)
13380 {
13381 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
13382 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053013383
13384 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080013385 }
13386
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013387 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080013388 "%s: called with key index = %d & key length %d & seq length %d",
13389 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013390
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013391 peerMacAddr = (v_MACADDR_t *)mac_addr;
13392
Jeff Johnson295189b2012-06-20 16:38:30 -070013393 /*extract key idx, key len and key*/
13394 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13395 setKey.keyId = key_index;
13396 setKey.keyLength = params->key_len;
13397 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080013398 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013399
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013400 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013401 {
13402 case WLAN_CIPHER_SUITE_WEP40:
13403 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13404 break;
13405
13406 case WLAN_CIPHER_SUITE_WEP104:
13407 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
13408 break;
13409
13410 case WLAN_CIPHER_SUITE_TKIP:
13411 {
13412 u8 *pKey = &setKey.Key[0];
13413 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
13414
13415 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
13416
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013417 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070013418
13419 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013420 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013421 |--------------|----------|----------|
13422 <---16bytes---><--8bytes--><--8bytes-->
13423
13424 */
13425 /*Sme expects the 32 bytes key to be in the below order
13426
13427 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013428 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013429 |--------------|----------|----------|
13430 <---16bytes---><--8bytes--><--8bytes-->
13431 */
13432 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013433 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070013434
13435 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013436 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013437
13438 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013439 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013440
13441
13442 break;
13443 }
13444
13445 case WLAN_CIPHER_SUITE_CCMP:
13446 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
13447 break;
13448
13449#ifdef FEATURE_WLAN_WAPI
13450 case WLAN_CIPHER_SUITE_SMS4:
13451 {
13452 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13453 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
13454 params->key, params->key_len);
13455 return 0;
13456 }
13457#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013458
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013459#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013460 case WLAN_CIPHER_SUITE_KRK:
13461 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
13462 break;
13463#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013464
13465#ifdef WLAN_FEATURE_11W
13466 case WLAN_CIPHER_SUITE_AES_CMAC:
13467 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070013468 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070013469#endif
13470
Jeff Johnson295189b2012-06-20 16:38:30 -070013471 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013472 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070013473 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013474 status = -EOPNOTSUPP;
13475 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013476 }
13477
13478 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
13479 __func__, setKey.encType);
13480
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013481 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070013482#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13483 (!pairwise)
13484#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013485 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013486#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013487 )
13488 {
13489 /* set group key*/
13490 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13491 "%s- %d: setting Broadcast key",
13492 __func__, __LINE__);
13493 setKey.keyDirection = eSIR_RX_ONLY;
13494 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13495 }
13496 else
13497 {
13498 /* set pairwise key*/
13499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13500 "%s- %d: setting pairwise key",
13501 __func__, __LINE__);
13502 setKey.keyDirection = eSIR_TX_RX;
13503 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013504 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013505 }
13506 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
13507 {
13508 setKey.keyDirection = eSIR_TX_RX;
13509 /*Set the group key*/
13510 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13511 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070013512
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013513 if ( 0 != status )
13514 {
13515 hddLog(VOS_TRACE_LEVEL_ERROR,
13516 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013517 status = -EINVAL;
13518 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013519 }
13520 /*Save the keys here and call sme_RoamSetKey for setting
13521 the PTK after peer joins the IBSS network*/
13522 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
13523 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013524 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013525 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053013526 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
13527 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
13528 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013529 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013530 if( pHostapdState->bssState == BSS_START )
13531 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013532 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13533 vos_status = wlan_hdd_check_ula_done(pAdapter);
13534
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013535 if (peerMacAddr && (pairwise_set_key == true))
13536 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013537
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013538 if ( vos_status != VOS_STATUS_SUCCESS )
13539 {
13540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13541 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13542 __LINE__, vos_status );
13543
13544 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13545
13546 status = -EINVAL;
13547 goto end;
13548 }
13549
Jeff Johnson295189b2012-06-20 16:38:30 -070013550 status = WLANSAP_SetKeySta( pVosContext, &setKey);
13551
13552 if ( status != eHAL_STATUS_SUCCESS )
13553 {
13554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13555 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13556 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013557 status = -EINVAL;
13558 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013559 }
13560 }
13561
13562 /* Saving WEP keys */
13563 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
13564 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
13565 {
13566 //Save the wep key in ap context. Issue setkey after the BSS is started.
13567 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13568 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
13569 }
13570 else
13571 {
13572 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013573 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013574 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
13575 }
13576 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013577 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
13578 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013579 {
13580 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13581 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13582
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013583#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13584 if (!pairwise)
13585#else
13586 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
13587#endif
13588 {
13589 /* set group key*/
13590 if (pHddStaCtx->roam_info.deferKeyComplete)
13591 {
13592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13593 "%s- %d: Perform Set key Complete",
13594 __func__, __LINE__);
13595 hdd_PerformRoamSetKeyComplete(pAdapter);
13596 }
13597 }
13598
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013599 if (pairwise_set_key == true)
13600 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013601
Jeff Johnson295189b2012-06-20 16:38:30 -070013602 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
13603
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080013604 pWextState->roamProfile.Keys.defaultIndex = key_index;
13605
13606
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013607 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013608 params->key, params->key_len);
13609
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013610
Jeff Johnson295189b2012-06-20 16:38:30 -070013611 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13612
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013613 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013614 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013615 __func__, setKey.peerMac[0], setKey.peerMac[1],
13616 setKey.peerMac[2], setKey.peerMac[3],
13617 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013618 setKey.keyDirection);
13619
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013620 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053013621
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013622 if ( vos_status != VOS_STATUS_SUCCESS )
13623 {
13624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013625 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13626 __LINE__, vos_status );
13627
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013628 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013629
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013630 status = -EINVAL;
13631 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013632
13633 }
13634
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013635#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013636 /* The supplicant may attempt to set the PTK once pre-authentication
13637 is done. Save the key in the UMAC and include it in the ADD BSS
13638 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013639 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013640 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013641 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013642 hddLog(VOS_TRACE_LEVEL_INFO_MED,
13643 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013644 status = 0;
13645 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013646 }
13647 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
13648 {
13649 hddLog(VOS_TRACE_LEVEL_ERROR,
13650 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013651 status = -EINVAL;
13652 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013653 }
13654#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070013655
13656 /* issue set key request to SME*/
13657 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13658 pAdapter->sessionId, &setKey, &roamId );
13659
13660 if ( 0 != status )
13661 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013662 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013663 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
13664 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013665 status = -EINVAL;
13666 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013667 }
13668
13669
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013670 /* in case of IBSS as there was no information available about WEP keys during
13671 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070013672 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013673 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
13674 !( ( IW_AUTH_KEY_MGMT_802_1X
13675 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070013676 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
13677 )
13678 &&
13679 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
13680 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
13681 )
13682 )
13683 {
13684 setKey.keyDirection = eSIR_RX_ONLY;
13685 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13686
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013687 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013688 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013689 __func__, setKey.peerMac[0], setKey.peerMac[1],
13690 setKey.peerMac[2], setKey.peerMac[3],
13691 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013692 setKey.keyDirection);
13693
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013694 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013695 pAdapter->sessionId, &setKey, &roamId );
13696
13697 if ( 0 != status )
13698 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013699 hddLog(VOS_TRACE_LEVEL_ERROR,
13700 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013701 __func__, status);
13702 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013703 status = -EINVAL;
13704 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013705 }
13706 }
13707 }
13708
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013709 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013710 for (i = 0; i < params->seq_len; i++) {
13711 rsc_counter |= (params->seq[i] << i*8);
13712 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013713 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
13714 }
13715
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013716end:
13717 /* Need to clear any trace of key value in the memory.
13718 * Thus zero out the memory even though it is local
13719 * variable.
13720 */
13721 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013722 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013723 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013724}
13725
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013726#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13727static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13728 struct net_device *ndev,
13729 u8 key_index, bool pairwise,
13730 const u8 *mac_addr,
13731 struct key_params *params
13732 )
13733#else
13734static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13735 struct net_device *ndev,
13736 u8 key_index, const u8 *mac_addr,
13737 struct key_params *params
13738 )
13739#endif
13740{
13741 int ret;
13742 vos_ssr_protect(__func__);
13743#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13744 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
13745 mac_addr, params);
13746#else
13747 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
13748 params);
13749#endif
13750 vos_ssr_unprotect(__func__);
13751
13752 return ret;
13753}
13754
Jeff Johnson295189b2012-06-20 16:38:30 -070013755/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013756 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013757 * This function is used to get the key information
13758 */
13759#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013760static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013761 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013762 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013763 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013764 const u8 *mac_addr, void *cookie,
13765 void (*callback)(void *cookie, struct key_params*)
13766 )
13767#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013768static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013769 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013770 struct net_device *ndev,
13771 u8 key_index, const u8 *mac_addr, void *cookie,
13772 void (*callback)(void *cookie, struct key_params*)
13773 )
13774#endif
13775{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013776 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013777 hdd_wext_state_t *pWextState = NULL;
13778 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013779 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013780 hdd_context_t *pHddCtx;
13781 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013782
13783 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013784
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013785 if (NULL == pAdapter)
13786 {
13787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13788 "%s: HDD adapter is Null", __func__);
13789 return -ENODEV;
13790 }
13791
13792 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13793 ret = wlan_hdd_validate_context(pHddCtx);
13794 if (0 != ret)
13795 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013796 return ret;
13797 }
13798
13799 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13800 pRoamProfile = &(pWextState->roamProfile);
13801
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013802 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13803 __func__, hdd_device_modetoString(pAdapter->device_mode),
13804 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013805
Jeff Johnson295189b2012-06-20 16:38:30 -070013806 memset(&params, 0, sizeof(params));
13807
13808 if (CSR_MAX_NUM_KEY <= key_index)
13809 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013810 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013811 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013812 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013813
13814 switch(pRoamProfile->EncryptionType.encryptionType[0])
13815 {
13816 case eCSR_ENCRYPT_TYPE_NONE:
13817 params.cipher = IW_AUTH_CIPHER_NONE;
13818 break;
13819
13820 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13821 case eCSR_ENCRYPT_TYPE_WEP40:
13822 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13823 break;
13824
13825 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13826 case eCSR_ENCRYPT_TYPE_WEP104:
13827 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13828 break;
13829
13830 case eCSR_ENCRYPT_TYPE_TKIP:
13831 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13832 break;
13833
13834 case eCSR_ENCRYPT_TYPE_AES:
13835 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13836 break;
13837
13838 default:
13839 params.cipher = IW_AUTH_CIPHER_NONE;
13840 break;
13841 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013842
c_hpothuaaf19692014-05-17 17:01:48 +053013843 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13844 TRACE_CODE_HDD_CFG80211_GET_KEY,
13845 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013846
Jeff Johnson295189b2012-06-20 16:38:30 -070013847 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13848 params.seq_len = 0;
13849 params.seq = NULL;
13850 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13851 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013852 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013853 return 0;
13854}
13855
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013856#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13857static int wlan_hdd_cfg80211_get_key(
13858 struct wiphy *wiphy,
13859 struct net_device *ndev,
13860 u8 key_index, bool pairwise,
13861 const u8 *mac_addr, void *cookie,
13862 void (*callback)(void *cookie, struct key_params*)
13863 )
13864#else
13865static int wlan_hdd_cfg80211_get_key(
13866 struct wiphy *wiphy,
13867 struct net_device *ndev,
13868 u8 key_index, const u8 *mac_addr, void *cookie,
13869 void (*callback)(void *cookie, struct key_params*)
13870 )
13871#endif
13872{
13873 int ret;
13874
13875 vos_ssr_protect(__func__);
13876#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13877 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13878 mac_addr, cookie, callback);
13879#else
13880 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13881 callback);
13882#endif
13883 vos_ssr_unprotect(__func__);
13884
13885 return ret;
13886}
13887
Jeff Johnson295189b2012-06-20 16:38:30 -070013888/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013889 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013890 * This function is used to delete the key information
13891 */
13892#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013893static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013894 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013895 u8 key_index,
13896 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013897 const u8 *mac_addr
13898 )
13899#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013900static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013901 struct net_device *ndev,
13902 u8 key_index,
13903 const u8 *mac_addr
13904 )
13905#endif
13906{
13907 int status = 0;
13908
13909 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013910 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013911 //it is observed that this is invalidating peer
13912 //key index whenever re-key is done. This is affecting data link.
13913 //It should be ok to ignore del_key.
13914#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013915 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13916 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013917 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13918 tCsrRoamSetKey setKey;
13919 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013920
Jeff Johnson295189b2012-06-20 16:38:30 -070013921 ENTER();
13922
13923 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13924 __func__,pAdapter->device_mode);
13925
13926 if (CSR_MAX_NUM_KEY <= key_index)
13927 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013928 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013929 key_index);
13930
13931 return -EINVAL;
13932 }
13933
13934 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13935 setKey.keyId = key_index;
13936
13937 if (mac_addr)
13938 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13939 else
13940 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13941
13942 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13943
13944 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013945 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013946 )
13947 {
13948
13949 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013950 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13951 if( pHostapdState->bssState == BSS_START)
13952 {
13953 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013954
Jeff Johnson295189b2012-06-20 16:38:30 -070013955 if ( status != eHAL_STATUS_SUCCESS )
13956 {
13957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13958 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13959 __LINE__, status );
13960 }
13961 }
13962 }
13963 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013964 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013965 )
13966 {
13967 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13968
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013969 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13970
13971 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013972 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013973 __func__, setKey.peerMac[0], setKey.peerMac[1],
13974 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013975 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013976 if(pAdapter->sessionCtx.station.conn_info.connState ==
13977 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013978 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013979 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013980 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013981
Jeff Johnson295189b2012-06-20 16:38:30 -070013982 if ( 0 != status )
13983 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013984 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013985 "%s: sme_RoamSetKey failure, returned %d",
13986 __func__, status);
13987 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13988 return -EINVAL;
13989 }
13990 }
13991 }
13992#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013993 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013994 return status;
13995}
13996
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013997#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13998static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13999 struct net_device *ndev,
14000 u8 key_index,
14001 bool pairwise,
14002 const u8 *mac_addr
14003 )
14004#else
14005static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
14006 struct net_device *ndev,
14007 u8 key_index,
14008 const u8 *mac_addr
14009 )
14010#endif
14011{
14012 int ret;
14013
14014 vos_ssr_protect(__func__);
14015#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14016 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
14017 mac_addr);
14018#else
14019 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
14020#endif
14021 vos_ssr_unprotect(__func__);
14022
14023 return ret;
14024}
14025
Jeff Johnson295189b2012-06-20 16:38:30 -070014026/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014027 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070014028 * This function is used to set the default tx key index
14029 */
14030#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014031static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014032 struct net_device *ndev,
14033 u8 key_index,
14034 bool unicast, bool multicast)
14035#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014036static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014037 struct net_device *ndev,
14038 u8 key_index)
14039#endif
14040{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014041 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014042 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053014043 hdd_wext_state_t *pWextState;
14044 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014045 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014046
14047 ENTER();
14048
Gopichand Nakkala29149562013-05-10 21:43:41 +053014049 if ((NULL == pAdapter))
14050 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053014052 "invalid adapter");
14053 return -EINVAL;
14054 }
14055
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014056 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14057 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
14058 pAdapter->sessionId, key_index));
14059
Gopichand Nakkala29149562013-05-10 21:43:41 +053014060 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14061 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14062
14063 if ((NULL == pWextState) || (NULL == pHddStaCtx))
14064 {
14065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14066 "invalid Wext state or HDD context");
14067 return -EINVAL;
14068 }
14069
Arif Hussain6d2a3322013-11-17 19:50:10 -080014070 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014071 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014072
Jeff Johnson295189b2012-06-20 16:38:30 -070014073 if (CSR_MAX_NUM_KEY <= key_index)
14074 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014075 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014076 key_index);
14077
14078 return -EINVAL;
14079 }
14080
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014081 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14082 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014083 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014084 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014085 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014086 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014087
Jeff Johnson295189b2012-06-20 16:38:30 -070014088 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070014089 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014090 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014091 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053014092 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080014093 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080014094#ifdef FEATURE_WLAN_WAPI
14095 (eCSR_ENCRYPT_TYPE_WPI !=
14096 pHddStaCtx->conn_info.ucEncryptionType) &&
14097#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014098 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080014099 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070014100 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014101 {
14102 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070014103 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014104
Jeff Johnson295189b2012-06-20 16:38:30 -070014105 tCsrRoamSetKey setKey;
14106 v_U32_t roamId= 0xFF;
14107 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014108
14109 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014110 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014111
Jeff Johnson295189b2012-06-20 16:38:30 -070014112 Keys->defaultIndex = (u8)key_index;
14113 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
14114 setKey.keyId = key_index;
14115 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014116
14117 vos_mem_copy(&setKey.Key[0],
14118 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014119 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014120
Gopichand Nakkala29149562013-05-10 21:43:41 +053014121 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014122
14123 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070014124 &pHddStaCtx->conn_info.bssId[0],
14125 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014126
Gopichand Nakkala29149562013-05-10 21:43:41 +053014127 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
14128 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
14129 eCSR_ENCRYPT_TYPE_WEP104)
14130 {
14131 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
14132 even though ap is configured for WEP-40 encryption. In this canse the key length
14133 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
14134 type(104) and switching encryption type to 40*/
14135 pWextState->roamProfile.EncryptionType.encryptionType[0] =
14136 eCSR_ENCRYPT_TYPE_WEP40;
14137 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
14138 eCSR_ENCRYPT_TYPE_WEP40;
14139 }
14140
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014141 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014142 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014143
Jeff Johnson295189b2012-06-20 16:38:30 -070014144 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014145 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014146 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014147
Jeff Johnson295189b2012-06-20 16:38:30 -070014148 if ( 0 != status )
14149 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014150 hddLog(VOS_TRACE_LEVEL_ERROR,
14151 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014152 status);
14153 return -EINVAL;
14154 }
14155 }
14156 }
14157
14158 /* In SoftAp mode setting key direction for default mode */
14159 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
14160 {
14161 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
14162 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
14163 (eCSR_ENCRYPT_TYPE_AES !=
14164 pWextState->roamProfile.EncryptionType.encryptionType[0])
14165 )
14166 {
14167 /* Saving key direction for default key index to TX default */
14168 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
14169 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
14170 }
14171 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014172 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014173 return status;
14174}
14175
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014176#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14177static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14178 struct net_device *ndev,
14179 u8 key_index,
14180 bool unicast, bool multicast)
14181#else
14182static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14183 struct net_device *ndev,
14184 u8 key_index)
14185#endif
14186{
14187 int ret;
14188 vos_ssr_protect(__func__);
14189#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14190 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
14191 multicast);
14192#else
14193 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
14194#endif
14195 vos_ssr_unprotect(__func__);
14196
14197 return ret;
14198}
14199
Jeff Johnson295189b2012-06-20 16:38:30 -070014200/*
14201 * FUNCTION: wlan_hdd_cfg80211_inform_bss
14202 * This function is used to inform the BSS details to nl80211 interface.
14203 */
14204static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
14205 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
14206{
14207 struct net_device *dev = pAdapter->dev;
14208 struct wireless_dev *wdev = dev->ieee80211_ptr;
14209 struct wiphy *wiphy = wdev->wiphy;
14210 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
14211 int chan_no;
14212 int ie_length;
14213 const char *ie;
14214 unsigned int freq;
14215 struct ieee80211_channel *chan;
14216 int rssi = 0;
14217 struct cfg80211_bss *bss = NULL;
14218
Jeff Johnson295189b2012-06-20 16:38:30 -070014219 if( NULL == pBssDesc )
14220 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014221 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014222 return bss;
14223 }
14224
14225 chan_no = pBssDesc->channelId;
14226 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
14227 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
14228
14229 if( NULL == ie )
14230 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014231 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014232 return bss;
14233 }
14234
14235#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
14236 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
14237 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014238 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014239 }
14240 else
14241 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014242 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014243 }
14244#else
14245 freq = ieee80211_channel_to_frequency(chan_no);
14246#endif
14247
14248 chan = __ieee80211_get_channel(wiphy, freq);
14249
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053014250 if (!chan) {
14251 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
14252 return NULL;
14253 }
14254
Abhishek Singhaee43942014-06-16 18:55:47 +053014255 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070014256
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014257 return cfg80211_inform_bss(wiphy, chan,
14258#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14259 CFG80211_BSS_FTYPE_UNKNOWN,
14260#endif
14261 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014262 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070014263 pBssDesc->capabilityInfo,
14264 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053014265 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070014266}
14267
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014268/*
14269 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
14270 * interface that BSS might have been lost.
14271 * @pAdapter: adaptor
14272 * @bssid: bssid which might have been lost
14273 *
14274 * Return: bss which is unlinked from kernel cache
14275 */
14276struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
14277 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
14278{
14279 struct net_device *dev = pAdapter->dev;
14280 struct wireless_dev *wdev = dev->ieee80211_ptr;
14281 struct wiphy *wiphy = wdev->wiphy;
14282 struct cfg80211_bss *bss = NULL;
14283
Abhishek Singh5a597e62016-12-05 15:16:30 +053014284 bss = hdd_get_bss_entry(wiphy,
14285 NULL, bssid,
14286 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014287 if (bss == NULL) {
14288 hddLog(LOGE, FL("BSS not present"));
14289 } else {
14290 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
14291 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
14292 cfg80211_unlink_bss(wiphy, bss);
14293 }
14294 return bss;
14295}
Jeff Johnson295189b2012-06-20 16:38:30 -070014296
14297
14298/*
14299 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
14300 * This function is used to inform the BSS details to nl80211 interface.
14301 */
14302struct cfg80211_bss*
14303wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
14304 tSirBssDescription *bss_desc
14305 )
14306{
14307 /*
14308 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
14309 already exists in bss data base of cfg80211 for that particular BSS ID.
14310 Using cfg80211_inform_bss_frame to update the bss entry instead of
14311 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
14312 now there is no possibility to get the mgmt(probe response) frame from PE,
14313 converting bss_desc to ieee80211_mgmt(probe response) and passing to
14314 cfg80211_inform_bss_frame.
14315 */
14316 struct net_device *dev = pAdapter->dev;
14317 struct wireless_dev *wdev = dev->ieee80211_ptr;
14318 struct wiphy *wiphy = wdev->wiphy;
14319 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014320#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14321 qcom_ie_age *qie_age = NULL;
14322 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
14323#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014324 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014325#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014326 const char *ie =
14327 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
14328 unsigned int freq;
14329 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014330 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014331 struct cfg80211_bss *bss_status = NULL;
Hanumanth Reddy Pothulae04e06c2018-05-31 14:41:36 +053014332 size_t frame_len = ie_length + offsetof(struct ieee80211_mgmt,
14333 u.probe_resp.variable);
Jeff Johnson295189b2012-06-20 16:38:30 -070014334 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070014335 hdd_context_t *pHddCtx;
14336 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070014337#ifdef WLAN_OPEN_SOURCE
14338 struct timespec ts;
14339#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014340
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014341
Wilson Yangf80a0542013-10-07 13:02:37 -070014342 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14343 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070014344 if (0 != status)
14345 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014346 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014347 }
14348
Hanumanth Reddy Pothula33548e22018-05-31 13:28:51 +053014349 mgmt = kzalloc(frame_len, GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070014350 if (!mgmt)
14351 {
14352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14353 "%s: memory allocation failed ", __func__);
14354 return NULL;
14355 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014356
Jeff Johnson295189b2012-06-20 16:38:30 -070014357 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014358
14359#ifdef WLAN_OPEN_SOURCE
14360 /* Android does not want the timestamp from the frame.
14361 Instead it wants a monotonic increasing value */
14362 get_monotonic_boottime(&ts);
14363 mgmt->u.probe_resp.timestamp =
14364 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
14365#else
14366 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014367 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
14368 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070014369
14370#endif
14371
Jeff Johnson295189b2012-06-20 16:38:30 -070014372 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
14373 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014374
14375#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14376 /* GPS Requirement: need age ie per entry. Using vendor specific. */
14377 /* Assuming this is the last IE, copy at the end */
14378 ie_length -=sizeof(qcom_ie_age);
14379 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
14380 qie_age->element_id = QCOM_VENDOR_IE_ID;
14381 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
14382 qie_age->oui_1 = QCOM_OUI1;
14383 qie_age->oui_2 = QCOM_OUI2;
14384 qie_age->oui_3 = QCOM_OUI3;
14385 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053014386 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
14387 * bss related timestamp is in units of ms. Due to this when scan results
14388 * are sent to lowi the scan age is high.To address this, send age in units
14389 * of 1/10 ms.
14390 */
14391 qie_age->age = (vos_timer_get_system_time() -
14392 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014393#endif
14394
Jeff Johnson295189b2012-06-20 16:38:30 -070014395 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053014396 if (bss_desc->fProbeRsp)
14397 {
14398 mgmt->frame_control |=
14399 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
14400 }
14401 else
14402 {
14403 mgmt->frame_control |=
14404 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
14405 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014406
14407#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014408 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014409 (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014410 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014411 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014412 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014413 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014414 (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014415
14416 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014417 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014418 }
14419 else
14420 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014421 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
14422 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070014423 kfree(mgmt);
14424 return NULL;
14425 }
14426#else
14427 freq = ieee80211_channel_to_frequency(chan_no);
14428#endif
14429 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014430 /*when the band is changed on the fly using the GUI, three things are done
14431 * 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)
14432 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
14433 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
14434 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
14435 * and discards the channels correponding to previous band and calls back with zero bss results.
14436 * 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
14437 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
14438 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
14439 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
14440 * So drop the bss and continue to next bss.
14441 */
14442 if(chan == NULL)
14443 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053014444 hddLog(VOS_TRACE_LEVEL_ERROR,
14445 FL("chan pointer is NULL, chan_no: %d freq: %d"),
14446 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070014447 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014448 return NULL;
14449 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053014450 /*To keep the rssi icon of the connected AP in the scan window
14451 *and the rssi icon of the wireless networks in sync
14452 * */
14453 if (( eConnectionState_Associated ==
14454 pAdapter->sessionCtx.station.conn_info.connState ) &&
14455 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
14456 pAdapter->sessionCtx.station.conn_info.bssId,
14457 WNI_CFG_BSSID_LEN)) &&
14458 (pHddCtx->hdd_wlan_suspended == FALSE))
14459 {
14460 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
14461 rssi = (pAdapter->rssi * 100);
14462 }
14463 else
14464 {
14465 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
14466 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014467
Nirav Shah20ac06f2013-12-12 18:14:06 +053014468 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053014469 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
14470 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053014471
Jeff Johnson295189b2012-06-20 16:38:30 -070014472 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
14473 frame_len, rssi, GFP_KERNEL);
14474 kfree(mgmt);
14475 return bss_status;
14476}
14477
14478/*
14479 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
14480 * This function is used to update the BSS data base of CFG8011
14481 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014482struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014483 tCsrRoamInfo *pRoamInfo
14484 )
14485{
14486 tCsrRoamConnectedProfile roamProfile;
14487 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14488 struct cfg80211_bss *bss = NULL;
14489
14490 ENTER();
14491
14492 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
14493 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
14494
14495 if (NULL != roamProfile.pBssDesc)
14496 {
Girish Gowlif4b68022014-08-28 23:18:57 +053014497 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14498 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070014499
14500 if (NULL == bss)
14501 {
14502 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
14503 __func__);
14504 }
14505
14506 sme_RoamFreeConnectProfile(hHal, &roamProfile);
14507 }
14508 else
14509 {
14510 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
14511 __func__);
14512 }
14513 return bss;
14514}
14515
14516/*
14517 * FUNCTION: wlan_hdd_cfg80211_update_bss
14518 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014519static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
14520 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070014521 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014522{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014523 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014524 tCsrScanResultInfo *pScanResult;
14525 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014526 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014527 tScanResultHandle pResult;
14528 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014529 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014530 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070014531 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014532
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014533 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14534 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
14535 NO_SESSION, pAdapter->sessionId));
14536
Wilson Yangf80a0542013-10-07 13:02:37 -070014537 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014538 ret = wlan_hdd_validate_context(pHddCtx);
14539 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070014540 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014541 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070014542 }
14543
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014544 if (pAdapter->request != NULL)
14545 {
14546 if ((pAdapter->request->n_ssids == 1)
14547 && (pAdapter->request->ssids != NULL)
14548 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
14549 is_p2p_scan = true;
14550 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014551 /*
14552 * start getting scan results and populate cgf80211 BSS database
14553 */
14554 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
14555
14556 /* no scan results */
14557 if (NULL == pResult)
14558 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014559 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
14560 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014561 wlan_hdd_get_frame_logs(pAdapter,
14562 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070014563 return status;
14564 }
14565
14566 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
14567
14568 while (pScanResult)
14569 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014570 /*
14571 * cfg80211_inform_bss() is not updating ie field of bss entry, if
14572 * entry already exists in bss data base of cfg80211 for that
14573 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
14574 * bss entry instead of cfg80211_inform_bss, But this call expects
14575 * mgmt packet as input. As of now there is no possibility to get
14576 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070014577 * ieee80211_mgmt(probe response) and passing to c
14578 * fg80211_inform_bss_frame.
14579 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014580 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
14581 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
14582 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014583 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14584 continue; //Skip the non p2p bss entries
14585 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014586 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14587 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014588
Jeff Johnson295189b2012-06-20 16:38:30 -070014589
14590 if (NULL == bss_status)
14591 {
14592 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014593 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014594 }
14595 else
14596 {
Yue Maf49ba872013-08-19 12:04:25 -070014597 cfg80211_put_bss(
14598#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
14599 wiphy,
14600#endif
14601 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070014602 }
14603
14604 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14605 }
14606
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014607 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014608 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014609 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014610}
14611
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014612void
14613hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
14614{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014615 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080014616 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014617} /****** end hddPrintMacAddr() ******/
14618
14619void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014620hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014621{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014622 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014623 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014624 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
14625 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
14626 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014627} /****** end hddPrintPmkId() ******/
14628
14629//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
14630//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
14631
14632//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
14633//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
14634
14635#define dump_bssid(bssid) \
14636 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014637 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
14638 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014639 }
14640
14641#define dump_pmkid(pMac, pmkid) \
14642 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014643 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
14644 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014645 }
14646
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070014647#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014648/*
14649 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
14650 * This function is used to notify the supplicant of a new PMKSA candidate.
14651 */
14652int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014653 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014654 int index, bool preauth )
14655{
Jeff Johnsone7245742012-09-05 17:12:55 -070014656#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014657 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014658 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014659
14660 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070014661 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014662
14663 if( NULL == pRoamInfo )
14664 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014665 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014666 return -EINVAL;
14667 }
14668
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014669 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
14670 {
14671 dump_bssid(pRoamInfo->bssid);
14672 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014673 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014674 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014675#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014676 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014677}
14678#endif //FEATURE_WLAN_LFR
14679
Yue Maef608272013-04-08 23:09:17 -070014680#ifdef FEATURE_WLAN_LFR_METRICS
14681/*
14682 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
14683 * 802.11r/LFR metrics reporting function to report preauth initiation
14684 *
14685 */
14686#define MAX_LFR_METRICS_EVENT_LENGTH 100
14687VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
14688 tCsrRoamInfo *pRoamInfo)
14689{
14690 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14691 union iwreq_data wrqu;
14692
14693 ENTER();
14694
14695 if (NULL == pAdapter)
14696 {
14697 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14698 return VOS_STATUS_E_FAILURE;
14699 }
14700
14701 /* create the event */
14702 memset(&wrqu, 0, sizeof(wrqu));
14703 memset(metrics_notification, 0, sizeof(metrics_notification));
14704
14705 wrqu.data.pointer = metrics_notification;
14706 wrqu.data.length = scnprintf(metrics_notification,
14707 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
14708 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14709
14710 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14711
14712 EXIT();
14713
14714 return VOS_STATUS_SUCCESS;
14715}
14716
14717/*
14718 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
14719 * 802.11r/LFR metrics reporting function to report preauth completion
14720 * or failure
14721 */
14722VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
14723 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
14724{
14725 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14726 union iwreq_data wrqu;
14727
14728 ENTER();
14729
14730 if (NULL == pAdapter)
14731 {
14732 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14733 return VOS_STATUS_E_FAILURE;
14734 }
14735
14736 /* create the event */
14737 memset(&wrqu, 0, sizeof(wrqu));
14738 memset(metrics_notification, 0, sizeof(metrics_notification));
14739
14740 scnprintf(metrics_notification, sizeof(metrics_notification),
14741 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
14742 MAC_ADDR_ARRAY(pRoamInfo->bssid));
14743
14744 if (1 == preauth_status)
14745 strncat(metrics_notification, " TRUE", 5);
14746 else
14747 strncat(metrics_notification, " FALSE", 6);
14748
14749 wrqu.data.pointer = metrics_notification;
14750 wrqu.data.length = strlen(metrics_notification);
14751
14752 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14753
14754 EXIT();
14755
14756 return VOS_STATUS_SUCCESS;
14757}
14758
14759/*
14760 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
14761 * 802.11r/LFR metrics reporting function to report handover initiation
14762 *
14763 */
14764VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
14765 tCsrRoamInfo *pRoamInfo)
14766{
14767 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14768 union iwreq_data wrqu;
14769
14770 ENTER();
14771
14772 if (NULL == pAdapter)
14773 {
14774 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14775 return VOS_STATUS_E_FAILURE;
14776 }
14777
14778 /* create the event */
14779 memset(&wrqu, 0, sizeof(wrqu));
14780 memset(metrics_notification, 0, sizeof(metrics_notification));
14781
14782 wrqu.data.pointer = metrics_notification;
14783 wrqu.data.length = scnprintf(metrics_notification,
14784 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14785 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14786
14787 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14788
14789 EXIT();
14790
14791 return VOS_STATUS_SUCCESS;
14792}
14793#endif
14794
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014795
14796/**
14797 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14798 * @scan_req: scan request to be checked
14799 *
14800 * Return: true or false
14801 */
14802#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14803static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14804 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014805 *scan_req, hdd_context_t
14806 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014807{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014808 if (!scan_req || !scan_req->wiphy ||
14809 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014810 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14811 return false;
14812 }
14813 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14814 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14815 return false;
14816 }
14817 return true;
14818}
14819#else
14820static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14821 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014822 *scan_req, hdd_context_t
14823 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014824{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014825 if (!scan_req || !scan_req->wiphy ||
14826 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014827 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14828 return false;
14829 }
14830 return true;
14831}
14832#endif
14833
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014834#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
14835/**
14836 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14837 * @adapter: Pointer to the adapter
14838 * @req : Scan request
14839 * @aborted : true scan aborted false scan success
14840 *
14841 * This function notifies scan done to cfg80211
14842 *
14843 * Return: none
14844 */
14845static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14846 struct cfg80211_scan_request *req,
14847 bool aborted)
14848{
14849 struct cfg80211_scan_info info = {
14850 .aborted = aborted
14851 };
14852
14853 if (adapter->dev->flags & IFF_UP)
14854 cfg80211_scan_done(req, &info);
14855 else
14856 hddLog(LOGW,
14857 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14858}
14859#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14860/**
14861 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14862 * @adapter: Pointer to the adapter
14863 * @req : Scan request
14864 * @aborted : true scan aborted false scan success
14865 *
14866 * This function notifies scan done to cfg80211
14867 *
14868 * Return: none
14869 */
14870static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14871 struct cfg80211_scan_request *req,
14872 bool aborted)
14873{
14874 if (adapter->dev->flags & IFF_UP)
14875 cfg80211_scan_done(req, aborted);
14876 else
14877 hddLog(LOGW,
14878 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14879}
14880#else
14881/**
14882 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14883 * @adapter: Pointer to the adapter
14884 * @req : Scan request
14885 * @aborted : true scan aborted false scan success
14886 *
14887 * This function notifies scan done to cfg80211
14888 *
14889 * Return: none
14890 */
14891static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14892 struct cfg80211_scan_request *req,
14893 bool aborted)
14894{
14895 cfg80211_scan_done(req, aborted);
14896}
14897#endif
14898
Mukul Sharmab392b642017-08-17 17:45:29 +053014899#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014900/*
14901 * FUNCTION: hdd_cfg80211_scan_done_callback
14902 * scanning callback function, called after finishing scan
14903 *
14904 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014905static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014906 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14907{
14908 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014909 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014910 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014911 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014912 struct cfg80211_scan_request *req = NULL;
14913 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014914 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014915 long waitRet = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014916 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014917
14918 ENTER();
14919
c_manjee1b4ab9a2016-10-26 11:36:55 +053014920 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14921 !pAdapter->dev) {
14922 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14923 return 0;
14924 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014925 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014926 if (NULL == pHddCtx) {
14927 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014928 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014929 }
14930
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014931#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014932 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014933 {
14934 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014935 }
14936#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014937 pScanInfo = &pHddCtx->scan_info;
14938
Jeff Johnson295189b2012-06-20 16:38:30 -070014939 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014940 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014941 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014942 __func__, halHandle, pContext, (int) scanId, (int) status);
14943
Kiet Lamac06e2c2013-10-23 16:25:07 +053014944 pScanInfo->mScanPendingCounter = 0;
14945
Jeff Johnson295189b2012-06-20 16:38:30 -070014946 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014947 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014948 &pScanInfo->scan_req_completion_event,
14949 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014950 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014951 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014952 hddLog(VOS_TRACE_LEVEL_ERROR,
14953 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014954 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014955 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014956 }
14957
Yue Maef608272013-04-08 23:09:17 -070014958 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014959 {
14960 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014961 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014962 }
14963
14964 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014965 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014966 {
14967 hddLog(VOS_TRACE_LEVEL_INFO,
14968 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014969 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014970 (int) scanId);
14971 }
14972
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014973#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014974 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014975#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014976 {
14977 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14978 pAdapter);
14979 if (0 > ret)
14980 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014981 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014982
Jeff Johnson295189b2012-06-20 16:38:30 -070014983 /* If any client wait scan result through WEXT
14984 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014985 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014986 {
14987 /* The other scan request waiting for current scan finish
14988 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014989 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014990 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014991 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014992 }
14993 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014994 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014995 {
14996 struct net_device *dev = pAdapter->dev;
14997 union iwreq_data wrqu;
14998 int we_event;
14999 char *msg;
15000
15001 memset(&wrqu, '\0', sizeof(wrqu));
15002 we_event = SIOCGIWSCAN;
15003 msg = NULL;
15004 wireless_send_event(dev, we_event, &wrqu, msg);
15005 }
15006 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070015007 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015008
15009 /* Get the Scan Req */
15010 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053015011 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015012
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015013 /* Scan is no longer pending */
15014 pScanInfo->mScanPending = VOS_FALSE;
15015
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053015016 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070015017 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053015018#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
15019 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053015020 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053015021#endif
15022
15023 if (pAdapter->dev) {
15024 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
15025 pAdapter->dev->name);
15026 }
mukul sharmae7041822015-12-03 15:09:21 +053015027 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070015028 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070015029 }
15030
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015031 /* last_scan_timestamp is used to decide if new scan
15032 * is needed or not on station interface. If last station
15033 * scan time and new station scan time is less then
15034 * last_scan_timestamp ; driver will return cached scan.
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015035 * Also only last_scan_timestamp is updated here last_scan_channellist
15036 * is updated on receiving scan request itself to make sure kernel
15037 * allocated scan request(scan_req) object is not dereferenced here,
15038 * because interface down, where kernel frees scan_req, may happen any
15039 * time while driver is processing scan_done_callback. So it's better
15040 * not to access scan_req in this routine.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015041 */
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015042 if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
15043 if (status == eCSR_SCAN_SUCCESS)
15044 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
15045 else {
15046 vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
15047 sizeof(pHddCtx->scan_info.last_scan_channelList));
15048 pHddCtx->scan_info.last_scan_numChannels = 0;
15049 pScanInfo->last_scan_timestamp = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015050 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015051 }
15052
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070015053 /*
15054 * cfg80211_scan_done informing NL80211 about completion
15055 * of scanning
15056 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015057 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
15058 {
15059 aborted = true;
15060 }
mukul sharmae7041822015-12-03 15:09:21 +053015061
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015062#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015063 if (NET_DEV_IS_IFF_UP(pAdapter) &&
15064 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015065#endif
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015066 hdd_cfg80211_scan_done(pAdapter, req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053015067
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080015068 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070015069
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015070allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015071 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
15072 ) && (pHddCtx->spoofMacAddr.isEnabled
15073 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053015074 /* Generate new random mac addr for next scan */
15075 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053015076
15077 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
15078 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053015079 }
15080
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015081 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015082 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015083
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015084 /* Acquire wakelock to handle the case where APP's tries to suspend
15085 * immediatly after the driver gets connect request(i.e after scan)
15086 * from supplicant, this result in app's is suspending and not able
15087 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015088 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015089
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015090#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015091 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015092#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015093#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015094 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015095#endif
15096
Jeff Johnson295189b2012-06-20 16:38:30 -070015097 EXIT();
15098 return 0;
15099}
15100
15101/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053015102 * FUNCTION: hdd_isConnectionInProgress
15103 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015104 *
15105 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015106v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
15107 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015108{
15109 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15110 hdd_station_ctx_t *pHddStaCtx = NULL;
15111 hdd_adapter_t *pAdapter = NULL;
15112 VOS_STATUS status = 0;
15113 v_U8_t staId = 0;
15114 v_U8_t *staMac = NULL;
15115
15116 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15117
15118 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15119 {
15120 pAdapter = pAdapterNode->pAdapter;
15121
15122 if( pAdapter )
15123 {
15124 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015125 "%s: Adapter with device mode %s (%d) exists",
15126 __func__, hdd_device_modetoString(pAdapter->device_mode),
15127 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015128 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053015129 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15130 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
15131 (eConnectionState_Connecting ==
15132 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
15133 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015134 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015135 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053015136 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015137 if (session_id && reason)
15138 {
15139 *session_id = pAdapter->sessionId;
15140 *reason = eHDD_CONNECTION_IN_PROGRESS;
15141 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015142 return VOS_TRUE;
15143 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015144 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053015145 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015146 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015147 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015148 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015149 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015150 if (session_id && reason)
15151 {
15152 *session_id = pAdapter->sessionId;
15153 *reason = eHDD_REASSOC_IN_PROGRESS;
15154 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015155 return VOS_TRUE;
15156 }
15157 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015158 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15159 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015160 {
15161 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15162 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Vignesh Viswanathan0ac8e562018-06-14 17:24:10 +053015163 sme_is_sta_key_exchange_in_progress(pHddCtx->hHal,
15164 pAdapter->sessionId))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015165 {
15166 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015167 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015168 "%s: client " MAC_ADDRESS_STR
15169 " is in the middle of WPS/EAPOL exchange.", __func__,
15170 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015171 if (session_id && reason)
15172 {
15173 *session_id = pAdapter->sessionId;
15174 *reason = eHDD_EAPOL_IN_PROGRESS;
15175 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015176 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015177 }
15178 }
15179 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
15180 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
15181 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015182 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15183 ptSapContext pSapCtx = NULL;
15184 pSapCtx = VOS_GET_SAP_CB(pVosContext);
15185 if(pSapCtx == NULL){
15186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15187 FL("psapCtx is NULL"));
15188 return VOS_FALSE;
15189 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015190 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
15191 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015192 if ((pSapCtx->aStaInfo[staId].isUsed) &&
15193 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015194 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015195 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015196
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015197 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015198 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
15199 "middle of WPS/EAPOL exchange.", __func__,
15200 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015201 if (session_id && reason)
15202 {
15203 *session_id = pAdapter->sessionId;
15204 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
15205 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015206 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015207 }
15208 }
15209 }
15210 }
15211 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15212 pAdapterNode = pNext;
15213 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015214 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015215}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015216
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015217/**
15218 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
15219 * to the Scan request
15220 * @scanRequest: Pointer to the csr scan request
15221 * @request: Pointer to the scan request from supplicant
15222 *
15223 * Return: None
15224 */
15225#ifdef CFG80211_SCAN_BSSID
15226static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15227 struct cfg80211_scan_request *request)
15228{
15229 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
15230}
15231#else
15232static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15233 struct cfg80211_scan_request *request)
15234{
15235}
15236#endif
15237
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015238/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015239 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070015240 * this scan respond to scan trigger and update cfg80211 scan database
15241 * later, scan dump command can be used to recieve scan results
15242 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015243int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015244#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15245 struct net_device *dev,
15246#endif
15247 struct cfg80211_scan_request *request)
15248{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015249 hdd_adapter_t *pAdapter = NULL;
15250 hdd_context_t *pHddCtx = NULL;
15251 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015252 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015253 tCsrScanRequest scanRequest;
15254 tANI_U8 *channelList = NULL, i;
15255 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015256 int status;
15257 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015258 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015259 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053015260 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015261 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015262 v_U8_t curr_session_id;
15263 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070015264
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015265#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
15266 struct net_device *dev = NULL;
15267 if (NULL == request)
15268 {
15269 hddLog(VOS_TRACE_LEVEL_ERROR,
15270 "%s: scan req param null", __func__);
15271 return -EINVAL;
15272 }
15273 dev = request->wdev->netdev;
15274#endif
15275
15276 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15277 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
15278 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15279
Jeff Johnson295189b2012-06-20 16:38:30 -070015280 ENTER();
15281
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015282 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
15283 __func__, hdd_device_modetoString(pAdapter->device_mode),
15284 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015285
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015286 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015287 if (0 != status)
15288 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015289 return status;
15290 }
15291
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015292 if (NULL == pwextBuf)
15293 {
15294 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
15295 __func__);
15296 return -EIO;
15297 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015298 cfg_param = pHddCtx->cfg_ini;
15299 pScanInfo = &pHddCtx->scan_info;
15300
Jeff Johnson295189b2012-06-20 16:38:30 -070015301#ifdef WLAN_BTAMP_FEATURE
15302 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015303 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070015304 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015305 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015306 "%s: No scanning when AMP is on", __func__);
15307 return -EOPNOTSUPP;
15308 }
15309#endif
15310 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015311 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070015312 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015313 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015314 "%s: Not scanning on device_mode = %s (%d)",
15315 __func__, hdd_device_modetoString(pAdapter->device_mode),
15316 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015317 return -EOPNOTSUPP;
15318 }
15319
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015320 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
15321 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
15322 return -EOPNOTSUPP;
15323 }
15324
Jeff Johnson295189b2012-06-20 16:38:30 -070015325 if (TRUE == pScanInfo->mScanPending)
15326 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015327 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
15328 {
15329 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
15330 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015331 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015332 }
15333
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053015334 // Don't allow scan if PNO scan is going on.
15335 if (pHddCtx->isPnoEnable)
15336 {
15337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15338 FL("pno scan in progress"));
15339 return -EBUSY;
15340 }
15341
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015342 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070015343 //Channel and action frame is pending
15344 //Otherwise Cancel Remain On Channel and allow Scan
15345 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015346 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070015347 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015348 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070015349 return -EBUSY;
15350 }
15351
Jeff Johnson295189b2012-06-20 16:38:30 -070015352 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
15353 {
15354 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080015355 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015356 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015357 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015358 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
15359 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015360 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015361 "%s: MAX TM Level Scan not allowed", __func__);
15362 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015363 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015364 }
15365 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
15366
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015367 /* Check if scan is allowed at this point of time.
15368 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053015369 if (TRUE == pHddCtx->btCoexModeSet)
15370 {
15371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15372 FL("BTCoex Mode operation in progress"));
15373 return -EBUSY;
15374 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015375 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015376 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015377
15378 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
15379 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
15380 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015381 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
15382 pHddCtx->last_scan_reject_reason != curr_reason ||
15383 !pHddCtx->last_scan_reject_timestamp)
15384 {
15385 pHddCtx->last_scan_reject_session_id = curr_session_id;
15386 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053015387 pHddCtx->last_scan_reject_timestamp =
15388 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015389 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053015390 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053015391 else
15392 {
15393 pHddCtx->scan_reject_cnt++;
15394
Abhishek Singhe4b12562017-06-20 16:53:39 +053015395 if ((pHddCtx->scan_reject_cnt >=
15396 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053015397 vos_system_time_after(jiffies_to_msecs(jiffies),
15398 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015399 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015400 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
15401 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
15402 vos_system_time_after(jiffies_to_msecs(jiffies),
15403 pHddCtx->last_scan_reject_timestamp));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015404 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015405 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015406 if (pHddCtx->cfg_ini->enableFatalEvent)
15407 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
15408 WLAN_LOG_INDICATOR_HOST_DRIVER,
15409 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
15410 FALSE, FALSE);
15411 else
15412 {
15413 hddLog(LOGE, FL("Triggering SSR"));
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +053015414 vos_wlanRestart(VOS_SCAN_REQ_EXPIRED);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015415 }
15416 }
15417 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015418 return -EBUSY;
15419 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015420 pHddCtx->last_scan_reject_timestamp = 0;
15421 pHddCtx->last_scan_reject_session_id = 0xFF;
15422 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015423 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015424
Jeff Johnson295189b2012-06-20 16:38:30 -070015425 vos_mem_zero( &scanRequest, sizeof(scanRequest));
15426
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015427 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
15428 * Becasue of this, driver is assuming that this is not wildcard scan and so
15429 * is not aging out the scan results.
15430 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053015431 if ((request->ssids) && (request->n_ssids == 1) &&
15432 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015433 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015434 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015435
15436 if ((request->ssids) && (0 < request->n_ssids))
15437 {
15438 tCsrSSIDInfo *SsidInfo;
15439 int j;
15440 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
15441 /* Allocate num_ssid tCsrSSIDInfo structure */
15442 SsidInfo = scanRequest.SSIDs.SSIDList =
15443 ( tCsrSSIDInfo *)vos_mem_malloc(
15444 request->n_ssids*sizeof(tCsrSSIDInfo));
15445
15446 if(NULL == scanRequest.SSIDs.SSIDList)
15447 {
15448 hddLog(VOS_TRACE_LEVEL_ERROR,
15449 "%s: memory alloc failed SSIDInfo buffer", __func__);
15450 return -ENOMEM;
15451 }
15452
15453 /* copy all the ssid's and their length */
15454 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
15455 {
15456 /* get the ssid length */
15457 SsidInfo->SSID.length = request->ssids[j].ssid_len;
15458 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
15459 SsidInfo->SSID.length);
15460 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
15461 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
15462 j, SsidInfo->SSID.ssId);
15463 }
15464 /* set the scan type to active */
15465 scanRequest.scanType = eSIR_ACTIVE_SCAN;
15466 }
15467 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015468 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015469 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15470 TRACE_CODE_HDD_CFG80211_SCAN,
15471 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070015472 /* set the scan type to active */
15473 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070015474 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015475 else
15476 {
15477 /*Set the scan type to default type, in this case it is ACTIVE*/
15478 scanRequest.scanType = pScanInfo->scan_mode;
15479 }
15480 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
15481 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070015482
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015483 csr_scan_request_assign_bssid(&scanRequest, request);
15484
Jeff Johnson295189b2012-06-20 16:38:30 -070015485 /* set BSSType to default type */
15486 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
15487
15488 /*TODO: scan the requested channels only*/
15489
15490 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015491 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070015492 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015493 hddLog(VOS_TRACE_LEVEL_WARN,
15494 "No of Scan Channels exceeded limit: %d", request->n_channels);
15495 request->n_channels = MAX_CHANNEL;
15496 }
15497
15498 hddLog(VOS_TRACE_LEVEL_INFO,
15499 "No of Scan Channels: %d", request->n_channels);
15500
15501
15502 if( request->n_channels )
15503 {
15504 char chList [(request->n_channels*5)+1];
15505 int len;
15506 channelList = vos_mem_malloc( request->n_channels );
15507 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053015508 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015509 hddLog(VOS_TRACE_LEVEL_ERROR,
15510 "%s: memory alloc failed channelList", __func__);
15511 status = -ENOMEM;
15512 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053015513 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015514
15515 for( i = 0, len = 0; i < request->n_channels ; i++ )
15516 {
15517 channelList[i] = request->channels[i]->hw_value;
15518 len += snprintf(chList+len, 5, "%d ", channelList[i]);
15519 }
15520
Nirav Shah20ac06f2013-12-12 18:14:06 +053015521 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015522 "Channel-List: %s ", chList);
15523 }
c_hpothu53512302014-04-15 18:49:53 +053015524
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015525 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
15526 scanRequest.ChannelInfo.ChannelList = channelList;
15527
15528 /* set requestType to full scan */
15529 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
15530
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015531 /* if there is back to back scan happening in driver with in
15532 * nDeferScanTimeInterval interval driver should defer new scan request
15533 * and should provide last cached scan results instead of new channel list.
15534 * This rule is not applicable if scan is p2p scan.
15535 * This condition will work only in case when last request no of channels
15536 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053015537 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053015538 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015539 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015540
Sushant Kaushik86592172015-04-27 16:35:03 +053015541 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
15542 /* if wps ie is NULL , then only defer scan */
15543 if ( pWpsIe == NULL &&
15544 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053015545 {
15546 if ( pScanInfo->last_scan_timestamp !=0 &&
15547 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
15548 {
15549 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
15550 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
15551 vos_mem_compare(pScanInfo->last_scan_channelList,
15552 channelList, pScanInfo->last_scan_numChannels))
15553 {
15554 hddLog(VOS_TRACE_LEVEL_WARN,
15555 " New and old station scan time differ is less then %u",
15556 pHddCtx->cfg_ini->nDeferScanTimeInterval);
15557
15558 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015559 pAdapter);
15560
Agarwal Ashish57e84372014-12-05 18:26:53 +053015561 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015562 "Return old cached scan as all channels and no of channels are same");
15563
Agarwal Ashish57e84372014-12-05 18:26:53 +053015564 if (0 > ret)
15565 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015566
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015567 hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015568
15569 status = eHAL_STATUS_SUCCESS;
15570 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053015571 }
15572 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015573 }
15574
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015575 /* Flush the scan results(only p2p beacons) for STA scan and P2P
15576 * search (Flush on both full scan and social scan but not on single
15577 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
15578 */
15579
15580 /* Supplicant does single channel scan after 8-way handshake
15581 * and in that case driver shoudnt flush scan results. If
15582 * driver flushes the scan results here and unfortunately if
15583 * the AP doesnt respond to our probe req then association
15584 * fails which is not desired
15585 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015586 if ((request->n_ssids == 1)
15587 && (request->ssids != NULL)
15588 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
15589 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015590
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015591 if( is_p2p_scan ||
15592 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015593 {
15594 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
15595 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
15596 pAdapter->sessionId );
15597 }
15598
15599 if( request->ie_len )
15600 {
15601 /* save this for future association (join requires this) */
15602 /*TODO: Array needs to be converted to dynamic allocation,
15603 * as multiple ie.s can be sent in cfg80211_scan_request structure
15604 * CR 597966
15605 */
15606 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
15607 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
15608 pScanInfo->scanAddIE.length = request->ie_len;
15609
15610 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15611 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15612 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015613 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015614 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070015615 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015616 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
15617 memcpy( pwextBuf->roamProfile.addIEScan,
15618 request->ie, request->ie_len);
15619 }
15620 else
15621 {
15622 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
15623 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070015624 }
15625
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015626 }
15627 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
15628 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
15629
15630 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
15631 request->ie_len);
15632 if (pP2pIe != NULL)
15633 {
15634#ifdef WLAN_FEATURE_P2P_DEBUG
15635 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
15636 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
15637 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053015638 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015639 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
15640 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15641 "Go nego completed to Connection is started");
15642 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15643 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053015644 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015645 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
15646 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015647 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015648 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
15649 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15650 "Disconnected state to Connection is started");
15651 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15652 "for 4way Handshake");
15653 }
15654#endif
15655
15656 /* no_cck will be set during p2p find to disable 11b rates */
15657 if(TRUE == request->no_cck)
15658 {
15659 hddLog(VOS_TRACE_LEVEL_INFO,
15660 "%s: This is a P2P Search", __func__);
15661 scanRequest.p2pSearch = 1;
15662
15663 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053015664 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015665 /* set requestType to P2P Discovery */
15666 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
15667 }
15668
15669 /*
15670 Skip Dfs Channel in case of P2P Search
15671 if it is set in ini file
15672 */
15673 if(cfg_param->skipDfsChnlInP2pSearch)
15674 {
15675 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015676 }
15677 else
15678 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015679 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015680 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015681
Agarwal Ashish4f616132013-12-30 23:32:50 +053015682 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015683 }
15684 }
15685
15686 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
15687
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015688#ifdef FEATURE_WLAN_TDLS
15689 /* if tdls disagree scan right now, return immediately.
15690 tdls will schedule the scan when scan is allowed. (return SUCCESS)
15691 or will reject the scan if any TDLS is in progress. (return -EBUSY)
15692 */
15693 status = wlan_hdd_tdls_scan_callback (pAdapter,
15694 wiphy,
15695#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15696 dev,
15697#endif
15698 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015699 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015700 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053015701 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015702 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
15703 "scan rejected %d", __func__, status);
15704 else
15705 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
15706 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015707 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053015708 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015709 }
15710#endif
15711
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015712 /* acquire the wakelock to avoid the apps suspend during the scan. To
15713 * address the following issues.
15714 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
15715 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
15716 * for long time, this result in apps running at full power for long time.
15717 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
15718 * be stuck in full power because of resume BMPS
15719 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015720 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015721
Nirav Shah20ac06f2013-12-12 18:14:06 +053015722 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
15723 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015724 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
15725 scanRequest.requestType, scanRequest.scanType,
15726 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053015727 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
15728
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015729 if (pHddCtx->spoofMacAddr.isEnabled &&
15730 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053015731 {
15732 hddLog(VOS_TRACE_LEVEL_INFO,
15733 "%s: MAC Spoofing enabled for current scan", __func__);
15734 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15735 * to fill TxBds for probe request during current scan
15736 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015737 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053015738 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015739
15740 if(status != VOS_STATUS_SUCCESS)
15741 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015742 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015743 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053015744#ifdef FEATURE_WLAN_TDLS
15745 wlan_hdd_tdls_scan_done_callback(pAdapter);
15746#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015747 goto free_mem;
15748 }
Siddharth Bhal76972212014-10-15 16:22:51 +053015749 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053015750 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070015751 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015752 pAdapter->sessionId, &scanRequest, &scanId,
15753 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070015754
Jeff Johnson295189b2012-06-20 16:38:30 -070015755 if (eHAL_STATUS_SUCCESS != status)
15756 {
15757 hddLog(VOS_TRACE_LEVEL_ERROR,
15758 "%s: sme_ScanRequest returned error %d", __func__, status);
15759 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015760 if(eHAL_STATUS_RESOURCES == status)
15761 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015762 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
15763 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015764 status = -EBUSY;
15765 } else {
15766 status = -EIO;
15767 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015768 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015769
15770#ifdef FEATURE_WLAN_TDLS
15771 wlan_hdd_tdls_scan_done_callback(pAdapter);
15772#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015773 goto free_mem;
15774 }
15775
15776 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015777 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070015778 pAdapter->request = request;
15779 pScanInfo->scanId = scanId;
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015780 pScanInfo->no_cck = request->no_cck;
15781 pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
15782 for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
15783 pHddCtx->scan_info.last_scan_channelList[i] =
15784 request->channels[i]->hw_value;
15785 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015786
15787 complete(&pScanInfo->scan_req_completion_event);
15788
15789free_mem:
15790 if( scanRequest.SSIDs.SSIDList )
15791 {
15792 vos_mem_free(scanRequest.SSIDs.SSIDList);
15793 }
15794
15795 if( channelList )
15796 vos_mem_free( channelList );
15797
15798 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015799 return status;
15800}
15801
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015802int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
15803#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15804 struct net_device *dev,
15805#endif
15806 struct cfg80211_scan_request *request)
15807{
15808 int ret;
15809
15810 vos_ssr_protect(__func__);
15811 ret = __wlan_hdd_cfg80211_scan(wiphy,
15812#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15813 dev,
15814#endif
15815 request);
15816 vos_ssr_unprotect(__func__);
15817
15818 return ret;
15819}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015820
15821void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
15822{
15823 v_U8_t iniDot11Mode =
15824 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
15825 eHddDot11Mode hddDot11Mode = iniDot11Mode;
15826
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015827 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
15828 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015829 switch ( iniDot11Mode )
15830 {
15831 case eHDD_DOT11_MODE_AUTO:
15832 case eHDD_DOT11_MODE_11ac:
15833 case eHDD_DOT11_MODE_11ac_ONLY:
15834#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053015835 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
15836 sme_IsFeatureSupportedByFW(DOT11AC) )
15837 hddDot11Mode = eHDD_DOT11_MODE_11ac;
15838 else
15839 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015840#else
15841 hddDot11Mode = eHDD_DOT11_MODE_11n;
15842#endif
15843 break;
15844 case eHDD_DOT11_MODE_11n:
15845 case eHDD_DOT11_MODE_11n_ONLY:
15846 hddDot11Mode = eHDD_DOT11_MODE_11n;
15847 break;
15848 default:
15849 hddDot11Mode = iniDot11Mode;
15850 break;
15851 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015852#ifdef WLAN_FEATURE_AP_HT40_24G
15853 if (operationChannel > SIR_11B_CHANNEL_END)
15854#endif
15855 {
15856 /* This call decides required channel bonding mode */
15857 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015858 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053015859 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015860 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015861}
15862
Jeff Johnson295189b2012-06-20 16:38:30 -070015863/*
15864 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015865 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015866 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015867int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053015868 const u8 *ssid, size_t ssid_len, const u8 *bssid,
15869 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070015870{
15871 int status = 0;
15872 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080015873 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015874 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015875 v_U32_t roamId;
15876 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070015877 eCsrAuthType RSNAuthType;
15878
15879 ENTER();
15880
15881 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015882 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015883 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015884
15885 status = wlan_hdd_validate_context(pHddCtx);
15886 if (status)
15887 {
Yue Mae36e3552014-03-05 17:06:20 -080015888 return status;
15889 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015890
Jeff Johnson295189b2012-06-20 16:38:30 -070015891 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
15892 {
15893 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
15894 return -EINVAL;
15895 }
15896
Nitesh Shah9b066282017-06-06 18:05:52 +053015897
Jeff Johnson295189b2012-06-20 16:38:30 -070015898 pRoamProfile = &pWextState->roamProfile;
15899
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015900 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070015901 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015902 hdd_station_ctx_t *pHddStaCtx;
15903 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053015904 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015905
Siddharth Bhalda0d1622015-04-24 15:47:49 +053015906 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
15907
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015908 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070015909 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
15910 {
15911 /*QoS not enabled in cfg file*/
15912 pRoamProfile->uapsd_mask = 0;
15913 }
15914 else
15915 {
15916 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015917 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070015918 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
15919 }
15920
15921 pRoamProfile->SSIDs.numOfSSIDs = 1;
15922 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
15923 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015924 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070015925 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
15926 ssid, ssid_len);
15927
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015928 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
15929 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
15930
Jeff Johnson295189b2012-06-20 16:38:30 -070015931 if (bssid)
15932 {
15933 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015934 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015935 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015936 /* Save BSSID in seperate variable as well, as RoamProfile
15937 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070015938 case of join failure we should send valid BSSID to supplicant
15939 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015940 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015941 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015942
Jeff Johnson295189b2012-06-20 16:38:30 -070015943 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015944 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070015945 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015946 /* Store bssid_hint to use in the scan filter. */
15947 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15948 WNI_CFG_BSSID_LEN);
15949 /*
15950 * Save BSSID in seperate variable as well, as RoamProfile
15951 * BSSID is getting zeroed out in the association process. And in
15952 * case of join failure we should send valid BSSID to supplicant
15953 */
15954 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15955 WNI_CFG_BSSID_LEN);
15956 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15957 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015958 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015959
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015960
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015961 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15962 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015963 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15964 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015965 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015966 /*set gen ie*/
15967 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15968 /*set auth*/
15969 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15970 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015971#ifdef FEATURE_WLAN_WAPI
15972 if (pAdapter->wapi_info.nWapiMode)
15973 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015974 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015975 switch (pAdapter->wapi_info.wapiAuthMode)
15976 {
15977 case WAPI_AUTH_MODE_PSK:
15978 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015979 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015980 pAdapter->wapi_info.wapiAuthMode);
15981 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15982 break;
15983 }
15984 case WAPI_AUTH_MODE_CERT:
15985 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015986 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015987 pAdapter->wapi_info.wapiAuthMode);
15988 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15989 break;
15990 }
15991 } // End of switch
15992 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15993 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15994 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015995 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015996 pRoamProfile->AuthType.numEntries = 1;
15997 pRoamProfile->EncryptionType.numEntries = 1;
15998 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15999 pRoamProfile->mcEncryptionType.numEntries = 1;
16000 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
16001 }
16002 }
16003#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016004#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016005 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016006 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
16007 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
16008 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016009 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
16010 sizeof (tSirGtkOffloadParams));
16011 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016012 }
16013#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016014 pRoamProfile->csrPersona = pAdapter->device_mode;
16015
Jeff Johnson32d95a32012-09-10 13:15:23 -070016016 if( operatingChannel )
16017 {
16018 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
16019 pRoamProfile->ChannelInfo.numOfChannels = 1;
16020 }
Chet Lanctot186b5732013-03-18 10:26:30 -070016021 else
16022 {
16023 pRoamProfile->ChannelInfo.ChannelList = NULL;
16024 pRoamProfile->ChannelInfo.numOfChannels = 0;
16025 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016026 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
16027 {
16028 hdd_select_cbmode(pAdapter,operatingChannel);
16029 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053016030
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016031 /*
16032 * Change conn_state to connecting before sme_RoamConnect(),
16033 * because sme_RoamConnect() has a direct path to call
16034 * hdd_smeRoamCallback(), which will change the conn_state
16035 * If direct path, conn_state will be accordingly changed
16036 * to NotConnected or Associated by either
16037 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
16038 * in sme_RoamCallback()
16039 * if sme_RomConnect is to be queued,
16040 * Connecting state will remain until it is completed.
16041 * If connection state is not changed,
16042 * connection state will remain in eConnectionState_NotConnected state.
16043 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
16044 * if conn state is eConnectionState_NotConnected.
16045 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
16046 * informed of connect result indication which is an issue.
16047 */
16048
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016049 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16050 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053016051 {
16052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016053 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016054 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
16055 eConnectionState_Connecting);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016056 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
16057 hdd_wait_for_ecsa_complete(pHddCtx);
Abhishek Singhf4669da2014-05-26 15:07:49 +053016058 }
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016059
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016060 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070016061 pAdapter->sessionId, pRoamProfile, &roamId);
16062
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016063 if ((eHAL_STATUS_SUCCESS != status) &&
16064 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16065 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016066
16067 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016068 hddLog(VOS_TRACE_LEVEL_ERROR,
16069 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
16070 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016071 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016072 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016073 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016074 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016075
16076 pRoamProfile->ChannelInfo.ChannelList = NULL;
16077 pRoamProfile->ChannelInfo.numOfChannels = 0;
16078
Jeff Johnson295189b2012-06-20 16:38:30 -070016079 }
16080 else
16081 {
16082 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
16083 return -EINVAL;
16084 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080016085 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016086 return status;
16087}
16088
16089/*
16090 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
16091 * This function is used to set the authentication type (OPEN/SHARED).
16092 *
16093 */
16094static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
16095 enum nl80211_auth_type auth_type)
16096{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016097 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016098 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16099
16100 ENTER();
16101
16102 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016103 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070016104 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016105 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016106 hddLog(VOS_TRACE_LEVEL_INFO,
16107 "%s: set authentication type to AUTOSWITCH", __func__);
16108 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
16109 break;
16110
16111 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016112#ifdef WLAN_FEATURE_VOWIFI_11R
16113 case NL80211_AUTHTYPE_FT:
16114#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016115 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016116 "%s: set authentication type to OPEN", __func__);
16117 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
16118 break;
16119
16120 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016121 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016122 "%s: set authentication type to SHARED", __func__);
16123 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
16124 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016125#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016126 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016127 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016128 "%s: set authentication type to CCKM WPA", __func__);
16129 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
16130 break;
16131#endif
16132
16133
16134 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016135 hddLog(VOS_TRACE_LEVEL_ERROR,
16136 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016137 auth_type);
16138 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
16139 return -EINVAL;
16140 }
16141
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016142 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016143 pHddStaCtx->conn_info.authType;
16144 return 0;
16145}
16146
16147/*
16148 * FUNCTION: wlan_hdd_set_akm_suite
16149 * This function is used to set the key mgmt type(PSK/8021x).
16150 *
16151 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016152static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016153 u32 key_mgmt
16154 )
16155{
16156 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16157 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053016158 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016159#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016160#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016161#endif
16162#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016163#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016164#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016165 /*set key mgmt type*/
16166 switch(key_mgmt)
16167 {
16168 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053016169 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016170#ifdef WLAN_FEATURE_VOWIFI_11R
16171 case WLAN_AKM_SUITE_FT_PSK:
16172#endif
16173 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070016174 __func__);
16175 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
16176 break;
16177
16178 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053016179 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016180#ifdef WLAN_FEATURE_VOWIFI_11R
16181 case WLAN_AKM_SUITE_FT_8021X:
16182#endif
16183 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070016184 __func__);
16185 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16186 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016187#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016188#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
16189#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
16190 case WLAN_AKM_SUITE_CCKM:
16191 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
16192 __func__);
16193 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
16194 break;
16195#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070016196#ifndef WLAN_AKM_SUITE_OSEN
16197#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
16198 case WLAN_AKM_SUITE_OSEN:
16199 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
16200 __func__);
16201 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16202 break;
16203#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016204
16205 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016206 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016207 __func__, key_mgmt);
16208 return -EINVAL;
16209
16210 }
16211 return 0;
16212}
16213
16214/*
16215 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016216 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070016217 * (NONE/WEP40/WEP104/TKIP/CCMP).
16218 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016219static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
16220 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070016221 bool ucast
16222 )
16223{
16224 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016225 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016226 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16227
16228 ENTER();
16229
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016230 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016231 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053016232 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070016233 __func__, cipher);
16234 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16235 }
16236 else
16237 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016238
Jeff Johnson295189b2012-06-20 16:38:30 -070016239 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016240 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016241 {
16242 case IW_AUTH_CIPHER_NONE:
16243 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16244 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016245
Jeff Johnson295189b2012-06-20 16:38:30 -070016246 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016247 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070016248 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016249
Jeff Johnson295189b2012-06-20 16:38:30 -070016250 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016251 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070016252 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016253
Jeff Johnson295189b2012-06-20 16:38:30 -070016254 case WLAN_CIPHER_SUITE_TKIP:
16255 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
16256 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016257
Jeff Johnson295189b2012-06-20 16:38:30 -070016258 case WLAN_CIPHER_SUITE_CCMP:
16259 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16260 break;
16261#ifdef FEATURE_WLAN_WAPI
16262 case WLAN_CIPHER_SUITE_SMS4:
16263 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
16264 break;
16265#endif
16266
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016267#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016268 case WLAN_CIPHER_SUITE_KRK:
16269 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
16270 break;
16271#endif
16272 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016273 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016274 __func__, cipher);
16275 return -EOPNOTSUPP;
16276 }
16277 }
16278
16279 if (ucast)
16280 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016281 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016282 __func__, encryptionType);
16283 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16284 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016285 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016286 encryptionType;
16287 }
16288 else
16289 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016290 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016291 __func__, encryptionType);
16292 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
16293 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
16294 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
16295 }
16296
16297 return 0;
16298}
16299
16300
16301/*
16302 * FUNCTION: wlan_hdd_cfg80211_set_ie
16303 * This function is used to parse WPA/RSN IE's.
16304 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016305int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016306#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16307 const u8 *ie,
16308#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016309 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016310#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016311 size_t ie_len
16312 )
16313{
16314 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016315#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16316 const u8 *genie = ie;
16317#else
Jeff Johnson295189b2012-06-20 16:38:30 -070016318 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016319#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016320 v_U16_t remLen = ie_len;
16321#ifdef FEATURE_WLAN_WAPI
16322 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
16323 u16 *tmp;
16324 v_U16_t akmsuiteCount;
16325 int *akmlist;
16326#endif
16327 ENTER();
16328
16329 /* clear previous assocAddIE */
16330 pWextState->assocAddIE.length = 0;
16331 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016332 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016333
16334 while (remLen >= 2)
16335 {
16336 v_U16_t eLen = 0;
16337 v_U8_t elementId;
16338 elementId = *genie++;
16339 eLen = *genie++;
16340 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016341
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053016342 /* Sanity check on eLen */
16343 if (eLen > remLen) {
16344 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
16345 __func__, eLen, elementId);
16346 VOS_ASSERT(0);
16347 return -EINVAL;
16348 }
16349
Arif Hussain6d2a3322013-11-17 19:50:10 -080016350 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070016351 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016352
16353 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070016354 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016355 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016356 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 -070016357 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016358 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016359 "%s: Invalid WPA IE", __func__);
16360 return -EINVAL;
16361 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016362 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070016363 {
16364 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016365 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016366 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016367
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016368 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016369 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016370 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
16371 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016372 VOS_ASSERT(0);
16373 return -ENOMEM;
16374 }
16375 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16376 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16377 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016378
Jeff Johnson295189b2012-06-20 16:38:30 -070016379 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
16380 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16381 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16382 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016383 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
16384 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053016385 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16386 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
16387 __func__, eLen);
16388 VOS_ASSERT(0);
16389 return -EINVAL;
16390 }
16391
Jeff Johnson295189b2012-06-20 16:38:30 -070016392 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
16393 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16394 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
16395 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
16396 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
16397 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016398 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053016399 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070016400 {
16401 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016402 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016403 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016404
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016405 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016406 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016407 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16408 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016409 VOS_ASSERT(0);
16410 return -ENOMEM;
16411 }
16412 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16413 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16414 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016415
Jeff Johnson295189b2012-06-20 16:38:30 -070016416 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16417 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16418 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016419#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016420 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
16421 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016422 /*Consider WFD IE, only for P2P Client */
16423 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
16424 {
16425 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016426 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016427 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016428
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016429 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016430 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016431 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16432 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016433 VOS_ASSERT(0);
16434 return -ENOMEM;
16435 }
16436 // WFD IE is saved to Additional IE ; it should be accumulated to handle
16437 // WPS IE + P2P IE + WFD IE
16438 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16439 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016440
Jeff Johnson295189b2012-06-20 16:38:30 -070016441 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16442 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16443 }
16444#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016445 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016446 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016447 HS20_OUI_TYPE_SIZE)) )
16448 {
16449 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016450 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016451 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016452
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016453 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016454 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016455 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16456 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016457 VOS_ASSERT(0);
16458 return -ENOMEM;
16459 }
16460 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16461 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016462
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016463 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16464 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16465 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016466 /* Appending OSEN Information Element in Assiciation Request */
16467 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
16468 OSEN_OUI_TYPE_SIZE)) )
16469 {
16470 v_U16_t curAddIELen = pWextState->assocAddIE.length;
16471 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
16472 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016473
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016474 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016475 {
16476 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16477 "Need bigger buffer space");
16478 VOS_ASSERT(0);
16479 return -ENOMEM;
16480 }
16481 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16482 pWextState->assocAddIE.length += eLen + 2;
16483
16484 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
16485 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16486 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16487 }
16488
Abhishek Singh4322e622015-06-10 15:42:54 +053016489 /* Update only for WPA IE */
16490 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
16491 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016492
16493 /* populating as ADDIE in beacon frames */
16494 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016495 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016496 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
16497 {
16498 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16499 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
16500 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16501 {
16502 hddLog(LOGE,
16503 "Coldn't pass "
16504 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
16505 }
16506 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
16507 else
16508 hddLog(LOGE,
16509 "Could not pass on "
16510 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
16511
16512 /* IBSS mode doesn't contain params->proberesp_ies still
16513 beaconIE's need to be populated in probe response frames */
16514 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
16515 {
16516 u16 rem_probe_resp_ie_len = eLen + 2;
16517 u8 probe_rsp_ie_len[3] = {0};
16518 u8 counter = 0;
16519
16520 /* Check Probe Resp Length if it is greater then 255 then
16521 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
16522 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
16523 not able Store More then 255 bytes into One Variable */
16524
16525 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
16526 {
16527 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
16528 {
16529 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
16530 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
16531 }
16532 else
16533 {
16534 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
16535 rem_probe_resp_ie_len = 0;
16536 }
16537 }
16538
16539 rem_probe_resp_ie_len = 0;
16540
16541 if (probe_rsp_ie_len[0] > 0)
16542 {
16543 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16544 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
16545 (tANI_U8*)(genie - 2),
16546 probe_rsp_ie_len[0], NULL,
16547 eANI_BOOLEAN_FALSE)
16548 == eHAL_STATUS_FAILURE)
16549 {
16550 hddLog(LOGE,
16551 "Could not pass"
16552 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
16553 }
16554 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
16555 }
16556
16557 if (probe_rsp_ie_len[1] > 0)
16558 {
16559 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16560 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
16561 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16562 probe_rsp_ie_len[1], NULL,
16563 eANI_BOOLEAN_FALSE)
16564 == eHAL_STATUS_FAILURE)
16565 {
16566 hddLog(LOGE,
16567 "Could not pass"
16568 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
16569 }
16570 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
16571 }
16572
16573 if (probe_rsp_ie_len[2] > 0)
16574 {
16575 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16576 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
16577 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16578 probe_rsp_ie_len[2], NULL,
16579 eANI_BOOLEAN_FALSE)
16580 == eHAL_STATUS_FAILURE)
16581 {
16582 hddLog(LOGE,
16583 "Could not pass"
16584 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
16585 }
16586 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
16587 }
16588
16589 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16590 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
16591 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16592 {
16593 hddLog(LOGE,
16594 "Could not pass"
16595 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
16596 }
16597 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016598 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070016599 break;
16600 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053016601 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16602 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
16603 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
16604 VOS_ASSERT(0);
16605 return -EINVAL;
16606 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016607 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
16608 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16609 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
16610 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
16611 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16612 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016613
Abhishek Singhb16f3562016-01-20 11:08:32 +053016614 /* Appending extended capabilities with Interworking or
16615 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016616 *
16617 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016618 * interworkingService or bsstransition bit is set to 1.
16619 * Driver is only interested in interworkingService and
16620 * bsstransition capability from supplicant.
16621 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016622 * required from supplicat, it needs to be handled while
16623 * sending Assoc Req in LIM.
16624 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016625 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016626 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016627 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016628 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016629 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016630
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016631 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016632 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016633 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16634 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016635 VOS_ASSERT(0);
16636 return -ENOMEM;
16637 }
16638 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16639 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016640
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016641 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16642 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16643 break;
16644 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016645#ifdef FEATURE_WLAN_WAPI
16646 case WLAN_EID_WAPI:
16647 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016648 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016649 pAdapter->wapi_info.nWapiMode);
16650 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016651 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016652 akmsuiteCount = WPA_GET_LE16(tmp);
16653 tmp = tmp + 1;
16654 akmlist = (int *)(tmp);
16655 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16656 {
16657 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16658 }
16659 else
16660 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016661 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016662 VOS_ASSERT(0);
16663 return -EINVAL;
16664 }
16665
16666 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16667 {
16668 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016669 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016670 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016671 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016672 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016673 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016674 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016675 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016676 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
16677 }
16678 break;
16679#endif
16680 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016681 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016682 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016683 /* when Unknown IE is received we should break and continue
16684 * to the next IE in the buffer instead we were returning
16685 * so changing this to break */
16686 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016687 }
16688 genie += eLen;
16689 remLen -= eLen;
16690 }
16691 EXIT();
16692 return 0;
16693}
16694
16695/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016696 * FUNCTION: hdd_isWPAIEPresent
16697 * Parse the received IE to find the WPA IE
16698 *
16699 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016700static bool hdd_isWPAIEPresent(
16701#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16702 const u8 *ie,
16703#else
16704 u8 *ie,
16705#endif
16706 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016707{
16708 v_U8_t eLen = 0;
16709 v_U16_t remLen = ie_len;
16710 v_U8_t elementId = 0;
16711
16712 while (remLen >= 2)
16713 {
16714 elementId = *ie++;
16715 eLen = *ie++;
16716 remLen -= 2;
16717 if (eLen > remLen)
16718 {
16719 hddLog(VOS_TRACE_LEVEL_ERROR,
16720 "%s: IE length is wrong %d", __func__, eLen);
16721 return FALSE;
16722 }
16723 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16724 {
16725 /* OUI - 0x00 0X50 0XF2
16726 WPA Information Element - 0x01
16727 WPA version - 0x01*/
16728 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16729 return TRUE;
16730 }
16731 ie += eLen;
16732 remLen -= eLen;
16733 }
16734 return FALSE;
16735}
16736
16737/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016738 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016739 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016740 * parameters during connect operation.
16741 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016742int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016743 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016744 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016745{
16746 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016747 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016748 ENTER();
16749
16750 /*set wpa version*/
16751 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
16752
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016753 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016754 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053016755 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016756 {
16757 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16758 }
16759 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
16760 {
16761 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16762 }
16763 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016764
16765 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016766 pWextState->wpaVersion);
16767
16768 /*set authentication type*/
16769 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
16770
16771 if (0 > status)
16772 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016773 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016774 "%s: failed to set authentication type ", __func__);
16775 return status;
16776 }
16777
16778 /*set key mgmt type*/
16779 if (req->crypto.n_akm_suites)
16780 {
16781 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
16782 if (0 > status)
16783 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016784 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070016785 __func__);
16786 return status;
16787 }
16788 }
16789
16790 /*set pairwise cipher type*/
16791 if (req->crypto.n_ciphers_pairwise)
16792 {
16793 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
16794 req->crypto.ciphers_pairwise[0], true);
16795 if (0 > status)
16796 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016797 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016798 "%s: failed to set unicast cipher type", __func__);
16799 return status;
16800 }
16801 }
16802 else
16803 {
16804 /*Reset previous cipher suite to none*/
16805 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
16806 if (0 > status)
16807 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016808 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016809 "%s: failed to set unicast cipher type", __func__);
16810 return status;
16811 }
16812 }
16813
16814 /*set group cipher type*/
16815 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
16816 false);
16817
16818 if (0 > status)
16819 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016820 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070016821 __func__);
16822 return status;
16823 }
16824
Chet Lanctot186b5732013-03-18 10:26:30 -070016825#ifdef WLAN_FEATURE_11W
16826 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
16827#endif
16828
Jeff Johnson295189b2012-06-20 16:38:30 -070016829 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
16830 if (req->ie_len)
16831 {
16832 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
16833 if ( 0 > status)
16834 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016835 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016836 __func__);
16837 return status;
16838 }
16839 }
16840
16841 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016842 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016843 {
16844 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
16845 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
16846 )
16847 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016848 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070016849 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
16850 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016851 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016852 __func__);
16853 return -EOPNOTSUPP;
16854 }
16855 else
16856 {
16857 u8 key_len = req->key_len;
16858 u8 key_idx = req->key_idx;
16859
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016860 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016861 && (CSR_MAX_NUM_KEY > key_idx)
16862 )
16863 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016864 hddLog(VOS_TRACE_LEVEL_INFO,
16865 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016866 __func__, key_idx, key_len);
16867 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016868 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070016869 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016870 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016871 (u8)key_len;
16872 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
16873 }
16874 }
16875 }
16876 }
16877
16878 return status;
16879}
16880
16881/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016882 * FUNCTION: wlan_hdd_try_disconnect
16883 * This function is used to disconnect from previous
16884 * connection
16885 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053016886int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016887{
16888 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016889 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016890 hdd_station_ctx_t *pHddStaCtx;
16891 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016892 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016893
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016894 ret = wlan_hdd_validate_context(pHddCtx);
16895 if (0 != ret)
16896 {
16897 return ret;
16898 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016899 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16900
16901 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
16902
16903 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
16904 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053016905 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016906 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
16907 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053016908 /* Indicate disconnect to SME so that in-progress connection or preauth
16909 * can be aborted
16910 */
16911 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
16912 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016913 spin_lock_bh(&pAdapter->lock_for_active_session);
16914 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16915 {
16916 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16917 }
16918 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053016919 hdd_connSetConnectionState(pHddStaCtx,
16920 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016921 /* Issue disconnect to CSR */
16922 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016923 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016924 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016925 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16926 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
16927 hddLog(LOG1,
16928 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
16929 } else if ( 0 != status ) {
16930 hddLog(LOGE,
16931 FL("csrRoamDisconnect failure, returned %d"),
16932 (int)status );
16933 result = -EINVAL;
16934 goto disconnected;
16935 }
16936 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016937 &pAdapter->disconnect_comp_var,
16938 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016939 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
16940 hddLog(LOGE,
16941 "%s: Failed to disconnect, timed out", __func__);
16942 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016943 }
16944 }
16945 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
16946 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016947 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016948 &pAdapter->disconnect_comp_var,
16949 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016950 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016951 {
16952 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016953 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016954 }
16955 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016956disconnected:
16957 hddLog(LOG1,
16958 FL("Set HDD connState to eConnectionState_NotConnected"));
16959 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16960 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016961}
16962
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016963/**
16964 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16965 * @adapter: Pointer to the HDD adapter
16966 * @req: Pointer to the structure cfg_connect_params receieved from user space
16967 *
16968 * This function will start reassociation if bssid hint, channel hint and
16969 * previous bssid parameters are present in the connect request
16970 *
16971 * Return: success if reassociation is happening
16972 * Error code if reassociation is not permitted or not happening
16973 */
16974#ifdef CFG80211_CONNECT_PREV_BSSID
16975static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16976 struct cfg80211_connect_params *req)
16977{
16978 int status = -EPERM;
16979 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
16980 hddLog(VOS_TRACE_LEVEL_INFO,
16981 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
16982 req->channel_hint->hw_value,
16983 MAC_ADDR_ARRAY(req->bssid_hint));
16984 status = hdd_reassoc(adapter, req->bssid_hint,
16985 req->channel_hint->hw_value,
16986 CONNECT_CMD_USERSPACE);
16987 }
16988 return status;
16989}
16990#else
16991static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16992 struct cfg80211_connect_params *req)
16993{
16994 return -EPERM;
16995}
16996#endif
16997
Abhishek Singhe3beee22017-07-31 15:35:40 +053016998/**
16999 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
17000 * connect in HT20 mode
17001 * @hdd_ctx: hdd context
17002 * @adapter: Pointer to the HDD adapter
17003 * @req: Pointer to the structure cfg_connect_params receieved from user space
17004 *
17005 * This function will check if supplicant has indicated to to connect in HT20
17006 * mode. this is currently applicable only for 2.4Ghz mode only.
17007 * if feature is enabled and supplicant indicate HT20 set
17008 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
17009 *
17010 * Return: void
17011 */
17012#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
17013static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
17014 hdd_adapter_t *adapter,
17015 struct cfg80211_connect_params *req)
17016{
17017 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
17018 tCsrRoamProfile *roam_profile;
17019
17020 roam_profile = &wext_state->roamProfile;
17021 roam_profile->force_24ghz_in_ht20 = false;
17022 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
17023 !(req->ht_capa.cap_info &
17024 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
17025 roam_profile->force_24ghz_in_ht20 = true;
17026
17027 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
17028 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
17029}
17030#else
17031static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
17032 hdd_adapter_t *adapter,
17033 struct cfg80211_connect_params *req)
17034{
17035 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
17036 tCsrRoamProfile *roam_profile;
17037
17038 roam_profile = &wext_state->roamProfile;
17039 roam_profile->force_24ghz_in_ht20 = false;
17040}
17041#endif
17042
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017043/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053017044 * FUNCTION: __wlan_hdd_cfg80211_connect
17045 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070017046 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017047static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017048 struct net_device *ndev,
17049 struct cfg80211_connect_params *req
17050 )
17051{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017052 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017053 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053017054#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
17055 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017056 const u8 *bssid_hint = req->bssid_hint;
17057#else
17058 const u8 *bssid_hint = NULL;
17059#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017060 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017061 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053017062 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017063
17064 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017065
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017066 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17067 TRACE_CODE_HDD_CFG80211_CONNECT,
17068 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017069 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017070 "%s: device_mode = %s (%d)", __func__,
17071 hdd_device_modetoString(pAdapter->device_mode),
17072 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017073
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017074 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017075 if (!pHddCtx)
17076 {
17077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17078 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053017079 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017080 }
17081
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017082 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017083 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017084 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017085 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017086 }
17087
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053017088 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
17089 return -EINVAL;
17090
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017091 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
17092 if (0 == status)
17093 return status;
17094
Agarwal Ashish51325b52014-06-16 16:50:49 +053017095
Jeff Johnson295189b2012-06-20 16:38:30 -070017096#ifdef WLAN_BTAMP_FEATURE
17097 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017098 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070017099 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017100 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017101 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080017102 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070017103 }
17104#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017105
17106 //If Device Mode is Station Concurrent Sessions Exit BMps
17107 //P2P Mode will be taken care in Open/close adapter
17108 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053017109 (vos_concurrent_open_sessions_running())) {
17110 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
17111 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017112 }
17113
17114 /*Try disconnecting if already in connected state*/
17115 status = wlan_hdd_try_disconnect(pAdapter);
17116 if ( 0 > status)
17117 {
17118 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17119 " connection"));
17120 return -EALREADY;
17121 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053017122 /* Check for max concurrent connections after doing disconnect if any*/
17123 if (vos_max_concurrent_connections_reached()) {
17124 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17125 return -ECONNREFUSED;
17126 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017127
Jeff Johnson295189b2012-06-20 16:38:30 -070017128 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017129 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070017130
17131 if ( 0 > status)
17132 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017133 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070017134 __func__);
17135 return status;
17136 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053017137
17138 if (pHddCtx->spoofMacAddr.isEnabled)
17139 {
17140 hddLog(VOS_TRACE_LEVEL_INFO,
17141 "%s: MAC Spoofing enabled ", __func__);
17142 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
17143 * to fill TxBds for probe request during SSID scan which may happen
17144 * as part of connect command
17145 */
17146 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
17147 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
17148 if (status != VOS_STATUS_SUCCESS)
17149 return -ECONNREFUSED;
17150 }
17151
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017152 if (req->channel)
17153 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070017154 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017155 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053017156
17157 /* Abort if any scan is going on */
17158 status = wlan_hdd_scan_abort(pAdapter);
17159 if (0 != status)
17160 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
17161
Abhishek Singhe3beee22017-07-31 15:35:40 +053017162 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
17163
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017164 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
17165 req->ssid_len, req->bssid,
17166 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017167
Sushant Kaushikd7083982015-03-18 14:33:24 +053017168 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017169 {
17170 //ReEnable BMPS if disabled
17171 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
17172 (NULL != pHddCtx))
17173 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053017174 if (pHddCtx->hdd_wlan_suspended)
17175 {
17176 hdd_set_pwrparams(pHddCtx);
17177 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017178 //ReEnable Bmps and Imps back
17179 hdd_enable_bmps_imps(pHddCtx);
17180 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053017181 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070017182 return status;
17183 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017184 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017185 EXIT();
17186 return status;
17187}
17188
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017189static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
17190 struct net_device *ndev,
17191 struct cfg80211_connect_params *req)
17192{
17193 int ret;
17194 vos_ssr_protect(__func__);
17195 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
17196 vos_ssr_unprotect(__func__);
17197
17198 return ret;
17199}
Jeff Johnson295189b2012-06-20 16:38:30 -070017200
17201/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017202 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070017203 * This function is used to issue a disconnect request to SME
17204 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017205static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017206 struct net_device *dev,
17207 u16 reason
17208 )
17209{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017210 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017211 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017212 tCsrRoamProfile *pRoamProfile;
17213 hdd_station_ctx_t *pHddStaCtx;
17214 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017215#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017216 tANI_U8 staIdx;
17217#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017218
Jeff Johnson295189b2012-06-20 16:38:30 -070017219 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017220
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017221 if (!pAdapter) {
17222 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17223 return -EINVAL;
17224 }
17225
17226 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17227 if (!pHddStaCtx) {
17228 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
17229 return -EINVAL;
17230 }
17231
17232 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17233 status = wlan_hdd_validate_context(pHddCtx);
17234 if (0 != status)
17235 {
17236 return status;
17237 }
17238
17239 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
17240
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017241 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17242 TRACE_CODE_HDD_CFG80211_DISCONNECT,
17243 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017244 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
17245 __func__, hdd_device_modetoString(pAdapter->device_mode),
17246 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017247
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017248 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
17249 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070017250
Jeff Johnson295189b2012-06-20 16:38:30 -070017251 if (NULL != pRoamProfile)
17252 {
17253 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017254 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
17255 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070017256 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017257 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070017258 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017259 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070017260 switch(reason)
17261 {
17262 case WLAN_REASON_MIC_FAILURE:
17263 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
17264 break;
17265
17266 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
17267 case WLAN_REASON_DISASSOC_AP_BUSY:
17268 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
17269 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
17270 break;
17271
17272 case WLAN_REASON_PREV_AUTH_NOT_VALID:
17273 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053017274 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070017275 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
17276 break;
17277
Jeff Johnson295189b2012-06-20 16:38:30 -070017278 default:
17279 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
17280 break;
17281 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017282 pScanInfo = &pHddCtx->scan_info;
17283 if (pScanInfo->mScanPending)
17284 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017285 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017286 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053017287 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017288 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017289 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053017290 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017291#ifdef FEATURE_WLAN_TDLS
17292 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017293 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017294 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017295 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
17296 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017297 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017298 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017299 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017301 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017302 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017303 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017304 status = sme_DeleteTdlsPeerSta(
17305 WLAN_HDD_GET_HAL_CTX(pAdapter),
17306 pAdapter->sessionId,
17307 mac);
17308 if (status != eHAL_STATUS_SUCCESS) {
17309 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
17310 return -EPERM;
17311 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017312 }
17313 }
17314#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053017315
17316 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
17317 reasonCode,
17318 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017319 status = wlan_hdd_disconnect(pAdapter, reasonCode);
17320 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070017321 {
17322 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017323 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017324 __func__, (int)status );
17325 return -EINVAL;
17326 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017327 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017328 else
17329 {
17330 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
17331 "called while in %d state", __func__,
17332 pHddStaCtx->conn_info.connState);
17333 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017334 }
17335 else
17336 {
17337 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
17338 }
17339
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017340 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017341 return status;
17342}
17343
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017344static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
17345 struct net_device *dev,
17346 u16 reason
17347 )
17348{
17349 int ret;
17350 vos_ssr_protect(__func__);
17351 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
17352 vos_ssr_unprotect(__func__);
17353
17354 return ret;
17355}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017356
Jeff Johnson295189b2012-06-20 16:38:30 -070017357/*
17358 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017359 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070017360 * settings in IBSS mode.
17361 */
17362static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017363 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070017364 struct cfg80211_ibss_params *params
17365 )
17366{
17367 int status = 0;
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017368 tANI_U32 ret;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017369 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070017370 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
17371 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017372
Jeff Johnson295189b2012-06-20 16:38:30 -070017373 ENTER();
17374
17375 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070017376 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070017377
17378 if (params->ie_len && ( NULL != params->ie) )
17379 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017380 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17381 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017382 {
17383 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
17384 encryptionType = eCSR_ENCRYPT_TYPE_AES;
17385 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017386 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017387 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017388 tDot11fIEWPA dot11WPAIE;
17389 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017390 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017391
Wilson Yang00256342013-10-10 23:13:38 -070017392 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017393 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17394 params->ie_len, DOT11F_EID_WPA);
17395 if ( NULL != ie )
17396 {
17397 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
Hanumanth Reddy Pothulad6d2d2c2018-06-27 12:28:12 +053017398
17399 if (ie[1] < DOT11F_IE_WPA_MIN_LEN ||
17400 ie[1] > DOT11F_IE_WPA_MAX_LEN) {
17401 hddLog(LOGE, FL("invalid ie len:%d"), ie[1]);
17402 return -EINVAL;
17403 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017404 // Unpack the WPA IE
17405 //Skip past the EID byte and length byte - and four byte WiFi OUI
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017406 ret = dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017407 &ie[2+4],
17408 ie[1] - 4,
17409 &dot11WPAIE);
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017410 if (DOT11F_FAILED(ret))
17411 {
17412 hddLog(LOGE,
17413 FL("unpack failed status:(0x%08x)"),
17414 ret);
17415 return -EINVAL;
17416 }
17417
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017418 /*Extract the multicast cipher, the encType for unicast
17419 cipher for wpa-none is none*/
17420 encryptionType =
17421 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
17422 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017423 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017424
Jeff Johnson295189b2012-06-20 16:38:30 -070017425 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
17426
17427 if (0 > status)
17428 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017429 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070017430 __func__);
17431 return status;
17432 }
17433 }
17434
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017435 pWextState->roamProfile.AuthType.authType[0] =
17436 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070017437 eCSR_AUTH_TYPE_OPEN_SYSTEM;
Jeff Johnson295189b2012-06-20 16:38:30 -070017438 if (params->privacy)
17439 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017440 /* Security enabled IBSS, At this time there is no information available
17441 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070017442 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017443 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070017444 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017445 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070017446 *enable privacy bit in beacons */
17447
17448 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
17449 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017450 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17451 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070017452 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
17453 pWextState->roamProfile.EncryptionType.numEntries = 1;
17454 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070017455 return status;
17456}
17457
17458/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017459 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017460 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017461 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017462static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017463 struct net_device *dev,
17464 struct cfg80211_ibss_params *params
17465 )
17466{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017467 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017468 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17469 tCsrRoamProfile *pRoamProfile;
17470 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017471 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17472 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017473 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070017474
17475 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017476
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017477 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17478 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
17479 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017480 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017481 "%s: device_mode = %s (%d)", __func__,
17482 hdd_device_modetoString(pAdapter->device_mode),
17483 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017484
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017485 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017486 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017487 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017488 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017489 }
17490
17491 if (NULL == pWextState)
17492 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017493 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017494 __func__);
17495 return -EIO;
17496 }
17497
Agarwal Ashish51325b52014-06-16 16:50:49 +053017498 if (vos_max_concurrent_connections_reached()) {
17499 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17500 return -ECONNREFUSED;
17501 }
17502
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017503 /*Try disconnecting if already in connected state*/
17504 status = wlan_hdd_try_disconnect(pAdapter);
17505 if ( 0 > status)
17506 {
17507 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17508 " IBSS connection"));
17509 return -EALREADY;
17510 }
17511
Jeff Johnson295189b2012-06-20 16:38:30 -070017512 pRoamProfile = &pWextState->roamProfile;
17513
17514 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
17515 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017516 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017517 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017518 return -EINVAL;
17519 }
17520
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017521 /* BSSID is provided by upper layers hence no need to AUTO generate */
17522 if (NULL != params->bssid) {
17523 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17524 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
17525 hddLog (VOS_TRACE_LEVEL_ERROR,
17526 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17527 return -EIO;
17528 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017529 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017530 }
krunal sonie9002db2013-11-25 14:24:17 -080017531 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
17532 {
17533 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17534 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
17535 {
17536 hddLog (VOS_TRACE_LEVEL_ERROR,
17537 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17538 return -EIO;
17539 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017540
17541 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080017542 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017543 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080017544 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017545
Jeff Johnson295189b2012-06-20 16:38:30 -070017546 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070017547 if (NULL !=
17548#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17549 params->chandef.chan)
17550#else
17551 params->channel)
17552#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017553 {
17554 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017555 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17556 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
17557 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17558 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017559
17560 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017561 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070017562 ieee80211_frequency_to_channel(
17563#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17564 params->chandef.chan->center_freq);
17565#else
17566 params->channel->center_freq);
17567#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017568
17569 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17570 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070017571 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017572 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
17573 __func__);
17574 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070017575 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017576
17577 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017578 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017579 if (channelNum == validChan[indx])
17580 {
17581 break;
17582 }
17583 }
17584 if (indx >= numChans)
17585 {
17586 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017587 __func__, channelNum);
17588 return -EINVAL;
17589 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017590 /* Set the Operational Channel */
17591 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
17592 channelNum);
17593 pRoamProfile->ChannelInfo.numOfChannels = 1;
17594 pHddStaCtx->conn_info.operationChannel = channelNum;
17595 pRoamProfile->ChannelInfo.ChannelList =
17596 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070017597 }
17598
17599 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017600 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070017601 if (status < 0)
17602 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017603 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070017604 __func__);
17605 return status;
17606 }
17607
17608 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017609 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053017610 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017611 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017612
17613 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017614 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017615
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017616 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017617 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017618}
17619
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017620static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17621 struct net_device *dev,
17622 struct cfg80211_ibss_params *params
17623 )
17624{
17625 int ret = 0;
17626
17627 vos_ssr_protect(__func__);
17628 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17629 vos_ssr_unprotect(__func__);
17630
17631 return ret;
17632}
17633
Jeff Johnson295189b2012-06-20 16:38:30 -070017634/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017635 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017636 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017637 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017638static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017639 struct net_device *dev
17640 )
17641{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017642 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017643 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17644 tCsrRoamProfile *pRoamProfile;
17645 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017646 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017647 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017648#ifdef WLAN_FEATURE_RMC
17649 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17650#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017651
17652 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017653
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017654 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17655 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17656 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017657 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017658 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017659 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017660 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017661 }
17662
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017663 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17664 hdd_device_modetoString(pAdapter->device_mode),
17665 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017666 if (NULL == pWextState)
17667 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017668 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017669 __func__);
17670 return -EIO;
17671 }
17672
17673 pRoamProfile = &pWextState->roamProfile;
17674
17675 /* Issue disconnect only if interface type is set to IBSS */
17676 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17677 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017678 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017679 __func__);
17680 return -EINVAL;
17681 }
17682
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017683#ifdef WLAN_FEATURE_RMC
17684 /* Clearing add IE of beacon */
17685 if (ccmCfgSetStr(pHddCtx->hHal,
17686 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17687 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17688 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17689 {
17690 hddLog (VOS_TRACE_LEVEL_ERROR,
17691 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17692 return -EINVAL;
17693 }
17694 if (ccmCfgSetInt(pHddCtx->hHal,
17695 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17696 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17697 {
17698 hddLog (VOS_TRACE_LEVEL_ERROR,
17699 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17700 __func__);
17701 return -EINVAL;
17702 }
17703
17704 // Reset WNI_CFG_PROBE_RSP Flags
17705 wlan_hdd_reset_prob_rspies(pAdapter);
17706
17707 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17708 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17709 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17710 {
17711 hddLog (VOS_TRACE_LEVEL_ERROR,
17712 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17713 __func__);
17714 return -EINVAL;
17715 }
17716#endif
17717
Jeff Johnson295189b2012-06-20 16:38:30 -070017718 /* Issue Disconnect request */
17719 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017720 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17721 pAdapter->sessionId,
17722 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17723 if (!HAL_STATUS_SUCCESS(hal_status)) {
17724 hddLog(LOGE,
17725 FL("sme_RoamDisconnect failed hal_status(%d)"),
17726 hal_status);
17727 return -EAGAIN;
17728 }
17729 status = wait_for_completion_timeout(
17730 &pAdapter->disconnect_comp_var,
17731 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17732 if (!status) {
17733 hddLog(LOGE,
17734 FL("wait on disconnect_comp_var failed"));
17735 return -ETIMEDOUT;
17736 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017737
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017738 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017739 return 0;
17740}
17741
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017742static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17743 struct net_device *dev
17744 )
17745{
17746 int ret = 0;
17747
17748 vos_ssr_protect(__func__);
17749 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17750 vos_ssr_unprotect(__func__);
17751
17752 return ret;
17753}
17754
Jeff Johnson295189b2012-06-20 16:38:30 -070017755/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017756 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017757 * This function is used to set the phy parameters
17758 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17759 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017760static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017761 u32 changed)
17762{
17763 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17764 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017765 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017766
17767 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017768
17769 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017770 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17771 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017772
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017773 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017774 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017775 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017776 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017777 }
17778
Jeff Johnson295189b2012-06-20 16:38:30 -070017779 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17780 {
17781 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17782 WNI_CFG_RTS_THRESHOLD_STAMAX :
17783 wiphy->rts_threshold;
17784
17785 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017786 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017787 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017788 hddLog(VOS_TRACE_LEVEL_ERROR,
17789 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017790 __func__, rts_threshold);
17791 return -EINVAL;
17792 }
17793
17794 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17795 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017796 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017797 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017798 hddLog(VOS_TRACE_LEVEL_ERROR,
17799 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017800 __func__, rts_threshold);
17801 return -EIO;
17802 }
17803
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017804 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017805 rts_threshold);
17806 }
17807
17808 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17809 {
17810 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17811 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17812 wiphy->frag_threshold;
17813
17814 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017815 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017816 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017817 hddLog(VOS_TRACE_LEVEL_ERROR,
17818 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017819 frag_threshold);
17820 return -EINVAL;
17821 }
17822
17823 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
17824 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017825 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017826 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017827 hddLog(VOS_TRACE_LEVEL_ERROR,
17828 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017829 __func__, frag_threshold);
17830 return -EIO;
17831 }
17832
17833 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
17834 frag_threshold);
17835 }
17836
17837 if ((changed & WIPHY_PARAM_RETRY_SHORT)
17838 || (changed & WIPHY_PARAM_RETRY_LONG))
17839 {
17840 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
17841 wiphy->retry_short :
17842 wiphy->retry_long;
17843
17844 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17845 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17846 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017847 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017848 __func__, retry_value);
17849 return -EINVAL;
17850 }
17851
17852 if (changed & WIPHY_PARAM_RETRY_SHORT)
17853 {
17854 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17855 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017856 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017857 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017858 hddLog(VOS_TRACE_LEVEL_ERROR,
17859 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017860 __func__, retry_value);
17861 return -EIO;
17862 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017863 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017864 __func__, retry_value);
17865 }
17866 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17867 {
17868 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17869 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017870 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017871 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017872 hddLog(VOS_TRACE_LEVEL_ERROR,
17873 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017874 __func__, retry_value);
17875 return -EIO;
17876 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017877 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017878 __func__, retry_value);
17879 }
17880 }
17881
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017882 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017883 return 0;
17884}
17885
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017886static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17887 u32 changed)
17888{
17889 int ret;
17890
17891 vos_ssr_protect(__func__);
17892 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17893 vos_ssr_unprotect(__func__);
17894
17895 return ret;
17896}
17897
Jeff Johnson295189b2012-06-20 16:38:30 -070017898/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017899 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017900 * This function is used to set the txpower
17901 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017902static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017903#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17904 struct wireless_dev *wdev,
17905#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017906#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017907 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017908#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017909 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017910#endif
17911 int dbm)
17912{
17913 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017914 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017915 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17916 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017917 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017918
17919 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017920
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017921 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17922 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17923 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017924 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017925 if (0 != status)
17926 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017927 return status;
17928 }
17929
17930 hHal = pHddCtx->hHal;
17931
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017932 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17933 dbm, ccmCfgSetCallback,
17934 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017935 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017936 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017937 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17938 return -EIO;
17939 }
17940
17941 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17942 dbm);
17943
17944 switch(type)
17945 {
17946 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17947 /* Fall through */
17948 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17949 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17950 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017951 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17952 __func__);
17953 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017954 }
17955 break;
17956 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017957 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017958 __func__);
17959 return -EOPNOTSUPP;
17960 break;
17961 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017962 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17963 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017964 return -EIO;
17965 }
17966
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017967 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017968 return 0;
17969}
17970
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017971static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17972#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17973 struct wireless_dev *wdev,
17974#endif
17975#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17976 enum tx_power_setting type,
17977#else
17978 enum nl80211_tx_power_setting type,
17979#endif
17980 int dbm)
17981{
17982 int ret;
17983 vos_ssr_protect(__func__);
17984 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17985#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17986 wdev,
17987#endif
17988#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17989 type,
17990#else
17991 type,
17992#endif
17993 dbm);
17994 vos_ssr_unprotect(__func__);
17995
17996 return ret;
17997}
17998
Jeff Johnson295189b2012-06-20 16:38:30 -070017999/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018000 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070018001 * This function is used to read the txpower
18002 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018003static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070018004#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18005 struct wireless_dev *wdev,
18006#endif
18007 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070018008{
18009
18010 hdd_adapter_t *pAdapter;
18011 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018012 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018013
Jeff Johnsone7245742012-09-05 17:12:55 -070018014 ENTER();
18015
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018016 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018017 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018018 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018019 *dbm = 0;
18020 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018021 }
18022
Jeff Johnson295189b2012-06-20 16:38:30 -070018023 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
18024 if (NULL == pAdapter)
18025 {
18026 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
18027 return -ENOENT;
18028 }
18029
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018030 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18031 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
18032 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070018033 wlan_hdd_get_classAstats(pAdapter);
18034 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
18035
Jeff Johnsone7245742012-09-05 17:12:55 -070018036 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018037 return 0;
18038}
18039
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018040static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
18041#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18042 struct wireless_dev *wdev,
18043#endif
18044 int *dbm)
18045{
18046 int ret;
18047
18048 vos_ssr_protect(__func__);
18049 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
18050#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18051 wdev,
18052#endif
18053 dbm);
18054 vos_ssr_unprotect(__func__);
18055
18056 return ret;
18057}
18058
Dustin Brown8c1d4092017-07-28 18:08:01 +053018059/*
18060 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
18061 * @stats: summary stats to use as a source
18062 * @info: kernel station_info struct to use as a destination
18063 *
18064 * Return: None
18065 */
18066static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
18067 struct station_info *info)
18068{
18069 int i;
18070
18071 info->rx_packets = stats->rx_frm_cnt;
18072 info->tx_packets = 0;
18073 info->tx_retries = 0;
18074 info->tx_failed = 0;
18075
18076 for (i = 0; i < 4; ++i) {
18077 info->tx_packets += stats->tx_frm_cnt[i];
18078 info->tx_retries += stats->multiple_retry_cnt[i];
18079 info->tx_failed += stats->fail_cnt[i];
18080 }
18081
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018082#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18083 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018084 info->filled |= STATION_INFO_TX_PACKETS |
18085 STATION_INFO_TX_RETRIES |
18086 STATION_INFO_TX_FAILED |
18087 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018088#else
18089 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
18090 BIT(NL80211_STA_INFO_TX_RETRIES) |
18091 BIT(NL80211_STA_INFO_TX_FAILED) |
18092 BIT(NL80211_STA_INFO_RX_PACKETS);
18093#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053018094}
18095
18096/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018097 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
18098 * @adapter: sap adapter pointer
18099 * @staid: station id of the client
18100 * @rssi: rssi value to fill
18101 *
18102 * Return: None
18103 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053018104void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018105wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
18106{
18107 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
18108
18109 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
18110}
18111
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018112#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18113 !defined(WITH_BACKPORTS)
18114static inline void wlan_hdd_fill_station_info_signal(struct station_info
18115 *sinfo)
18116{
18117 sinfo->filled |= STATION_INFO_SIGNAL;
18118}
18119#else
18120static inline void wlan_hdd_fill_station_info_signal(struct station_info
18121 *sinfo)
18122{
18123 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
18124}
18125#endif
18126
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018127/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053018128 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
18129 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018130 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053018131 * @info: kernel station_info struct to populate
18132 *
18133 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
18134 * support "station dump" and "station get" for SAP vdevs, even though they
18135 * aren't technically stations.
18136 *
18137 * Return: errno
18138 */
18139static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018140wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
18141#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18142 const u8* mac,
18143#else
18144 u8* mac,
18145#endif
18146 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018147{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018148 v_MACADDR_t *peerMacAddr;
18149 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018150 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018151 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018152
18153 status = wlan_hdd_get_station_stats(adapter);
18154 if (!VOS_IS_STATUS_SUCCESS(status)) {
18155 hddLog(VOS_TRACE_LEVEL_ERROR,
18156 "Failed to get SAP stats; status:%d", status);
18157 return 0;
18158 }
18159
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018160 peerMacAddr = (v_MACADDR_t *)mac;
18161 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
18162 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
18163 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
18164
18165 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
18166 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018167 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018168 }
18169
Dustin Brown8c1d4092017-07-28 18:08:01 +053018170 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
18171
18172 return 0;
18173}
18174
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018175static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018176#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18177 const u8* mac,
18178#else
18179 u8* mac,
18180#endif
18181 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070018182{
18183 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
18184 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18185 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053018186 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018187
18188 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
18189 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070018190
18191 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
18192 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
18193 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
18194 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
18195 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
18196 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
18197 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018198 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018199 tANI_U16 myRate;
18200 tANI_U16 currentRate = 0;
18201 tANI_U8 maxSpeedMCS = 0;
18202 tANI_U8 maxMCSIdx = 0;
18203 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053018204 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070018205 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018206 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018207
Leo Chang6f8870f2013-03-26 18:11:36 -070018208#ifdef WLAN_FEATURE_11AC
18209 tANI_U32 vht_mcs_map;
18210 eDataRate11ACMaxMcs vhtMaxMcs;
18211#endif /* WLAN_FEATURE_11AC */
18212
Jeff Johnsone7245742012-09-05 17:12:55 -070018213 ENTER();
18214
Dustin Brown8c1d4092017-07-28 18:08:01 +053018215 status = wlan_hdd_validate_context(pHddCtx);
18216 if (0 != status)
18217 {
18218 return status;
18219 }
18220
18221 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018222 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053018223
Jeff Johnson295189b2012-06-20 16:38:30 -070018224 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
18225 (0 == ssidlen))
18226 {
18227 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
18228 " Invalid ssidlen, %d", __func__, ssidlen);
18229 /*To keep GUI happy*/
18230 return 0;
18231 }
18232
Mukul Sharma811205f2014-07-09 21:07:30 +053018233 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
18234 {
18235 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18236 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053018237 /* return a cached value */
18238 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053018239 return 0;
18240 }
18241
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053018242 wlan_hdd_get_station_stats(pAdapter);
18243 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018244
Kiet Lam3b17fc82013-09-27 05:24:08 +053018245 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018246 wlan_hdd_get_snr(pAdapter, &snr);
18247 pHddStaCtx->conn_info.signal = sinfo->signal;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018248 pHddStaCtx->cache_conn_info.signal = sinfo->signal;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018249 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018250 pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018251 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053018252
c_hpothu09f19542014-05-30 21:53:31 +053018253 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053018254 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
18255 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053018256 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053018257 {
18258 rate_flags = pAdapter->maxRateFlags;
18259 }
c_hpothu44ff4e02014-05-08 00:13:57 +053018260
Jeff Johnson295189b2012-06-20 16:38:30 -070018261 //convert to the UI units of 100kbps
18262 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
18263
18264#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070018265 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 -070018266 sinfo->signal,
18267 pCfg->reportMaxLinkSpeed,
18268 myRate,
18269 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018270 (int) pCfg->linkSpeedRssiMid,
18271 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070018272 (int) rate_flags,
18273 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070018274#endif //LINKSPEED_DEBUG_ENABLED
18275
Hanumanth Reddy Pothula596b8b32018-05-01 20:17:38 +053018276#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || defined(WITH_BACKPORTS)
18277 /* assume basic BW. anything else will override this later */
18278 sinfo->txrate.bw = RATE_INFO_BW_20;
18279#endif
18280
Jeff Johnson295189b2012-06-20 16:38:30 -070018281 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
18282 {
18283 // we do not want to necessarily report the current speed
18284 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
18285 {
18286 // report the max possible speed
18287 rssidx = 0;
18288 }
18289 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
18290 {
18291 // report the max possible speed with RSSI scaling
18292 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
18293 {
18294 // report the max possible speed
18295 rssidx = 0;
18296 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018297 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070018298 {
18299 // report middle speed
18300 rssidx = 1;
18301 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018302 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
18303 {
18304 // report middle speed
18305 rssidx = 2;
18306 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018307 else
18308 {
18309 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018310 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070018311 }
18312 }
18313 else
18314 {
18315 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
18316 hddLog(VOS_TRACE_LEVEL_ERROR,
18317 "%s: Invalid value for reportMaxLinkSpeed: %u",
18318 __func__, pCfg->reportMaxLinkSpeed);
18319 rssidx = 0;
18320 }
18321
18322 maxRate = 0;
18323
18324 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018325 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
18326 OperationalRates, &ORLeng))
18327 {
18328 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18329 /*To keep GUI happy*/
18330 return 0;
18331 }
18332
Jeff Johnson295189b2012-06-20 16:38:30 -070018333 for (i = 0; i < ORLeng; i++)
18334 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018335 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018336 {
18337 /* Validate Rate Set */
18338 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
18339 {
18340 currentRate = supported_data_rate[j].supported_rate[rssidx];
18341 break;
18342 }
18343 }
18344 /* Update MAX rate */
18345 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18346 }
18347
18348 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018349 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
18350 ExtendedRates, &ERLeng))
18351 {
18352 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18353 /*To keep GUI happy*/
18354 return 0;
18355 }
18356
Jeff Johnson295189b2012-06-20 16:38:30 -070018357 for (i = 0; i < ERLeng; i++)
18358 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018359 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018360 {
18361 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
18362 {
18363 currentRate = supported_data_rate[j].supported_rate[rssidx];
18364 break;
18365 }
18366 }
18367 /* Update MAX rate */
18368 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18369 }
c_hpothu79aab322014-07-14 21:11:01 +053018370
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018371 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053018372 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018373 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053018374 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070018375 {
c_hpothu79aab322014-07-14 21:11:01 +053018376 if (rate_flags & eHAL_TX_RATE_VHT80)
18377 mode = 2;
18378 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
18379 mode = 1;
18380 else
18381 mode = 0;
18382
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018383 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
18384 MCSRates, &MCSLeng))
18385 {
18386 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18387 /*To keep GUI happy*/
18388 return 0;
18389 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018390 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070018391#ifdef WLAN_FEATURE_11AC
18392 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018393 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070018394 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018395 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018396 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070018397 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070018398 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018399 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018400 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018401 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070018402 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018403 maxMCSIdx = 7;
18404 }
18405 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
18406 {
18407 maxMCSIdx = 8;
18408 }
18409 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
18410 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018411 //VHT20 is supporting 0~8
18412 if (rate_flags & eHAL_TX_RATE_VHT20)
18413 maxMCSIdx = 8;
18414 else
18415 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070018416 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018417
c_hpothu79aab322014-07-14 21:11:01 +053018418 if (0 != rssidx)/*check for scaled */
18419 {
18420 //get middle rate MCS index if rssi=1/2
18421 for (i=0; i <= maxMCSIdx; i++)
18422 {
18423 if (sinfo->signal <= rssiMcsTbl[mode][i])
18424 {
18425 maxMCSIdx = i;
18426 break;
18427 }
18428 }
18429 }
18430
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018431 if (rate_flags & eHAL_TX_RATE_VHT80)
18432 {
18433 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
18434 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
18435 }
18436 else if (rate_flags & eHAL_TX_RATE_VHT40)
18437 {
18438 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
18439 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
18440 }
18441 else if (rate_flags & eHAL_TX_RATE_VHT20)
18442 {
18443 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
18444 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
18445 }
18446
Leo Chang6f8870f2013-03-26 18:11:36 -070018447 maxSpeedMCS = 1;
18448 if (currentRate > maxRate)
18449 {
18450 maxRate = currentRate;
18451 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018452
Leo Chang6f8870f2013-03-26 18:11:36 -070018453 }
18454 else
18455#endif /* WLAN_FEATURE_11AC */
18456 {
18457 if (rate_flags & eHAL_TX_RATE_HT40)
18458 {
18459 rateFlag |= 1;
18460 }
18461 if (rate_flags & eHAL_TX_RATE_SGI)
18462 {
18463 rateFlag |= 2;
18464 }
18465
Girish Gowli01abcee2014-07-31 20:18:55 +053018466 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053018467 if (rssidx == 1 || rssidx == 2)
18468 {
18469 //get middle rate MCS index if rssi=1/2
18470 for (i=0; i <= 7; i++)
18471 {
18472 if (sinfo->signal <= rssiMcsTbl[mode][i])
18473 {
18474 temp = i+1;
18475 break;
18476 }
18477 }
18478 }
c_hpothu79aab322014-07-14 21:11:01 +053018479
18480 for (i = 0; i < MCSLeng; i++)
18481 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018482 for (j = 0; j < temp; j++)
18483 {
18484 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
18485 {
18486 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018487 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018488 break;
18489 }
18490 }
18491 if ((j < temp) && (currentRate > maxRate))
18492 {
18493 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070018494 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018495 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018496 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018497 }
18498 }
18499
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018500 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
18501 {
18502 maxRate = myRate;
18503 maxSpeedMCS = 1;
18504 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18505 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018506 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053018507 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070018508 {
18509 maxRate = myRate;
18510 if (rate_flags & eHAL_TX_RATE_LEGACY)
18511 {
18512 maxSpeedMCS = 0;
18513 }
18514 else
18515 {
18516 maxSpeedMCS = 1;
18517 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18518 }
18519 }
18520
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018521 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070018522 {
18523 sinfo->txrate.legacy = maxRate;
18524#ifdef LINKSPEED_DEBUG_ENABLED
18525 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
18526#endif //LINKSPEED_DEBUG_ENABLED
18527 }
18528 else
18529 {
18530 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070018531#ifdef WLAN_FEATURE_11AC
18532 sinfo->txrate.nss = 1;
18533 if (rate_flags & eHAL_TX_RATE_VHT80)
18534 {
18535 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018536#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18537 defined(WITH_BACKPORTS)
18538 sinfo->txrate.bw = RATE_INFO_BW_80;
18539#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018540 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018541#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018542 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018543 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070018544 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018545 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018546#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18547 defined(WITH_BACKPORTS)
18548 sinfo->txrate.bw = RATE_INFO_BW_40;
18549#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018550 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018551#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018552 }
18553 else if (rate_flags & eHAL_TX_RATE_VHT20)
18554 {
18555 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18556 }
18557#endif /* WLAN_FEATURE_11AC */
18558 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
18559 {
18560 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18561 if (rate_flags & eHAL_TX_RATE_HT40)
18562 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018563#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18564 defined(WITH_BACKPORTS)
18565 sinfo->txrate.bw = RATE_INFO_BW_40;
18566#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018567 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018568#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018569 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018570 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018571 if (rate_flags & eHAL_TX_RATE_SGI)
18572 {
18573 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18574 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018575
Jeff Johnson295189b2012-06-20 16:38:30 -070018576#ifdef LINKSPEED_DEBUG_ENABLED
18577 pr_info("Reporting MCS rate %d flags %x\n",
18578 sinfo->txrate.mcs,
18579 sinfo->txrate.flags );
18580#endif //LINKSPEED_DEBUG_ENABLED
18581 }
18582 }
18583 else
18584 {
18585 // report current rate instead of max rate
18586
18587 if (rate_flags & eHAL_TX_RATE_LEGACY)
18588 {
18589 //provide to the UI in units of 100kbps
18590 sinfo->txrate.legacy = myRate;
18591#ifdef LINKSPEED_DEBUG_ENABLED
18592 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
18593#endif //LINKSPEED_DEBUG_ENABLED
18594 }
18595 else
18596 {
18597 //must be MCS
18598 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018599#ifdef WLAN_FEATURE_11AC
18600 sinfo->txrate.nss = 1;
18601 if (rate_flags & eHAL_TX_RATE_VHT80)
18602 {
18603 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18604 }
18605 else
18606#endif /* WLAN_FEATURE_11AC */
18607 {
18608 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18609 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018610 if (rate_flags & eHAL_TX_RATE_SGI)
18611 {
18612 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18613 }
18614 if (rate_flags & eHAL_TX_RATE_HT40)
18615 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018616#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18617 defined(WITH_BACKPORTS)
18618 sinfo->txrate.bw = RATE_INFO_BW_40;
18619#else
Jeff Johnson295189b2012-06-20 16:38:30 -070018620 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018621#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018622 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018623#ifdef WLAN_FEATURE_11AC
18624 else if (rate_flags & eHAL_TX_RATE_VHT80)
18625 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018626#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18627 defined(WITH_BACKPORTS)
18628 sinfo->txrate.bw = RATE_INFO_BW_80;
18629#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018630 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018631#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018632 }
18633#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018634#ifdef LINKSPEED_DEBUG_ENABLED
18635 pr_info("Reporting actual MCS rate %d flags %x\n",
18636 sinfo->txrate.mcs,
18637 sinfo->txrate.flags );
18638#endif //LINKSPEED_DEBUG_ENABLED
18639 }
18640 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018641
18642#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18643 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018644 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018645#else
18646 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18647#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018648
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018649 sinfo->tx_packets =
18650 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18651 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18652 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18653 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18654
18655 sinfo->tx_retries =
18656 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18657 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18658 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18659 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18660
18661 sinfo->tx_failed =
18662 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18663 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18664 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18665 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18666
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018667#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18668 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018669 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018670 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018671 STATION_INFO_TX_PACKETS |
18672 STATION_INFO_TX_RETRIES |
18673 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018674#else
18675 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18676 BIT(NL80211_STA_INFO_TX_PACKETS) |
18677 BIT(NL80211_STA_INFO_TX_RETRIES) |
18678 BIT(NL80211_STA_INFO_TX_FAILED);
18679#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018680
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018681 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018682
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018683 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18684 &sinfo->txrate, sizeof(sinfo->txrate));
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018685 vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate,
18686 &sinfo->txrate, sizeof(sinfo->txrate));
18687
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018688 if (rate_flags & eHAL_TX_RATE_LEGACY)
18689 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18690 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18691 sinfo->rx_packets);
18692 else
18693 hddLog(LOG1,
18694 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18695 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18696 sinfo->tx_packets, sinfo->rx_packets);
18697
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018698 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18699 TRACE_CODE_HDD_CFG80211_GET_STA,
18700 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018701 EXIT();
18702 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018703}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018704#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18705static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18706 const u8* mac, struct station_info *sinfo)
18707#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018708static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18709 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018710#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018711{
18712 int ret;
18713
18714 vos_ssr_protect(__func__);
18715 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18716 vos_ssr_unprotect(__func__);
18717
18718 return ret;
18719}
18720
18721static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018722 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018723{
18724 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018725 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018726 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018727 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018728
Jeff Johnsone7245742012-09-05 17:12:55 -070018729 ENTER();
18730
Jeff Johnson295189b2012-06-20 16:38:30 -070018731 if (NULL == pAdapter)
18732 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018733 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018734 return -ENODEV;
18735 }
18736
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018737 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18738 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18739 pAdapter->sessionId, timeout));
18740
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018741 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018742 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018743 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018744 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018745 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018746 }
18747
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018748 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
18749 (TRUE == pHddCtx->hdd_wlan_suspended) &&
18750 (pHddCtx->cfg_ini->fhostArpOffload) &&
18751 (eConnectionState_Associated ==
18752 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
18753 {
Amar Singhald53568e2013-09-26 11:03:45 -070018754
18755 hddLog(VOS_TRACE_LEVEL_INFO,
18756 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053018757 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018758 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18759 {
18760 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018761 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018762 __func__, vos_status);
18763 }
18764 }
18765
Jeff Johnson295189b2012-06-20 16:38:30 -070018766 /**The get power cmd from the supplicant gets updated by the nl only
18767 *on successful execution of the function call
18768 *we are oppositely mapped w.r.t mode in the driver
18769 **/
18770 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
18771
18772 if (VOS_STATUS_E_FAILURE == vos_status)
18773 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018774 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18775 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018776 return -EINVAL;
18777 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018778 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018779 return 0;
18780}
18781
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018782static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
18783 struct net_device *dev, bool mode, int timeout)
18784{
18785 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018786
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018787 vos_ssr_protect(__func__);
18788 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
18789 vos_ssr_unprotect(__func__);
18790
18791 return ret;
18792}
Sushant Kaushik084f6592015-09-10 13:11:56 +053018793
Jeff Johnson295189b2012-06-20 16:38:30 -070018794#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018795static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
18796 struct net_device *netdev,
18797 u8 key_index)
18798{
18799 ENTER();
18800 return 0;
18801}
18802
Jeff Johnson295189b2012-06-20 16:38:30 -070018803static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018804 struct net_device *netdev,
18805 u8 key_index)
18806{
18807 int ret;
18808 vos_ssr_protect(__func__);
18809 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
18810 vos_ssr_unprotect(__func__);
18811 return ret;
18812}
18813#endif //LINUX_VERSION_CODE
18814
18815#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18816static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18817 struct net_device *dev,
18818 struct ieee80211_txq_params *params)
18819{
18820 ENTER();
18821 return 0;
18822}
18823#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18824static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18825 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018826{
Jeff Johnsone7245742012-09-05 17:12:55 -070018827 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070018828 return 0;
18829}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018830#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070018831
18832#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18833static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018834 struct net_device *dev,
18835 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018836{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018837 int ret;
18838
18839 vos_ssr_protect(__func__);
18840 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
18841 vos_ssr_unprotect(__func__);
18842 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018843}
18844#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18845static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
18846 struct ieee80211_txq_params *params)
18847{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018848 int ret;
18849
18850 vos_ssr_protect(__func__);
18851 ret = __wlan_hdd_set_txq_params(wiphy, params);
18852 vos_ssr_unprotect(__func__);
18853 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018854}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018855#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018856
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018857static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018858 struct net_device *dev,
18859 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070018860{
18861 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018862 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018863 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018864 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018865 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018866 v_CONTEXT_t pVosContext = NULL;
18867 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018868
Jeff Johnsone7245742012-09-05 17:12:55 -070018869 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018870
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018871 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070018872 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018873 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018874 return -EINVAL;
18875 }
18876
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018877 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18878 TRACE_CODE_HDD_CFG80211_DEL_STA,
18879 pAdapter->sessionId, pAdapter->device_mode));
18880
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018881 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18882 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018883 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018884 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018885 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018886 }
18887
Jeff Johnson295189b2012-06-20 16:38:30 -070018888 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018889 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018890 )
18891 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018892 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
18893 pSapCtx = VOS_GET_SAP_CB(pVosContext);
18894 if(pSapCtx == NULL){
18895 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18896 FL("psapCtx is NULL"));
18897 return -ENOENT;
18898 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053018899 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
18900 {
18901 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
18902 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
18903 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
18904 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018905 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070018906 {
18907 v_U16_t i;
18908 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
18909 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018910 if ((pSapCtx->aStaInfo[i].isUsed) &&
18911 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070018912 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018913 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018914 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018915 ETHER_ADDR_LEN);
18916
Jeff Johnson295189b2012-06-20 16:38:30 -070018917 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018918 "%s: Delete STA with MAC::"
18919 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018920 __func__,
18921 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18922 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018923 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018924 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018925 }
18926 }
18927 }
18928 else
18929 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018930
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018931 vos_status = hdd_softap_GetStaId(pAdapter,
18932 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018933 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18934 {
18935 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018936 "%s: Skip this DEL STA as this is not used::"
18937 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018938 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018939 return -ENOENT;
18940 }
18941
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018942 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018943 {
18944 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018945 "%s: Skip this DEL STA as deauth is in progress::"
18946 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018947 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018948 return -ENOENT;
18949 }
18950
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018951 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018952
Jeff Johnson295189b2012-06-20 16:38:30 -070018953 hddLog(VOS_TRACE_LEVEL_INFO,
18954 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018955 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018956 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018957 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018958
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018959 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018960 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18961 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018962 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018963 hddLog(VOS_TRACE_LEVEL_INFO,
18964 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018965 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018966 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018967 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018968 return -ENOENT;
18969 }
18970
Jeff Johnson295189b2012-06-20 16:38:30 -070018971 }
18972 }
18973
18974 EXIT();
18975
18976 return 0;
18977}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018978
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018979#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018980int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018981 struct net_device *dev,
18982 struct station_del_parameters *param)
18983#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018984#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018985int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018986 struct net_device *dev, const u8 *mac)
18987#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018988int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018989 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018990#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018991#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018992{
18993 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018994 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018995
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018996 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018997
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018998#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018999 if (NULL == param) {
19000 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019001 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019002 return -EINVAL;
19003 }
19004
19005 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
19006 param->subtype, &delStaParams);
19007
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019008#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053019009 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019010 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019011#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019012 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
19013
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019014 vos_ssr_unprotect(__func__);
19015
19016 return ret;
19017}
19018
19019static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019020 struct net_device *dev,
19021#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19022 const u8 *mac,
19023#else
19024 u8 *mac,
19025#endif
19026 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019027{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019028 hdd_adapter_t *pAdapter;
19029 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019030 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019031#ifdef FEATURE_WLAN_TDLS
19032 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019033
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019034 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019035
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019036 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19037 if (NULL == pAdapter)
19038 {
19039 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19040 "%s: Adapter is NULL",__func__);
19041 return -EINVAL;
19042 }
19043 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19044 status = wlan_hdd_validate_context(pHddCtx);
19045 if (0 != status)
19046 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019047 return status;
19048 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019049
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019050 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19051 TRACE_CODE_HDD_CFG80211_ADD_STA,
19052 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019053 mask = params->sta_flags_mask;
19054
19055 set = params->sta_flags_set;
19056
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019058 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
19059 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019060
19061 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
19062 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080019063 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019064 }
19065 }
19066#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019067 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019068 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070019069}
19070
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019071#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19072static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19073 struct net_device *dev, const u8 *mac,
19074 struct station_parameters *params)
19075#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019076static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19077 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019078#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019079{
19080 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019081
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019082 vos_ssr_protect(__func__);
19083 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
19084 vos_ssr_unprotect(__func__);
19085
19086 return ret;
19087}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019088#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070019089
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019090static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070019091 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019092{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019093 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19094 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019095 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019096 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019097 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019098 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070019099
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019100 ENTER();
19101
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019102 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019103 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019104 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019105 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019106 return -EINVAL;
19107 }
19108
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019109 if (!pmksa) {
19110 hddLog(LOGE, FL("pmksa is NULL"));
19111 return -EINVAL;
19112 }
19113
19114 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070019115 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019116 pmksa->bssid, pmksa->pmkid);
19117 return -EINVAL;
19118 }
19119
19120 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
19121 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19122
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019123 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19124 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019125 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019126 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019127 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019128 }
19129
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019130 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019131 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19132
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019133 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
19134 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019135
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019136 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019137 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019138 &pmk_id, 1, FALSE);
19139
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019140 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19141 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
19142 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019143
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019144 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019145 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019146}
19147
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019148static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
19149 struct cfg80211_pmksa *pmksa)
19150{
19151 int ret;
19152
19153 vos_ssr_protect(__func__);
19154 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
19155 vos_ssr_unprotect(__func__);
19156
19157 return ret;
19158}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019159
Wilson Yang6507c4e2013-10-01 20:11:19 -070019160
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019161static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070019162 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019163{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019164 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19165 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019166 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019167 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019168
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019169 ENTER();
19170
Wilson Yang6507c4e2013-10-01 20:11:19 -070019171 /* Validate pAdapter */
19172 if (NULL == pAdapter)
19173 {
19174 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
19175 return -EINVAL;
19176 }
19177
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019178 if (!pmksa) {
19179 hddLog(LOGE, FL("pmksa is NULL"));
19180 return -EINVAL;
19181 }
19182
19183 if (!pmksa->bssid) {
19184 hddLog(LOGE, FL("pmksa->bssid is NULL"));
19185 return -EINVAL;
19186 }
19187
Kiet Lam98c46a12014-10-31 15:34:57 -070019188 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
19189 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19190
Wilson Yang6507c4e2013-10-01 20:11:19 -070019191 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19192 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019193 if (0 != status)
19194 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019195 return status;
19196 }
19197
19198 /*Retrieve halHandle*/
19199 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19200
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019201 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19202 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
19203 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019204 /* Delete the PMKID CSR cache */
19205 if (eHAL_STATUS_SUCCESS !=
19206 sme_RoamDelPMKIDfromCache(halHandle,
19207 pAdapter->sessionId, pmksa->bssid, FALSE)) {
19208 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
19209 MAC_ADDR_ARRAY(pmksa->bssid));
19210 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019211 }
19212
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019213 EXIT();
19214 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019215}
19216
Wilson Yang6507c4e2013-10-01 20:11:19 -070019217
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019218static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
19219 struct cfg80211_pmksa *pmksa)
19220{
19221 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019222
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019223 vos_ssr_protect(__func__);
19224 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
19225 vos_ssr_unprotect(__func__);
19226
19227 return ret;
19228
19229}
19230
19231static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019232{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019233 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19234 tHalHandle halHandle;
19235 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019236 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019237
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019238 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070019239
19240 /* Validate pAdapter */
19241 if (NULL == pAdapter)
19242 {
19243 hddLog(VOS_TRACE_LEVEL_ERROR,
19244 "%s: Invalid Adapter" ,__func__);
19245 return -EINVAL;
19246 }
19247
19248 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19249 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019250 if (0 != status)
19251 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019252 return status;
19253 }
19254
19255 /*Retrieve halHandle*/
19256 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19257
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019258 /* Flush the PMKID cache in CSR */
19259 if (eHAL_STATUS_SUCCESS !=
19260 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
19261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
19262 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019263 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019264 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080019265 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019266}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019267
19268static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
19269{
19270 int ret;
19271
19272 vos_ssr_protect(__func__);
19273 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
19274 vos_ssr_unprotect(__func__);
19275
19276 return ret;
19277}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019278#endif
19279
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019280#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019281static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19282 struct net_device *dev,
19283 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019284{
19285 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19286 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019287 hdd_context_t *pHddCtx;
19288 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019289
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019290 ENTER();
19291
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019292 if (NULL == pAdapter)
19293 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019294 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019295 return -ENODEV;
19296 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019297 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19298 ret = wlan_hdd_validate_context(pHddCtx);
19299 if (0 != ret)
19300 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019301 return ret;
19302 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019303 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019304 if (NULL == pHddStaCtx)
19305 {
19306 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
19307 return -EINVAL;
19308 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019309
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019310 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19311 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
19312 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019313 // Added for debug on reception of Re-assoc Req.
19314 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
19315 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019316 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019317 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080019318 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019319 }
19320
19321#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080019322 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019323 ftie->ie_len);
19324#endif
19325
19326 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053019327 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
19328 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019329 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019330
19331 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019332 return 0;
19333}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019334
19335static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19336 struct net_device *dev,
19337 struct cfg80211_update_ft_ies_params *ftie)
19338{
19339 int ret;
19340
19341 vos_ssr_protect(__func__);
19342 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
19343 vos_ssr_unprotect(__func__);
19344
19345 return ret;
19346}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019347#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019348
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019349#ifdef FEATURE_WLAN_SCAN_PNO
19350
19351void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
19352 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
19353{
19354 int ret;
19355 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
19356 hdd_context_t *pHddCtx;
19357
Nirav Shah80830bf2013-12-31 16:35:12 +053019358 ENTER();
19359
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019360 if (NULL == pAdapter)
19361 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019363 "%s: HDD adapter is Null", __func__);
19364 return ;
19365 }
19366
19367 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19368 if (NULL == pHddCtx)
19369 {
19370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19371 "%s: HDD context is Null!!!", __func__);
19372 return ;
19373 }
19374
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019375 spin_lock(&pHddCtx->schedScan_lock);
19376 if (TRUE == pHddCtx->isWiphySuspended)
19377 {
19378 pHddCtx->isSchedScanUpdatePending = TRUE;
19379 spin_unlock(&pHddCtx->schedScan_lock);
19380 hddLog(VOS_TRACE_LEVEL_INFO,
19381 "%s: Update cfg80211 scan database after it resume", __func__);
19382 return ;
19383 }
19384 spin_unlock(&pHddCtx->schedScan_lock);
19385
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019386 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
19387
19388 if (0 > ret)
19389 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053019390 else
19391 {
19392 /* Acquire wakelock to handle the case where APP's tries to suspend
19393 * immediatly after the driver gets connect request(i.e after pno)
19394 * from supplicant, this result in app's is suspending and not able
19395 * to process the connect request to AP */
19396 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
19397 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019398 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19400 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019401}
19402
19403/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019404 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019405 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019406 */
19407static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
19408{
19409 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
19410 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019411 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019412 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19413 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053019414
19415 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
19416 {
19417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19418 "%s: PNO is allowed only in STA interface", __func__);
19419 return eHAL_STATUS_FAILURE;
19420 }
19421
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019422 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
19423
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019424 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053019425 * active sessions. PNO is allowed only in case when sap session
19426 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019427 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019428 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
19429 {
19430 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019431 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019432
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019433 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
19434 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
19435 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
19436 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053019437 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
19438 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053019439 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019440 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019441 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019442 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019443 }
19444 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19445 pAdapterNode = pNext;
19446 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019447 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019448}
19449
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019450void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
19451{
19452 hdd_adapter_t *pAdapter = callbackContext;
19453 hdd_context_t *pHddCtx;
19454
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019455 ENTER();
19456
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019457 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
19458 {
19459 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19460 FL("Invalid adapter or adapter has invalid magic"));
19461 return;
19462 }
19463
19464 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19465 if (0 != wlan_hdd_validate_context(pHddCtx))
19466 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019467 return;
19468 }
19469
c_hpothub53c45d2014-08-18 16:53:14 +053019470 if (VOS_STATUS_SUCCESS != status)
19471 {
19472 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019473 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053019474 pHddCtx->isPnoEnable = FALSE;
19475 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019476
19477 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
19478 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019479 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019480}
19481
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019482#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
19483 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
19484/**
19485 * hdd_config_sched_scan_plan() - configures the sched scan plans
19486 * from the framework.
19487 * @pno_req: pointer to PNO scan request
19488 * @request: pointer to scan request from framework
19489 *
19490 * Return: None
19491 */
19492static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
19493 struct cfg80211_sched_scan_request *request,
19494 hdd_context_t *hdd_ctx)
19495{
19496 v_U32_t i = 0;
19497
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019498 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019499 for (i = 0; i < request->n_scan_plans; i++)
19500 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019501 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
19502 request->scan_plans[i].iterations;
19503 pno_req->scanTimers.aTimerValues[i].uTimerValue =
19504 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019505 }
19506}
19507#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019508static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019509 struct cfg80211_sched_scan_request *request,
19510 hdd_context_t *hdd_ctx)
19511{
19512 v_U32_t i, temp_int;
19513 /* Driver gets only one time interval which is hardcoded in
19514 * supplicant for 10000ms. Taking power consumption into account 6
19515 * timers will be used, Timervalue is increased exponentially
19516 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
19517 * timer is configurable through INI param gPNOScanTimerRepeatValue.
19518 * If it is set to 0 only one timer will be used and PNO scan cycle
19519 * will be repeated after each interval specified by supplicant
19520 * till PNO is disabled.
19521 */
19522 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019523 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019524 HDD_PNO_SCAN_TIMERS_SET_ONE;
19525 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019526 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019527 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
19528
19529 temp_int = (request->interval)/1000;
19530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19531 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
19532 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019533 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019534 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019535 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019536 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019537 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019538 temp_int *= 2;
19539 }
19540 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019541 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019542}
19543#endif
19544
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019545/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019546 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
19547 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019548 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019549static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019550 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19551{
19552 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019553 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019554 hdd_context_t *pHddCtx;
19555 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019556 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053019557 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
19558 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019559 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
19560 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019561 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019562 hdd_config_t *pConfig = NULL;
19563 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019564
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019565 ENTER();
19566
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019567 if (NULL == pAdapter)
19568 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019570 "%s: HDD adapter is Null", __func__);
19571 return -ENODEV;
19572 }
19573
19574 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019575 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019576
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019577 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019578 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019579 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019580 }
19581
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019582 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019583 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19584 if (NULL == hHal)
19585 {
19586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19587 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019588 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019589 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019590 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19591 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
19592 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019593 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053019594 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019595 {
19596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19597 "%s: aborting the existing scan is unsuccessfull", __func__);
19598 return -EBUSY;
19599 }
19600
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019601 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019602 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019604 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019605 return -EBUSY;
19606 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019607
c_hpothu37f21312014-04-09 21:49:54 +053019608 if (TRUE == pHddCtx->isPnoEnable)
19609 {
19610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19611 FL("already PNO is enabled"));
19612 return -EBUSY;
19613 }
c_hpothu225aa7c2014-10-22 17:45:13 +053019614
19615 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
19616 {
19617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19618 "%s: abort ROC failed ", __func__);
19619 return -EBUSY;
19620 }
19621
c_hpothu37f21312014-04-09 21:49:54 +053019622 pHddCtx->isPnoEnable = TRUE;
19623
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019624 pnoRequest.enable = 1; /*Enable PNO */
19625 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019626
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019627 if (( !pnoRequest.ucNetworksCount ) ||
19628 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019629 {
19630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019631 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019632 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019633 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019634 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019635 goto error;
19636 }
19637
19638 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
19639 {
19640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019641 "%s: Incorrect number of channels %d",
19642 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019643 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019644 goto error;
19645 }
19646
19647 /* Framework provides one set of channels(all)
19648 * common for all saved profile */
19649 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
19650 channels_allowed, &num_channels_allowed))
19651 {
19652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19653 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019654 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019655 goto error;
19656 }
19657 /* Checking each channel against allowed channel list */
19658 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053019659 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019660 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019661 char chList [(request->n_channels*5)+1];
19662 int len;
19663 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019664 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019665 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019666 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019667 if (request->channels[i]->hw_value == channels_allowed[indx])
19668 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019669 if ((!pConfig->enableDFSPnoChnlScan) &&
19670 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
19671 {
19672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19673 "%s : Dropping DFS channel : %d",
19674 __func__,channels_allowed[indx]);
19675 num_ignore_dfs_ch++;
19676 break;
19677 }
19678
Nirav Shah80830bf2013-12-31 16:35:12 +053019679 valid_ch[num_ch++] = request->channels[i]->hw_value;
19680 len += snprintf(chList+len, 5, "%d ",
19681 request->channels[i]->hw_value);
19682 break ;
19683 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019684 }
19685 }
Nirav Shah80830bf2013-12-31 16:35:12 +053019686 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019687
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019688 /*If all channels are DFS and dropped, then ignore the PNO request*/
19689 if (num_ignore_dfs_ch == request->n_channels)
19690 {
19691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19692 "%s : All requested channels are DFS channels", __func__);
19693 ret = -EINVAL;
19694 goto error;
19695 }
19696 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019697
19698 pnoRequest.aNetworks =
19699 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19700 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019701 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019702 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19703 FL("failed to allocate memory aNetworks %u"),
19704 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19705 goto error;
19706 }
19707 vos_mem_zero(pnoRequest.aNetworks,
19708 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19709
19710 /* Filling per profile params */
19711 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
19712 {
19713 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019714 request->match_sets[i].ssid.ssid_len;
19715
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019716 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
19717 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019718 {
19719 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019720 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019721 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019722 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019723 goto error;
19724 }
19725
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019726 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019727 request->match_sets[i].ssid.ssid,
19728 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19730 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019731 i, pnoRequest.aNetworks[i].ssId.ssId);
19732 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
19733 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
19734 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019735
19736 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019737 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
19738 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019739
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019740 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019741 }
19742
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019743 for (i = 0; i < request->n_ssids; i++)
19744 {
19745 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019746 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019747 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019748 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019749 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019750 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019751 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019752 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019753 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019754 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019755 break;
19756 }
19757 j++;
19758 }
19759 }
19760 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19761 "Number of hidden networks being Configured = %d",
19762 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080019764 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019765
19766 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19767 if (pnoRequest.p24GProbeTemplate == NULL)
19768 {
19769 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19770 FL("failed to allocate memory p24GProbeTemplate %u"),
19771 SIR_PNO_MAX_PB_REQ_SIZE);
19772 goto error;
19773 }
19774
19775 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19776 if (pnoRequest.p5GProbeTemplate == NULL)
19777 {
19778 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19779 FL("failed to allocate memory p5GProbeTemplate %u"),
19780 SIR_PNO_MAX_PB_REQ_SIZE);
19781 goto error;
19782 }
19783
19784 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19785 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19786
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053019787 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
19788 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019789 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019790 pnoRequest.us24GProbeTemplateLen = request->ie_len;
19791 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
19792 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019793
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019794 pnoRequest.us5GProbeTemplateLen = request->ie_len;
19795 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
19796 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019797 }
19798
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019799 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053019800
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019801 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019802
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019803 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019804 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19805 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019806 pAdapter->pno_req_status = 0;
19807
Nirav Shah80830bf2013-12-31 16:35:12 +053019808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19809 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019810 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
19811 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053019812
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019813 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019814 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019815 hdd_cfg80211_sched_scan_done_callback, pAdapter);
19816 if (eHAL_STATUS_SUCCESS != status)
19817 {
19818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019819 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019820 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019821 goto error;
19822 }
19823
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019824 ret = wait_for_completion_timeout(
19825 &pAdapter->pno_comp_var,
19826 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19827 if (0 >= ret)
19828 {
19829 // Did not receive the response for PNO enable in time.
19830 // Assuming the PNO enable was success.
19831 // Returning error from here, because we timeout, results
19832 // in side effect of Wifi (Wifi Setting) not to work.
19833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19834 FL("Timed out waiting for PNO to be Enabled"));
19835 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019836 }
19837
19838 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053019839 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019840
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019841error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19843 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053019844 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019845 if (pnoRequest.aNetworks)
19846 vos_mem_free(pnoRequest.aNetworks);
19847 if (pnoRequest.p24GProbeTemplate)
19848 vos_mem_free(pnoRequest.p24GProbeTemplate);
19849 if (pnoRequest.p5GProbeTemplate)
19850 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019851
19852 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019853 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019854}
19855
19856/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019857 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
19858 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019859 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019860static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
19861 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19862{
19863 int ret;
19864
19865 vos_ssr_protect(__func__);
19866 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
19867 vos_ssr_unprotect(__func__);
19868
19869 return ret;
19870}
19871
19872/*
19873 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
19874 * Function to disable PNO
19875 */
19876static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019877 struct net_device *dev)
19878{
19879 eHalStatus status = eHAL_STATUS_FAILURE;
19880 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19881 hdd_context_t *pHddCtx;
19882 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019883 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019884 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019885
19886 ENTER();
19887
19888 if (NULL == pAdapter)
19889 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019890 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019891 "%s: HDD adapter is Null", __func__);
19892 return -ENODEV;
19893 }
19894
19895 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019896
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019897 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019898 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019900 "%s: HDD context is Null", __func__);
19901 return -ENODEV;
19902 }
19903
19904 /* The return 0 is intentional when isLogpInProgress and
19905 * isLoadUnloadInProgress. We did observe a crash due to a return of
19906 * failure in sched_scan_stop , especially for a case where the unload
19907 * of the happens at the same time. The function __cfg80211_stop_sched_scan
19908 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
19909 * success. If it returns a failure , then its next invocation due to the
19910 * clean up of the second interface will have the dev pointer corresponding
19911 * to the first one leading to a crash.
19912 */
19913 if (pHddCtx->isLogpInProgress)
19914 {
19915 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19916 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019917 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019918 return ret;
19919 }
19920
Mihir Shete18156292014-03-11 15:38:30 +053019921 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019922 {
19923 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19924 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19925 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019926 }
19927
19928 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19929 if (NULL == hHal)
19930 {
19931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19932 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019933 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019934 }
19935
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019936 pnoRequest.enable = 0; /* Disable PNO */
19937 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019938
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019939 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19940 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19941 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019942
19943 INIT_COMPLETION(pAdapter->pno_comp_var);
19944 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19945 pnoRequest.callbackContext = pAdapter;
19946 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019947 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019948 pAdapter->sessionId,
19949 NULL, pAdapter);
19950 if (eHAL_STATUS_SUCCESS != status)
19951 {
19952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19953 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019954 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019955 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019956 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019957 ret = wait_for_completion_timeout(
19958 &pAdapter->pno_comp_var,
19959 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19960 if (0 >= ret)
19961 {
19962 // Did not receive the response for PNO disable in time.
19963 // Assuming the PNO disable was success.
19964 // Returning error from here, because we timeout, results
19965 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019966 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019967 FL("Timed out waiting for PNO to be disabled"));
19968 ret = 0;
19969 }
19970
19971 ret = pAdapter->pno_req_status;
19972 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019973
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019974error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019975 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019976 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019977
19978 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019979 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019980}
19981
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019982/*
19983 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19984 * NL interface to disable PNO
19985 */
19986static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19987 struct net_device *dev)
19988{
19989 int ret;
19990
19991 vos_ssr_protect(__func__);
19992 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19993 vos_ssr_unprotect(__func__);
19994
19995 return ret;
19996}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019997#endif /*FEATURE_WLAN_SCAN_PNO*/
19998
19999
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020000#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020001#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020002static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20003 struct net_device *dev,
20004 u8 *peer, u8 action_code,
20005 u8 dialog_token,
20006 u16 status_code, u32 peer_capability,
20007 const u8 *buf, size_t len)
20008#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020009#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20010 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020011static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20012 struct net_device *dev,
20013 const u8 *peer, u8 action_code,
20014 u8 dialog_token, u16 status_code,
20015 u32 peer_capability, bool initiator,
20016 const u8 *buf, size_t len)
20017#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20018static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20019 struct net_device *dev,
20020 const u8 *peer, u8 action_code,
20021 u8 dialog_token, u16 status_code,
20022 u32 peer_capability, const u8 *buf,
20023 size_t len)
20024#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20025static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20026 struct net_device *dev,
20027 u8 *peer, u8 action_code,
20028 u8 dialog_token,
20029 u16 status_code, u32 peer_capability,
20030 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020031#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020032static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20033 struct net_device *dev,
20034 u8 *peer, u8 action_code,
20035 u8 dialog_token,
20036 u16 status_code, const u8 *buf,
20037 size_t len)
20038#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020039#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020040{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020041 hdd_adapter_t *pAdapter;
20042 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020043 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070020044 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080020045 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070020046 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020047 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020048 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020049#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020050 u32 peer_capability = 0;
20051#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020052 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020053 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020054 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020055
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020056 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20057 if (NULL == pAdapter)
20058 {
20059 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20060 "%s: Adapter is NULL",__func__);
20061 return -EINVAL;
20062 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020063 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20064 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
20065 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020066
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020067 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020068 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020069 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020071 "Invalid arguments");
20072 return -EINVAL;
20073 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020074
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020075 if (pHddCtx->isLogpInProgress)
20076 {
20077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20078 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053020079 wlan_hdd_tdls_set_link_status(pAdapter,
20080 peer,
20081 eTDLS_LINK_IDLE,
20082 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020083 return -EBUSY;
20084 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020085
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020086 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
20087 {
20088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20089 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
20090 return -EAGAIN;
20091 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020092
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020093 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
20094 if (!pHddTdlsCtx) {
20095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20096 "%s: pHddTdlsCtx not valid.", __func__);
Hanumanth Reddy Pothula36dfa522018-03-12 16:42:08 +053020097 return -EINVAL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020098 }
20099
Hoonki Lee27511902013-03-14 18:19:06 -070020100 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020101 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020102 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020103 "%s: TDLS mode is disabled OR not enabled in FW."
20104 MAC_ADDRESS_STR " action %d declined.",
20105 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020106 return -ENOTSUPP;
20107 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020108
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020109 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20110
20111 if( NULL == pHddStaCtx )
20112 {
20113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20114 "%s: HDD station context NULL ",__func__);
20115 return -EINVAL;
20116 }
20117
20118 /* STA should be connected and authenticated
20119 * before sending any TDLS frames
20120 */
20121 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
20122 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
20123 {
20124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20125 "STA is not connected or unauthenticated. "
20126 "connState %u, uIsAuthenticated %u",
20127 pHddStaCtx->conn_info.connState,
20128 pHddStaCtx->conn_info.uIsAuthenticated);
20129 return -EAGAIN;
20130 }
20131
Hoonki Lee27511902013-03-14 18:19:06 -070020132 /* other than teardown frame, other mgmt frames are not sent if disabled */
20133 if (SIR_MAC_TDLS_TEARDOWN != action_code)
20134 {
20135 /* if tdls_mode is disabled to respond to peer's request */
20136 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
20137 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020139 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020140 " TDLS mode is disabled. action %d declined.",
20141 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070020142
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020143 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070020144 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053020145
20146 if (vos_max_concurrent_connections_reached())
20147 {
20148 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
20149 return -EINVAL;
20150 }
Hoonki Lee27511902013-03-14 18:19:06 -070020151 }
20152
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020153 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
20154 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053020155 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020156 {
20157 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020158 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020159 " TDLS setup is ongoing. action %d declined.",
20160 __func__, MAC_ADDR_ARRAY(peer), action_code);
20161 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020162 }
20163 }
20164
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020165 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
20166 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080020167 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020168 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20169 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020170 {
20171 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
20172 we return error code at 'add_station()'. Hence we have this
20173 check again in addtion to add_station().
20174 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020175 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020176 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020177 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20178 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020179 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
20180 __func__, MAC_ADDR_ARRAY(peer), action_code,
20181 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053020182 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080020183 }
20184 else
20185 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020186 /* maximum reached. tweak to send error code to peer and return
20187 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020188 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020189 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20190 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020191 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
20192 __func__, MAC_ADDR_ARRAY(peer), status_code,
20193 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070020194 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020195 /* fall through to send setup resp with failure status
20196 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020197 }
20198 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020199 else
20200 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020201 mutex_lock(&pHddCtx->tdls_lock);
20202 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020203 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020204 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020205 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020207 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
20208 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020209 return -EPERM;
20210 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020211 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020212 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020213 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020214
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020215 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020216 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020217 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
20218 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020219
Hoonki Leea34dd892013-02-05 22:56:02 -080020220 /*Except teardown responder will not be used so just make 0*/
20221 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020222 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080020223 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020224
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020225 mutex_lock(&pHddCtx->tdls_lock);
20226 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020227
20228 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
20229 responder = pTdlsPeer->is_responder;
20230 else
Hoonki Leea34dd892013-02-05 22:56:02 -080020231 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020233 "%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 -070020234 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
20235 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020236 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020237 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080020238 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020239 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020240 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020241
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020242 /* Discard TDLS setup if peer is removed by user app */
20243 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
20244 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20245 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
20246 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
20247
20248 mutex_lock(&pHddCtx->tdls_lock);
20249 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20250 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
20251 mutex_unlock(&pHddCtx->tdls_lock);
20252 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
20253 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
20254 MAC_ADDR_ARRAY(peer), action_code);
20255 return -EINVAL;
20256 }
20257 mutex_unlock(&pHddCtx->tdls_lock);
20258 }
20259
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020260 /* For explicit trigger of DIS_REQ come out of BMPS for
20261 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070020262 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053020263 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020264 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
20265 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070020266 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020267 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020269 "%s: Sending frame action_code %u.Disable BMPS", __func__,
20270 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020271 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
20272 if (status != VOS_STATUS_SUCCESS) {
20273 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020274 } else {
20275 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020276 }
Hoonki Lee14621352013-04-16 17:51:19 -070020277 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020278 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020279 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020280 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
20281 }
20282 }
Hoonki Lee14621352013-04-16 17:51:19 -070020283 }
20284
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020285 /* make sure doesn't call send_mgmt() while it is pending */
20286 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
20287 {
20288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080020289 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020290 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020291 ret = -EBUSY;
20292 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020293 }
20294
20295 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020296 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
20297
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020298 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
20299 pAdapter->sessionId, peer, action_code, dialog_token,
20300 status_code, peer_capability, (tANI_U8 *)buf, len,
20301 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020302
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020303 if (VOS_STATUS_SUCCESS != status)
20304 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20306 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020307 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020308 ret = -EINVAL;
20309 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020310 }
20311
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20313 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
20314 WAIT_TIME_TDLS_MGMT);
20315
Hoonki Leed37cbb32013-04-20 00:31:14 -070020316 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
20317 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
20318
20319 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020320 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070020321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070020322 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070020323 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020324 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080020325
20326 if (pHddCtx->isLogpInProgress)
20327 {
20328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20329 "%s: LOGP in Progress. Ignore!!!", __func__);
20330 return -EAGAIN;
20331 }
Abhishek Singh837adf22015-10-01 17:37:37 +053020332 if (rc <= 0)
20333 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
20334 WLAN_LOG_INDICATOR_HOST_DRIVER,
20335 WLAN_LOG_REASON_HDD_TIME_OUT,
20336 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080020337
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020338 ret = -EINVAL;
20339 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020340 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020341 else
20342 {
20343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20344 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
20345 __func__, rc, pAdapter->mgmtTxCompletionStatus);
20346 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020347
Gopichand Nakkala05922802013-03-14 12:23:19 -070020348 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070020349 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020350 ret = max_sta_failed;
20351 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070020352 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020353
Hoonki Leea34dd892013-02-05 22:56:02 -080020354 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
20355 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020356 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020357 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20358 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020359 }
20360 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
20361 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020362 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020363 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20364 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020365 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020366
20367 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020368
20369tx_failed:
20370 /* add_station will be called before sending TDLS_SETUP_REQ and
20371 * TDLS_SETUP_RSP and as part of add_station driver will enable
20372 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
20373 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
20374 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
20375 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
20376 */
20377
20378 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20379 (SIR_MAC_TDLS_SETUP_RSP == action_code))
20380 wlan_hdd_tdls_check_bmps(pAdapter);
20381 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020382}
20383
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020384#if TDLS_MGMT_VERSION2
20385static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20386 u8 *peer, u8 action_code, u8 dialog_token,
20387 u16 status_code, u32 peer_capability,
20388 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020389#else /* TDLS_MGMT_VERSION2 */
20390#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20391static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20392 struct net_device *dev,
20393 const u8 *peer, u8 action_code,
20394 u8 dialog_token, u16 status_code,
20395 u32 peer_capability, bool initiator,
20396 const u8 *buf, size_t len)
20397#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20398static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20399 struct net_device *dev,
20400 const u8 *peer, u8 action_code,
20401 u8 dialog_token, u16 status_code,
20402 u32 peer_capability, const u8 *buf,
20403 size_t len)
20404#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20405static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20406 struct net_device *dev,
20407 u8 *peer, u8 action_code,
20408 u8 dialog_token,
20409 u16 status_code, u32 peer_capability,
20410 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020411#else
20412static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20413 u8 *peer, u8 action_code, u8 dialog_token,
20414 u16 status_code, const u8 *buf, size_t len)
20415#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020416#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020417{
20418 int ret;
20419
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020420 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020421#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020422 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20423 dialog_token, status_code,
20424 peer_capability, buf, len);
20425#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020426#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20427 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020428 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20429 dialog_token, status_code,
20430 peer_capability, initiator,
20431 buf, len);
20432#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20433 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20434 dialog_token, status_code,
20435 peer_capability, buf, len);
20436#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20437 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20438 dialog_token, status_code,
20439 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020440#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020441 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20442 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020443#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020444#endif
20445 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020446
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020447 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020448}
Atul Mittal115287b2014-07-08 13:26:33 +053020449
20450int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020451#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20452 const u8 *peer,
20453#else
Atul Mittal115287b2014-07-08 13:26:33 +053020454 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020455#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020456 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053020457 cfg80211_exttdls_callback callback)
20458{
20459
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020460 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053020461 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020462 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053020463 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20464 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
20465 __func__, MAC_ADDR_ARRAY(peer));
20466
20467 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20468 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20469
20470 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020471 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20472 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20473 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020474 return -ENOTSUPP;
20475 }
20476
20477 /* To cater the requirement of establishing the TDLS link
20478 * irrespective of the data traffic , get an entry of TDLS peer.
20479 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020480 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020481 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
20482 if (pTdlsPeer == NULL) {
20483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20484 "%s: peer " MAC_ADDRESS_STR " not existing",
20485 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020486 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020487 return -EINVAL;
20488 }
20489
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020490 /* check FW TDLS Off Channel capability */
20491 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020492 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020493 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020494 {
20495 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
20496 pTdlsPeer->peerParams.global_operating_class =
20497 tdls_peer_params->global_operating_class;
20498 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
20499 pTdlsPeer->peerParams.min_bandwidth_kbps =
20500 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020501 /* check configured channel is valid, non dfs and
20502 * not current operating channel */
20503 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
20504 tdls_peer_params->channel)) &&
20505 (pHddStaCtx) &&
20506 (tdls_peer_params->channel !=
20507 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020508 {
20509 pTdlsPeer->isOffChannelConfigured = TRUE;
20510 }
20511 else
20512 {
20513 pTdlsPeer->isOffChannelConfigured = FALSE;
20514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20515 "%s: Configured Tdls Off Channel is not valid", __func__);
20516
20517 }
20518 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020519 "%s: tdls_off_channel %d isOffChannelConfigured %d "
20520 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020521 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020522 pTdlsPeer->isOffChannelConfigured,
20523 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020524 }
20525 else
20526 {
20527 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020528 "%s: TDLS off channel FW capability %d, "
20529 "host capab %d or Invalid TDLS Peer Params", __func__,
20530 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
20531 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020532 }
20533
Atul Mittal115287b2014-07-08 13:26:33 +053020534 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
20535
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020536 mutex_unlock(&pHddCtx->tdls_lock);
20537
Atul Mittal115287b2014-07-08 13:26:33 +053020538 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20539 " %s TDLS Add Force Peer Failed",
20540 __func__);
20541 return -EINVAL;
20542 }
20543 /*EXT TDLS*/
20544
20545 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020546 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020547 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20548 " %s TDLS set callback Failed",
20549 __func__);
20550 return -EINVAL;
20551 }
20552
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020553 mutex_unlock(&pHddCtx->tdls_lock);
20554
Atul Mittal115287b2014-07-08 13:26:33 +053020555 return(0);
20556
20557}
20558
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020559int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
20560#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20561 const u8 *peer
20562#else
20563 u8 *peer
20564#endif
20565)
Atul Mittal115287b2014-07-08 13:26:33 +053020566{
20567
20568 hddTdlsPeer_t *pTdlsPeer;
20569 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020570
Atul Mittal115287b2014-07-08 13:26:33 +053020571 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20572 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
20573 __func__, MAC_ADDR_ARRAY(peer));
20574
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020575 if (0 != wlan_hdd_validate_context(pHddCtx)) {
20576 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
20577 return -EINVAL;
20578 }
20579
Atul Mittal115287b2014-07-08 13:26:33 +053020580 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20581 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20582
20583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020584 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20585 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20586 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020587 return -ENOTSUPP;
20588 }
20589
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020590 mutex_lock(&pHddCtx->tdls_lock);
20591 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053020592
20593 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020594 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020595 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020596 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053020597 __func__, MAC_ADDR_ARRAY(peer));
20598 return -EINVAL;
20599 }
20600 else {
20601 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
20602 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020603 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
20604 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020605 /* if channel switch is configured, reset
20606 the channel for this peer */
20607 if (TRUE == pTdlsPeer->isOffChannelConfigured)
20608 {
20609 pTdlsPeer->peerParams.channel = 0;
20610 pTdlsPeer->isOffChannelConfigured = FALSE;
20611 }
Atul Mittal115287b2014-07-08 13:26:33 +053020612 }
20613
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020614 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020615 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020616 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053020617 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020618 }
Atul Mittal115287b2014-07-08 13:26:33 +053020619
20620 /*EXT TDLS*/
20621
20622 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020623 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20625 " %s TDLS set callback Failed",
20626 __func__);
20627 return -EINVAL;
20628 }
Atul Mittal115287b2014-07-08 13:26:33 +053020629
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020630 mutex_unlock(&pHddCtx->tdls_lock);
20631
20632 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053020633}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020634static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020635#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20636 const u8 *peer,
20637#else
20638 u8 *peer,
20639#endif
20640 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020641{
20642 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20643 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020644 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020645 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020646
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020647 ENTER();
20648
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020649 if (!pAdapter) {
20650 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
20651 return -EINVAL;
20652 }
20653
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020654 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20655 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
20656 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020657 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020658 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070020660 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020661 return -EINVAL;
20662 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020663
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020664 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020665 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020666 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020667 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020668 }
20669
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020670
20671 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020672 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020673 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020674 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020675 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
20676 "Cannot process TDLS commands",
20677 pHddCtx->cfg_ini->fEnableTDLSSupport,
20678 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020679 return -ENOTSUPP;
20680 }
20681
20682 switch (oper) {
20683 case NL80211_TDLS_ENABLE_LINK:
20684 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020685 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020686 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053020687 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
20688 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053020689 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020690 tANI_U16 numCurrTdlsPeers = 0;
20691 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020692 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020693 tSirMacAddr peerMac;
20694 int channel;
20695 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020696
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20698 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
20699 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020700
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020701 mutex_lock(&pHddCtx->tdls_lock);
20702 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020703 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053020704 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020705 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020706 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20707 " (oper %d) not exsting. ignored",
20708 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20709 return -EINVAL;
20710 }
20711
20712 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20713 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20714 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20715 "NL80211_TDLS_ENABLE_LINK");
20716
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020717 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
20718 {
20719 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
20720 MAC_ADDRESS_STR " failed",
20721 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020722 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020723 return -EINVAL;
20724 }
20725
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020726 /* before starting tdls connection, set tdls
20727 * off channel established status to default value */
20728 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020729
20730 mutex_unlock(&pHddCtx->tdls_lock);
20731
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053020732 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020733 /* TDLS Off Channel, Disable tdls channel switch,
20734 when there are more than one tdls link */
20735 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053020736 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020737 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020738 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020739 /* get connected peer and send disable tdls off chan */
20740 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020741 if ((connPeer) &&
20742 (connPeer->isOffChannelSupported == TRUE) &&
20743 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020744 {
20745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20746 "%s: More then one peer connected, Disable "
20747 "TDLS channel switch", __func__);
20748
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020749 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020750 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
20751 channel = connPeer->peerParams.channel;
20752
20753 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020754
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020755 ret = sme_SendTdlsChanSwitchReq(
20756 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020757 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020758 peerMac,
20759 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020760 TDLS_OFF_CHANNEL_BW_OFFSET,
20761 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020762 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020763 hddLog(VOS_TRACE_LEVEL_ERROR,
20764 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020765 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020766 }
20767 else
20768 {
20769 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20770 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020771 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020772 "isOffChannelConfigured %d",
20773 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020774 (connPeer ? (connPeer->isOffChannelSupported)
20775 : -1),
20776 (connPeer ? (connPeer->isOffChannelConfigured)
20777 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020778 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020779 }
20780 }
20781
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020782 mutex_lock(&pHddCtx->tdls_lock);
20783 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20784 if ( NULL == pTdlsPeer ) {
20785 mutex_unlock(&pHddCtx->tdls_lock);
20786 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20787 "%s: " MAC_ADDRESS_STR
20788 " (oper %d) peer got freed in other context. ignored",
20789 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20790 return -EINVAL;
20791 }
20792 peer_status = pTdlsPeer->link_status;
20793 mutex_unlock(&pHddCtx->tdls_lock);
20794
20795 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020796 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020797 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053020798
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020799 if (0 != wlan_hdd_tdls_get_link_establish_params(
20800 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020801 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020802 return -EINVAL;
20803 }
20804 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020805
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020806 ret = sme_SendTdlsLinkEstablishParams(
20807 WLAN_HDD_GET_HAL_CTX(pAdapter),
20808 pAdapter->sessionId, peer,
20809 &tdlsLinkEstablishParams);
20810 if (ret != VOS_STATUS_SUCCESS) {
20811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
20812 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020813 /* Send TDLS peer UAPSD capabilities to the firmware and
20814 * register with the TL on after the response for this operation
20815 * is received .
20816 */
20817 ret = wait_for_completion_interruptible_timeout(
20818 &pAdapter->tdls_link_establish_req_comp,
20819 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053020820
20821 mutex_lock(&pHddCtx->tdls_lock);
20822 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20823 if ( NULL == pTdlsPeer ) {
20824 mutex_unlock(&pHddCtx->tdls_lock);
20825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20826 "%s %d: " MAC_ADDRESS_STR
20827 " (oper %d) peer got freed in other context. ignored",
20828 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
20829 (int)oper);
20830 return -EINVAL;
20831 }
20832 peer_status = pTdlsPeer->link_status;
20833 mutex_unlock(&pHddCtx->tdls_lock);
20834
20835 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020836 {
20837 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020838 FL("Link Establish Request Failed Status %ld"),
20839 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020840 return -EINVAL;
20841 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020842 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020843
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020844 mutex_lock(&pHddCtx->tdls_lock);
20845 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20846 if ( NULL == pTdlsPeer ) {
20847 mutex_unlock(&pHddCtx->tdls_lock);
20848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20849 "%s: " MAC_ADDRESS_STR
20850 " (oper %d) peer got freed in other context. ignored",
20851 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20852 return -EINVAL;
20853 }
20854
Atul Mittal115287b2014-07-08 13:26:33 +053020855 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20856 eTDLS_LINK_CONNECTED,
20857 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020858 staDesc.ucSTAId = pTdlsPeer->staId;
20859 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053020860
20861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20862 "%s: tdlsLinkEstablishParams of peer "
20863 MAC_ADDRESS_STR "uapsdQueues: %d"
20864 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
20865 "isResponder: %d peerstaId: %d",
20866 __func__,
20867 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
20868 tdlsLinkEstablishParams.uapsdQueues,
20869 tdlsLinkEstablishParams.qos,
20870 tdlsLinkEstablishParams.maxSp,
20871 tdlsLinkEstablishParams.isBufSta,
20872 tdlsLinkEstablishParams.isOffChannelSupported,
20873 tdlsLinkEstablishParams.isResponder,
20874 pTdlsPeer->staId);
20875
20876 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20877 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
20878 __func__,
20879 staDesc.ucSTAId,
20880 staDesc.ucQosEnabled);
20881
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020882 ret = WLANTL_UpdateTdlsSTAClient(
20883 pHddCtx->pvosContext,
20884 &staDesc);
20885 if (ret != VOS_STATUS_SUCCESS) {
20886 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
20887 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053020888
Gopichand Nakkala471708b2013-06-04 20:03:01 +053020889 /* Mark TDLS client Authenticated .*/
20890 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
20891 pTdlsPeer->staId,
20892 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020893 if (VOS_STATUS_SUCCESS == status)
20894 {
Hoonki Lee14621352013-04-16 17:51:19 -070020895 if (pTdlsPeer->is_responder == 0)
20896 {
20897 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020898 tdlsConnInfo_t *tdlsInfo;
20899
20900 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
20901
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020902 if (!vos_timer_is_initialized(
20903 &pTdlsPeer->initiatorWaitTimeoutTimer))
20904 {
20905 /* Initialize initiator wait callback */
20906 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020907 &pTdlsPeer->initiatorWaitTimeoutTimer,
20908 VOS_TIMER_TYPE_SW,
20909 wlan_hdd_tdls_initiator_wait_cb,
20910 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020911 }
Hoonki Lee14621352013-04-16 17:51:19 -070020912 wlan_hdd_tdls_timer_restart(pAdapter,
20913 &pTdlsPeer->initiatorWaitTimeoutTimer,
20914 WAIT_TIME_TDLS_INITIATOR);
20915 /* suspend initiator TX until it receives direct packet from the
20916 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020917 ret = WLANTL_SuspendDataTx(
20918 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20919 &staId, NULL);
20920 if (ret != VOS_STATUS_SUCCESS) {
20921 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20922 }
Hoonki Lee14621352013-04-16 17:51:19 -070020923 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020924
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020925 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020926 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020927 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020928 suppChannelLen =
20929 tdlsLinkEstablishParams.supportedChannelsLen;
20930
20931 if ((suppChannelLen > 0) &&
20932 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20933 {
20934 tANI_U8 suppPeerChannel = 0;
20935 int i = 0;
20936 for (i = 0U; i < suppChannelLen; i++)
20937 {
20938 suppPeerChannel =
20939 tdlsLinkEstablishParams.supportedChannels[i];
20940
20941 pTdlsPeer->isOffChannelSupported = FALSE;
20942 if (suppPeerChannel ==
20943 pTdlsPeer->peerParams.channel)
20944 {
20945 pTdlsPeer->isOffChannelSupported = TRUE;
20946 break;
20947 }
20948 }
20949 }
20950 else
20951 {
20952 pTdlsPeer->isOffChannelSupported = FALSE;
20953 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020954 }
20955 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20956 "%s: TDLS channel switch request for channel "
20957 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020958 "%d isOffChannelSupported %d", __func__,
20959 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020960 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020961 suppChannelLen,
20962 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020963
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020964 /* TDLS Off Channel, Enable tdls channel switch,
20965 when their is only one tdls link and it supports */
20966 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20967 if ((numCurrTdlsPeers == 1) &&
20968 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20969 (TRUE == pTdlsPeer->isOffChannelConfigured))
20970 {
20971 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20972 "%s: Send TDLS channel switch request for channel %d",
20973 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020974
20975 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020976 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20977 channel = pTdlsPeer->peerParams.channel;
20978
20979 mutex_unlock(&pHddCtx->tdls_lock);
20980
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020981 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20982 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020983 peerMac,
20984 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020985 TDLS_OFF_CHANNEL_BW_OFFSET,
20986 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020987 if (ret != VOS_STATUS_SUCCESS) {
20988 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20989 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020990 }
20991 else
20992 {
20993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20994 "%s: TDLS channel switch request not sent"
20995 " numCurrTdlsPeers %d "
20996 "isOffChannelSupported %d "
20997 "isOffChannelConfigured %d",
20998 __func__, numCurrTdlsPeers,
20999 pTdlsPeer->isOffChannelSupported,
21000 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021001 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021002 }
21003
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070021004 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021005 else
21006 mutex_unlock(&pHddCtx->tdls_lock);
21007
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021008 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021009
21010 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021011 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
21012 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021013 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021014 int ac;
21015 uint8 ucAc[4] = { WLANTL_AC_VO,
21016 WLANTL_AC_VI,
21017 WLANTL_AC_BK,
21018 WLANTL_AC_BE };
21019 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
21020 for(ac=0; ac < 4; ac++)
21021 {
21022 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
21023 pTdlsPeer->staId, ucAc[ac],
21024 tlTid[ac], tlTid[ac], 0, 0,
21025 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021026 if (status != VOS_STATUS_SUCCESS) {
21027 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
21028 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021029 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021030 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021031 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021032
Bhargav Shah66896792015-10-01 18:17:37 +053021033 /* stop TCP delack timer if TDLS is enable */
21034 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21035 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053021036 hdd_wlan_tdls_enable_link_event(peer,
21037 pTdlsPeer->isOffChannelSupported,
21038 pTdlsPeer->isOffChannelConfigured,
21039 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021040 }
21041 break;
21042 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080021043 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021044 tANI_U16 numCurrTdlsPeers = 0;
21045 hddTdlsPeer_t *connPeer = NULL;
21046
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21048 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
21049 __func__, MAC_ADDR_ARRAY(peer));
21050
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021051 mutex_lock(&pHddCtx->tdls_lock);
21052 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021053
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021054
Sunil Dutt41de4e22013-11-14 18:09:02 +053021055 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021056 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021057 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21058 " (oper %d) not exsting. ignored",
21059 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
21060 return -EINVAL;
21061 }
21062
21063 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21064 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
21065 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
21066 "NL80211_TDLS_DISABLE_LINK");
21067
Hoonki Lee5305c3a2013-04-29 23:28:59 -070021068 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080021069 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021070 long status;
21071
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053021072 /* set tdls off channel status to false for this peer */
21073 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053021074 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
21075 eTDLS_LINK_TEARING,
21076 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
21077 eTDLS_LINK_UNSPECIFIED:
21078 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021079 mutex_unlock(&pHddCtx->tdls_lock);
21080
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021081 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
21082
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021083 status = sme_DeleteTdlsPeerSta(
21084 WLAN_HDD_GET_HAL_CTX(pAdapter),
21085 pAdapter->sessionId, peer );
21086 if (status != VOS_STATUS_SUCCESS) {
21087 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
21088 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021089
21090 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
21091 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021092
21093 mutex_lock(&pHddCtx->tdls_lock);
21094 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21095 if ( NULL == pTdlsPeer ) {
21096 mutex_unlock(&pHddCtx->tdls_lock);
21097 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21098 " peer was freed in other context",
21099 __func__, MAC_ADDR_ARRAY(peer));
21100 return -EINVAL;
21101 }
21102
Atul Mittal271a7652014-09-12 13:18:22 +053021103 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053021104 eTDLS_LINK_IDLE,
21105 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021106 mutex_unlock(&pHddCtx->tdls_lock);
21107
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021108 if (status <= 0)
21109 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21111 "%s: Del station failed status %ld",
21112 __func__, status);
21113 return -EPERM;
21114 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021115
21116 /* TDLS Off Channel, Enable tdls channel switch,
21117 when their is only one tdls link and it supports */
21118 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
21119 if (numCurrTdlsPeers == 1)
21120 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021121 tSirMacAddr peerMac;
21122 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021123
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021124 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021125 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021126
21127 if (connPeer == NULL) {
21128 mutex_unlock(&pHddCtx->tdls_lock);
21129 hddLog(VOS_TRACE_LEVEL_ERROR,
21130 "%s connPeer is NULL", __func__);
21131 return -EINVAL;
21132 }
21133
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021134 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
21135 channel = connPeer->peerParams.channel;
21136
21137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21138 "%s: TDLS channel switch "
21139 "isOffChannelSupported %d "
21140 "isOffChannelConfigured %d "
21141 "isOffChannelEstablished %d",
21142 __func__,
21143 (connPeer ? connPeer->isOffChannelSupported : -1),
21144 (connPeer ? connPeer->isOffChannelConfigured : -1),
21145 (connPeer ? connPeer->isOffChannelEstablished : -1));
21146
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021147 if ((connPeer) &&
21148 (connPeer->isOffChannelSupported == TRUE) &&
21149 (connPeer->isOffChannelConfigured == TRUE))
21150 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053021151 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021152 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021153 status = sme_SendTdlsChanSwitchReq(
21154 WLAN_HDD_GET_HAL_CTX(pAdapter),
21155 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021156 peerMac,
21157 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021158 TDLS_OFF_CHANNEL_BW_OFFSET,
21159 TDLS_CHANNEL_SWITCH_ENABLE);
21160 if (status != VOS_STATUS_SUCCESS) {
21161 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
21162 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021163 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021164 else
21165 mutex_unlock(&pHddCtx->tdls_lock);
21166 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021167 else
21168 {
21169 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21170 "%s: TDLS channel switch request not sent "
21171 "numCurrTdlsPeers %d ",
21172 __func__, numCurrTdlsPeers);
21173 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021174 }
21175 else
21176 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021177 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021178 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21179 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080021180 }
Bhargav Shah66896792015-10-01 18:17:37 +053021181 if (numCurrTdlsPeers == 0) {
21182 /* start TCP delack timer if TDLS is disable */
21183 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21184 hdd_manage_delack_timer(pHddCtx);
21185 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021186 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021187 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021188 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021189 {
Atul Mittal115287b2014-07-08 13:26:33 +053021190 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021191
Atul Mittal115287b2014-07-08 13:26:33 +053021192 if (0 != status)
21193 {
21194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021195 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053021196 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021197 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053021198 break;
21199 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021200 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021201 {
Atul Mittal115287b2014-07-08 13:26:33 +053021202 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
21203 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021204 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053021205 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021206
Atul Mittal115287b2014-07-08 13:26:33 +053021207 if (0 != status)
21208 {
21209 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021210 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053021211 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053021212 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053021213 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021214 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021215 case NL80211_TDLS_DISCOVERY_REQ:
21216 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021218 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021219 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021220 return -ENOTSUPP;
21221 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21223 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021224 return -ENOTSUPP;
21225 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021226
21227 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021228 return 0;
21229}
Chilam NG571c65a2013-01-19 12:27:36 +053021230
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021231static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021232#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
21233 const u8 *peer,
21234#else
21235 u8 *peer,
21236#endif
21237 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021238{
21239 int ret;
21240
21241 vos_ssr_protect(__func__);
21242 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
21243 vos_ssr_unprotect(__func__);
21244
21245 return ret;
21246}
21247
Chilam NG571c65a2013-01-19 12:27:36 +053021248int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
21249 struct net_device *dev, u8 *peer)
21250{
Arif Hussaina7c8e412013-11-20 11:06:42 -080021251 hddLog(VOS_TRACE_LEVEL_INFO,
21252 "tdls send discover req: "MAC_ADDRESS_STR,
21253 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021254#if TDLS_MGMT_VERSION2
21255 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21256 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21257#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021258#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
21259 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21260 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
21261#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
21262 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21263 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21264#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
21265 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21266 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21267#else
Chilam NG571c65a2013-01-19 12:27:36 +053021268 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21269 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021270#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021271#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053021272}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021273#endif
21274
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021275#ifdef WLAN_FEATURE_GTK_OFFLOAD
21276/*
21277 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
21278 * Callback rountine called upon receiving response for
21279 * get offload info
21280 */
21281void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
21282 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
21283{
21284
21285 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021286 tANI_U8 tempReplayCounter[8];
21287 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021288
21289 ENTER();
21290
21291 if (NULL == pAdapter)
21292 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053021293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021294 "%s: HDD adapter is Null", __func__);
21295 return ;
21296 }
21297
21298 if (NULL == pGtkOffloadGetInfoRsp)
21299 {
21300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21301 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
21302 return ;
21303 }
21304
21305 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
21306 {
21307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21308 "%s: wlan Failed to get replay counter value",
21309 __func__);
21310 return ;
21311 }
21312
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021313 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21314 /* Update replay counter */
21315 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
21316 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21317
21318 {
21319 /* changing from little to big endian since supplicant
21320 * works on big endian format
21321 */
21322 int i;
21323 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21324
21325 for (i = 0; i < 8; i++)
21326 {
21327 tempReplayCounter[7-i] = (tANI_U8)p[i];
21328 }
21329 }
21330
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021331 /* Update replay counter to NL */
21332 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021333 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021334}
21335
21336/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021337 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021338 * This function is used to offload GTK rekeying job to the firmware.
21339 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021340int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021341 struct cfg80211_gtk_rekey_data *data)
21342{
21343 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21344 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21345 hdd_station_ctx_t *pHddStaCtx;
21346 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021347 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021348 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021349 eHalStatus status = eHAL_STATUS_FAILURE;
21350
21351 ENTER();
21352
21353 if (NULL == pAdapter)
21354 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053021355 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021356 "%s: HDD adapter is Null", __func__);
21357 return -ENODEV;
21358 }
21359
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053021360 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21361 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
21362 pAdapter->sessionId, pAdapter->device_mode));
21363
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021364 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021365 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021366 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021367 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021368 }
21369
21370 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21371 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
21372 if (NULL == hHal)
21373 {
21374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21375 "%s: HAL context is Null!!!", __func__);
21376 return -EAGAIN;
21377 }
21378
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021379 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
21380 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
21381 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
21382 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021383 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021384 {
21385 /* changing from big to little endian since driver
21386 * works on little endian format
21387 */
21388 tANI_U8 *p =
21389 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
21390 int i;
21391
21392 for (i = 0; i < 8; i++)
21393 {
21394 p[7-i] = data->replay_ctr[i];
21395 }
21396 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021397
21398 if (TRUE == pHddCtx->hdd_wlan_suspended)
21399 {
21400 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021401 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
21402 sizeof (tSirGtkOffloadParams));
21403 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021404 pAdapter->sessionId);
21405
21406 if (eHAL_STATUS_SUCCESS != status)
21407 {
21408 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21409 "%s: sme_SetGTKOffload failed, returned %d",
21410 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021411
21412 /* Need to clear any trace of key value in the memory.
21413 * Thus zero out the memory even though it is local
21414 * variable.
21415 */
21416 vos_mem_zero(&hddGtkOffloadReqParams,
21417 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021418 return status;
21419 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021420 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21421 "%s: sme_SetGTKOffload successfull", __func__);
21422 }
21423 else
21424 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21426 "%s: wlan not suspended GTKOffload request is stored",
21427 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021428 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021429
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021430 /* Need to clear any trace of key value in the memory.
21431 * Thus zero out the memory even though it is local
21432 * variable.
21433 */
21434 vos_mem_zero(&hddGtkOffloadReqParams,
21435 sizeof(hddGtkOffloadReqParams));
21436
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021437 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021438 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021439}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021440
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021441int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
21442 struct cfg80211_gtk_rekey_data *data)
21443{
21444 int ret;
21445
21446 vos_ssr_protect(__func__);
21447 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
21448 vos_ssr_unprotect(__func__);
21449
21450 return ret;
21451}
21452#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021453/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021454 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021455 * This function is used to set access control policy
21456 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021457static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21458 struct net_device *dev,
21459 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021460{
21461 int i;
21462 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21463 hdd_hostapd_state_t *pHostapdState;
21464 tsap_Config_t *pConfig;
21465 v_CONTEXT_t pVosContext = NULL;
21466 hdd_context_t *pHddCtx;
21467 int status;
21468
21469 ENTER();
21470
21471 if (NULL == pAdapter)
21472 {
21473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21474 "%s: HDD adapter is Null", __func__);
21475 return -ENODEV;
21476 }
21477
21478 if (NULL == params)
21479 {
21480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21481 "%s: params is Null", __func__);
21482 return -EINVAL;
21483 }
21484
21485 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21486 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021487 if (0 != status)
21488 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021489 return status;
21490 }
21491
21492 pVosContext = pHddCtx->pvosContext;
21493 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
21494
21495 if (NULL == pHostapdState)
21496 {
21497 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21498 "%s: pHostapdState is Null", __func__);
21499 return -EINVAL;
21500 }
21501
21502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
21503 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021504 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21505 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
21506 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021507
21508 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
21509 {
21510 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
21511
21512 /* default value */
21513 pConfig->num_accept_mac = 0;
21514 pConfig->num_deny_mac = 0;
21515
21516 /**
21517 * access control policy
21518 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
21519 * listed in hostapd.deny file.
21520 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
21521 * listed in hostapd.accept file.
21522 */
21523 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
21524 {
21525 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
21526 }
21527 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
21528 {
21529 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
21530 }
21531 else
21532 {
21533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21534 "%s:Acl Policy : %d is not supported",
21535 __func__, params->acl_policy);
21536 return -ENOTSUPP;
21537 }
21538
21539 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
21540 {
21541 pConfig->num_accept_mac = params->n_acl_entries;
21542 for (i = 0; i < params->n_acl_entries; i++)
21543 {
21544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21545 "** Add ACL MAC entry %i in WhiletList :"
21546 MAC_ADDRESS_STR, i,
21547 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21548
21549 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
21550 sizeof(qcmacaddr));
21551 }
21552 }
21553 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
21554 {
21555 pConfig->num_deny_mac = params->n_acl_entries;
21556 for (i = 0; i < params->n_acl_entries; i++)
21557 {
21558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21559 "** Add ACL MAC entry %i in BlackList :"
21560 MAC_ADDRESS_STR, i,
21561 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21562
21563 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
21564 sizeof(qcmacaddr));
21565 }
21566 }
21567
21568 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
21569 {
21570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21571 "%s: SAP Set Mac Acl fail", __func__);
21572 return -EINVAL;
21573 }
21574 }
21575 else
21576 {
21577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053021578 "%s: Invalid device_mode = %s (%d)",
21579 __func__, hdd_device_modetoString(pAdapter->device_mode),
21580 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021581 return -EINVAL;
21582 }
21583
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021584 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021585 return 0;
21586}
21587
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021588static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21589 struct net_device *dev,
21590 const struct cfg80211_acl_data *params)
21591{
21592 int ret;
21593 vos_ssr_protect(__func__);
21594 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
21595 vos_ssr_unprotect(__func__);
21596
21597 return ret;
21598}
21599
Leo Chang9056f462013-08-01 19:21:11 -070021600#ifdef WLAN_NL80211_TESTMODE
21601#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070021602void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070021603(
21604 void *pAdapter,
21605 void *indCont
21606)
21607{
Leo Changd9df8aa2013-09-26 13:32:26 -070021608 tSirLPHBInd *lphbInd;
21609 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053021610 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070021611
21612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021613 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070021614
c_hpothu73f35e62014-04-18 13:40:08 +053021615 if (pAdapter == NULL)
21616 {
21617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21618 "%s: pAdapter is NULL\n",__func__);
21619 return;
21620 }
21621
Leo Chang9056f462013-08-01 19:21:11 -070021622 if (NULL == indCont)
21623 {
21624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021625 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070021626 return;
21627 }
21628
c_hpothu73f35e62014-04-18 13:40:08 +053021629 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070021630 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070021631 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053021632 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070021633 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070021634 GFP_ATOMIC);
21635 if (!skb)
21636 {
21637 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21638 "LPHB timeout, NL buffer alloc fail");
21639 return;
21640 }
21641
Leo Changac3ba772013-10-07 09:47:04 -070021642 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070021643 {
21644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21645 "WLAN_HDD_TM_ATTR_CMD put fail");
21646 goto nla_put_failure;
21647 }
Leo Changac3ba772013-10-07 09:47:04 -070021648 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070021649 {
21650 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21651 "WLAN_HDD_TM_ATTR_TYPE put fail");
21652 goto nla_put_failure;
21653 }
Leo Changac3ba772013-10-07 09:47:04 -070021654 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070021655 sizeof(tSirLPHBInd), lphbInd))
21656 {
21657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21658 "WLAN_HDD_TM_ATTR_DATA put fail");
21659 goto nla_put_failure;
21660 }
Leo Chang9056f462013-08-01 19:21:11 -070021661 cfg80211_testmode_event(skb, GFP_ATOMIC);
21662 return;
21663
21664nla_put_failure:
21665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21666 "NLA Put fail");
21667 kfree_skb(skb);
21668
21669 return;
21670}
21671#endif /* FEATURE_WLAN_LPHB */
21672
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021673static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070021674{
21675 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
21676 int err = 0;
21677#ifdef FEATURE_WLAN_LPHB
21678 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070021679 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021680
21681 ENTER();
21682
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021683 err = wlan_hdd_validate_context(pHddCtx);
21684 if (0 != err)
21685 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021686 return err;
21687 }
Leo Chang9056f462013-08-01 19:21:11 -070021688#endif /* FEATURE_WLAN_LPHB */
21689
21690 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
21691 if (err)
21692 {
21693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21694 "%s Testmode INV ATTR", __func__);
21695 return err;
21696 }
21697
21698 if (!tb[WLAN_HDD_TM_ATTR_CMD])
21699 {
21700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21701 "%s Testmode INV CMD", __func__);
21702 return -EINVAL;
21703 }
21704
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021705 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21706 TRACE_CODE_HDD_CFG80211_TESTMODE,
21707 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070021708 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
21709 {
21710#ifdef FEATURE_WLAN_LPHB
21711 /* Low Power Heartbeat configuration request */
21712 case WLAN_HDD_TM_CMD_WLAN_HB:
21713 {
21714 int buf_len;
21715 void *buf;
21716 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080021717 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070021718
21719 if (!tb[WLAN_HDD_TM_ATTR_DATA])
21720 {
21721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21722 "%s Testmode INV DATA", __func__);
21723 return -EINVAL;
21724 }
21725
21726 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
21727 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080021728
Manjeet Singh3c577442017-02-10 19:03:38 +053021729 if (buf_len > sizeof(*hb_params)) {
21730 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
21731 buf_len);
21732 return -ERANGE;
21733 }
21734
Amar Singhal05852702014-02-04 14:40:00 -080021735 hb_params_temp =(tSirLPHBReq *)buf;
21736 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
21737 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
21738 return -EINVAL;
21739
Leo Chang9056f462013-08-01 19:21:11 -070021740 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
21741 if (NULL == hb_params)
21742 {
21743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21744 "%s Request Buffer Alloc Fail", __func__);
21745 return -EINVAL;
21746 }
21747
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053021748 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070021749 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070021750 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
21751 hb_params,
21752 wlan_hdd_cfg80211_lphb_ind_handler);
21753 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070021754 {
Leo Changd9df8aa2013-09-26 13:32:26 -070021755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21756 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070021757 vos_mem_free(hb_params);
21758 }
Leo Chang9056f462013-08-01 19:21:11 -070021759 return 0;
21760 }
21761#endif /* FEATURE_WLAN_LPHB */
21762 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21764 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070021765 return -EOPNOTSUPP;
21766 }
21767
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021768 EXIT();
21769 return err;
Leo Chang9056f462013-08-01 19:21:11 -070021770}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021771
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053021772static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
21773#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
21774 struct wireless_dev *wdev,
21775#endif
21776 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021777{
21778 int ret;
21779
21780 vos_ssr_protect(__func__);
21781 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
21782 vos_ssr_unprotect(__func__);
21783
21784 return ret;
21785}
Leo Chang9056f462013-08-01 19:21:11 -070021786#endif /* CONFIG_NL80211_TESTMODE */
21787
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021788extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021789static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021790 struct net_device *dev,
21791 int idx, struct survey_info *survey)
21792{
21793 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21794 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053021795 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021796 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053021797 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021798 v_S7_t snr,rssi;
21799 int status, i, j, filled = 0;
21800
21801 ENTER();
21802
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021803 if (NULL == pAdapter)
21804 {
21805 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21806 "%s: HDD adapter is Null", __func__);
21807 return -ENODEV;
21808 }
21809
21810 if (NULL == wiphy)
21811 {
21812 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21813 "%s: wiphy is Null", __func__);
21814 return -ENODEV;
21815 }
21816
21817 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21818 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021819 if (0 != status)
21820 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021821 return status;
21822 }
21823
Mihir Sheted9072e02013-08-21 17:02:29 +053021824 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21825
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021826 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053021827 0 != pAdapter->survey_idx ||
21828 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021829 {
21830 /* The survey dump ops when implemented completely is expected to
21831 * return a survey of all channels and the ops is called by the
21832 * kernel with incremental values of the argument 'idx' till it
21833 * returns -ENONET. But we can only support the survey for the
21834 * operating channel for now. survey_idx is used to track
21835 * that the ops is called only once and then return -ENONET for
21836 * the next iteration
21837 */
21838 pAdapter->survey_idx = 0;
21839 return -ENONET;
21840 }
21841
Mukul Sharma9d5233b2015-06-11 20:28:20 +053021842 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
21843 {
21844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21845 "%s: Roaming in progress, hence return ", __func__);
21846 return -ENONET;
21847 }
21848
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021849 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
21850
21851 wlan_hdd_get_snr(pAdapter, &snr);
21852 wlan_hdd_get_rssi(pAdapter, &rssi);
21853
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021854 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21855 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
21856 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021857 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
21858 hdd_wlan_get_freq(channel, &freq);
21859
21860
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053021861 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021862 {
21863 if (NULL == wiphy->bands[i])
21864 {
21865 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
21866 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
21867 continue;
21868 }
21869
21870 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
21871 {
21872 struct ieee80211_supported_band *band = wiphy->bands[i];
21873
21874 if (band->channels[j].center_freq == (v_U16_t)freq)
21875 {
21876 survey->channel = &band->channels[j];
21877 /* The Rx BDs contain SNR values in dB for the received frames
21878 * while the supplicant expects noise. So we calculate and
21879 * return the value of noise (dBm)
21880 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
21881 */
21882 survey->noise = rssi - snr;
21883 survey->filled = SURVEY_INFO_NOISE_DBM;
21884 filled = 1;
21885 }
21886 }
21887 }
21888
21889 if (filled)
21890 pAdapter->survey_idx = 1;
21891 else
21892 {
21893 pAdapter->survey_idx = 0;
21894 return -ENONET;
21895 }
21896
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021897 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021898 return 0;
21899}
21900
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021901static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
21902 struct net_device *dev,
21903 int idx, struct survey_info *survey)
21904{
21905 int ret;
21906
21907 vos_ssr_protect(__func__);
21908 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
21909 vos_ssr_unprotect(__func__);
21910
21911 return ret;
21912}
21913
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021914/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021915 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021916 * this is called when cfg80211 driver resume
21917 * driver updates latest sched_scan scan result(if any) to cfg80211 database
21918 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021919int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021920{
21921 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21922 hdd_adapter_t *pAdapter;
21923 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21924 VOS_STATUS status = VOS_STATUS_SUCCESS;
21925
21926 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021927
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021928 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021929 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021930 return 0;
21931 }
21932
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021933 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21934 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021935
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021936 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021937 {
21938 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21939 "%s: Resume SoftAP", __func__);
21940 hdd_set_wlan_suspend_mode(false);
21941 }
21942
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021943 spin_lock(&pHddCtx->schedScan_lock);
21944 pHddCtx->isWiphySuspended = FALSE;
21945 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21946 {
21947 spin_unlock(&pHddCtx->schedScan_lock);
21948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21949 "%s: Return resume is not due to PNO indication", __func__);
21950 return 0;
21951 }
21952 // Reset flag to avoid updatating cfg80211 data old results again
21953 pHddCtx->isSchedScanUpdatePending = FALSE;
21954 spin_unlock(&pHddCtx->schedScan_lock);
21955
21956 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21957
21958 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21959 {
21960 pAdapter = pAdapterNode->pAdapter;
21961 if ( (NULL != pAdapter) &&
21962 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21963 {
21964 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021965 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021966 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21967 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021968 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021969 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021970 {
21971 /* Acquire wakelock to handle the case where APP's tries to
21972 * suspend immediately after updating the scan results. Whis
21973 * results in app's is in suspended state and not able to
21974 * process the connect request to AP
21975 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021976 hdd_prevent_suspend_timeout(2000,
21977 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021978 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021979 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021980
21981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21982 "%s : cfg80211 scan result database updated", __func__);
21983
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021984 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021985 return 0;
21986
21987 }
21988 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21989 pAdapterNode = pNext;
21990 }
21991
21992 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21993 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021994 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021995 return 0;
21996}
21997
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021998int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21999{
22000 int ret;
22001
22002 vos_ssr_protect(__func__);
22003 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
22004 vos_ssr_unprotect(__func__);
22005
22006 return ret;
22007}
22008
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022009/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022010 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022011 * this is called when cfg80211 driver suspends
22012 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022013int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022014 struct cfg80211_wowlan *wow)
22015{
22016 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022017 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022018
22019 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022020
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022021 ret = wlan_hdd_validate_context(pHddCtx);
22022 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022023 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022024 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022025 }
22026
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053022027 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053022028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22029 "%s: Suspend SoftAP", __func__);
22030 hdd_set_wlan_suspend_mode(true);
22031 }
22032
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022033
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022034 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
22035 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
22036 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022037 pHddCtx->isWiphySuspended = TRUE;
22038
22039 EXIT();
22040
22041 return 0;
22042}
22043
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022044int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
22045 struct cfg80211_wowlan *wow)
22046{
22047 int ret;
22048
22049 vos_ssr_protect(__func__);
22050 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
22051 vos_ssr_unprotect(__func__);
22052
22053 return ret;
22054}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022055
22056#ifdef FEATURE_OEM_DATA_SUPPORT
22057static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022058 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022059{
22060 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22061
22062 ENTER();
22063
22064 if (wlan_hdd_validate_context(pHddCtx)) {
22065 return;
22066 }
22067 if (!pMsg)
22068 {
22069 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
22070 return;
22071 }
22072
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022073 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022074
22075 EXIT();
22076 return;
22077
22078}
22079
22080void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022081 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022082{
22083 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22084
22085 ENTER();
22086
22087 if (wlan_hdd_validate_context(pHddCtx)) {
22088 return;
22089 }
22090
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022091 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022092
22093 switch(evType) {
22094 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022095 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022096 break;
22097 default:
22098 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
22099 break;
22100 }
22101 EXIT();
22102}
22103#endif
22104
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022105#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22106 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022107/**
22108 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
22109 * @wiphy: Pointer to wiphy
22110 * @wdev: Pointer to wireless device structure
22111 *
22112 * This function is used to abort an ongoing scan
22113 *
22114 * Return: None
22115 */
22116static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22117 struct wireless_dev *wdev)
22118{
22119 struct net_device *dev = wdev->netdev;
22120 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22121 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
22122 int ret;
22123
22124 ENTER();
22125
22126 if (NULL == adapter) {
22127 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
22128 return;
22129 }
22130
22131 ret = wlan_hdd_validate_context(hdd_ctx);
22132 if (0 != ret)
22133 return;
22134
22135 wlan_hdd_scan_abort(adapter);
22136
22137 return;
22138}
22139
22140/**
22141 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
22142 * @wiphy: Pointer to wiphy
22143 * @wdev: Pointer to wireless device structure
22144 *
22145 * Return: None
22146 */
22147void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22148 struct wireless_dev *wdev)
22149{
22150 vos_ssr_protect(__func__);
22151 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
22152 vos_ssr_unprotect(__func__);
22153
22154 return;
22155}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022156#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022157
Abhishek Singh936c6932017-11-07 17:28:23 +053022158#ifdef CHANNEL_SWITCH_SUPPORTED
22159/**
22160 * __wlan_hdd_cfg80211_channel_switch()- function to switch
22161 * channel in SAP/GO
22162 * @wiphy: wiphy pointer
22163 * @dev: dev pointer.
22164 * @csa_params: Change channel params
22165 *
22166 * This function is called to switch channel in SAP/GO
22167 *
22168 * Return: 0 if success else return non zero
22169 */
22170static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22171 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22172{
22173 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22174 hdd_context_t *hdd_ctx;
22175 uint8_t channel;
22176 int ret;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022177 ptSapContext sap_ctx;
Abhishek Singh936c6932017-11-07 17:28:23 +053022178 v_CONTEXT_t vos_ctx;
22179
22180 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
22181
22182 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
22183 ret = wlan_hdd_validate_context(hdd_ctx);
22184 if (ret)
22185 return ret;
22186
22187 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
22188 if (!vos_ctx) {
22189 hddLog(LOGE, FL("Vos ctx is null"));
22190 return -EINVAL;
22191 }
22192
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022193 if (WLAN_HDD_SOFTAP != adapter->device_mode)
Abhishek Singh936c6932017-11-07 17:28:23 +053022194 return -ENOTSUPP;
22195
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022196 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
22197 if (!sap_ctx) {
22198 hddLog(LOGE, FL("sap_ctx is NULL"));
22199 return -EINVAL;
22200 }
22201
22202 ret = wlansap_chk_n_set_chan_change_in_progress(sap_ctx);
22203 if (ret)
22204 return ret;
22205
22206 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
22207
Abhishek Singh936c6932017-11-07 17:28:23 +053022208 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053022209 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053022210
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022211 if (ret) {
22212 wlansap_reset_chan_change_in_progress(sap_ctx);
22213 complete(&sap_ctx->ecsa_info.chan_switch_comp);
22214 }
22215
Abhishek Singh936c6932017-11-07 17:28:23 +053022216 return ret;
22217}
22218
22219/**
22220 * wlan_hdd_cfg80211_channel_switch()- function to switch
22221 * channel in SAP/GO
22222 * @wiphy: wiphy pointer
22223 * @dev: dev pointer.
22224 * @csa_params: Change channel params
22225 *
22226 * This function is called to switch channel in SAP/GO
22227 *
22228 * Return: 0 if success else return non zero
22229 */
22230static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22231 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22232{
22233 int ret;
22234
22235 vos_ssr_protect(__func__);
22236 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
22237 vos_ssr_unprotect(__func__);
22238
22239 return ret;
22240}
22241#endif
22242
Jeff Johnson295189b2012-06-20 16:38:30 -070022243/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053022244static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070022245{
22246 .add_virtual_intf = wlan_hdd_add_virtual_intf,
22247 .del_virtual_intf = wlan_hdd_del_virtual_intf,
22248 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
22249 .change_station = wlan_hdd_change_station,
22250#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
22251 .add_beacon = wlan_hdd_cfg80211_add_beacon,
22252 .del_beacon = wlan_hdd_cfg80211_del_beacon,
22253 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022254#else
22255 .start_ap = wlan_hdd_cfg80211_start_ap,
22256 .change_beacon = wlan_hdd_cfg80211_change_beacon,
22257 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070022258#endif
22259 .change_bss = wlan_hdd_cfg80211_change_bss,
22260 .add_key = wlan_hdd_cfg80211_add_key,
22261 .get_key = wlan_hdd_cfg80211_get_key,
22262 .del_key = wlan_hdd_cfg80211_del_key,
22263 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022264#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070022265 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022266#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022267 .scan = wlan_hdd_cfg80211_scan,
22268 .connect = wlan_hdd_cfg80211_connect,
22269 .disconnect = wlan_hdd_cfg80211_disconnect,
22270 .join_ibss = wlan_hdd_cfg80211_join_ibss,
22271 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
22272 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
22273 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
22274 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070022275 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
22276 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053022277 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070022278#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
22279 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
22280 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
22281 .set_txq_params = wlan_hdd_set_txq_params,
22282#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022283 .get_station = wlan_hdd_cfg80211_get_station,
22284 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
22285 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022286 .add_station = wlan_hdd_cfg80211_add_station,
22287#ifdef FEATURE_WLAN_LFR
22288 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
22289 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
22290 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
22291#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070022292#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
22293 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
22294#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080022295#ifdef FEATURE_WLAN_TDLS
22296 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
22297 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
22298#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053022299#ifdef WLAN_FEATURE_GTK_OFFLOAD
22300 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
22301#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053022302#ifdef FEATURE_WLAN_SCAN_PNO
22303 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
22304 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
22305#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022306 .resume = wlan_hdd_cfg80211_resume_wlan,
22307 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053022308 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070022309#ifdef WLAN_NL80211_TESTMODE
22310 .testmode_cmd = wlan_hdd_cfg80211_testmode,
22311#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022312 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022313#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22314 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022315 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022316#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053022317#ifdef CHANNEL_SWITCH_SUPPORTED
22318 .channel_switch = wlan_hdd_cfg80211_channel_switch,
22319#endif
22320
Jeff Johnson295189b2012-06-20 16:38:30 -070022321};
22322