blob: b1ccb19dcc241864e22446ed022999991ca5b145 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05302 * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053066#include <linux/etherdevice.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067#include <wlan_hdd_includes.h>
68#include <net/arp.h>
69#include <net/cfg80211.h>
70#include <linux/wireless.h>
71#include <wlan_hdd_wowl.h>
72#include <aniGlobal.h>
73#include "ccmApi.h"
74#include "sirParams.h"
75#include "dot11f.h"
76#include "wlan_hdd_assoc.h"
77#include "wlan_hdd_wext.h"
78#include "sme_Api.h"
79#include "wlan_hdd_p2p.h"
80#include "wlan_hdd_cfg80211.h"
81#include "wlan_hdd_hostapd.h"
82#include "sapInternal.h"
83#include "wlan_hdd_softap_tx_rx.h"
84#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053085#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053086#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053087#include "wlan_hdd_trace.h"
88#include "vos_types.h"
89#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070090#ifdef WLAN_BTAMP_FEATURE
91#include "bap_hdd_misc.h"
92#endif
93#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080094#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053095#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053096#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053097#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070098#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053099#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +0530100#include "wlan_logging_sock_svc.h"
Agrawal Ashishcfe83282016-09-29 13:03:45 +0530101#include "wlan_hdd_misc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530102
Jeff Johnson295189b2012-06-20 16:38:30 -0700103
104#define g_mode_rates_size (12)
105#define a_mode_rates_size (8)
106#define FREQ_BASE_80211G (2407)
107#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700108#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530109#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800111 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700112
113#define HDD2GHZCHAN(freq, chan, flag) { \
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530114 .band = HDD_NL80211_BAND_2GHZ, \
Jeff Johnson295189b2012-06-20 16:38:30 -0700115 .center_freq = (freq), \
116 .hw_value = (chan),\
117 .flags = (flag), \
118 .max_antenna_gain = 0 ,\
119 .max_power = 30, \
120}
121
122#define HDD5GHZCHAN(freq, chan, flag) { \
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530123 .band = HDD_NL80211_BAND_5GHZ, \
Jeff Johnson295189b2012-06-20 16:38:30 -0700124 .center_freq = (freq), \
125 .hw_value = (chan),\
126 .flags = (flag), \
127 .max_antenna_gain = 0 ,\
128 .max_power = 30, \
129}
130
131#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
132{\
133 .bitrate = rate, \
134 .hw_value = rate_id, \
135 .flags = flag, \
136}
137
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530138#ifdef WLAN_FEATURE_VOWIFI_11R
139#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
140#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
141#endif
142
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530143#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530144#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530145
Sunil Duttc69bccb2014-05-26 21:30:20 +0530146#ifdef WLAN_FEATURE_LINK_LAYER_STATS
147/*
148 * Used to allocate the size of 4096 for the link layer stats.
149 * The size of 4096 is considered assuming that all data per
150 * respective event fit with in the limit.Please take a call
151 * on the limit based on the data requirements on link layer
152 * statistics.
153 */
154#define LL_STATS_EVENT_BUF_SIZE 4096
155#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530156#ifdef WLAN_FEATURE_EXTSCAN
157/*
158 * Used to allocate the size of 4096 for the EXTScan NL data.
159 * The size of 4096 is considered assuming that all data per
160 * respective event fit with in the limit.Please take a call
161 * on the limit based on the data requirements.
162 */
163
164#define EXTSCAN_EVENT_BUF_SIZE 4096
165#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
166#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530167
Atul Mittal115287b2014-07-08 13:26:33 +0530168/*EXT TDLS*/
169/*
170 * Used to allocate the size of 4096 for the TDLS.
171 * The size of 4096 is considered assuming that all data per
172 * respective event fit with in the limit.Please take a call
173 * on the limit based on the data requirements on link layer
174 * statistics.
175 */
176#define EXTTDLS_EVENT_BUF_SIZE 4096
177
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530178/*
179 * Values for Mac spoofing feature
180 *
181 */
182#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
183#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
184#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530185#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
186
Anurag Chouhan343af7e2016-12-16 13:11:19 +0530187/*
188 * max_sched_scan_plans defined to 10
189 */
190#define MAX_SCHED_SCAN_PLANS 10
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530191
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530192static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700193{
194 WLAN_CIPHER_SUITE_WEP40,
195 WLAN_CIPHER_SUITE_WEP104,
196 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800197#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700198#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
199 WLAN_CIPHER_SUITE_KRK,
200 WLAN_CIPHER_SUITE_CCMP,
201#else
202 WLAN_CIPHER_SUITE_CCMP,
203#endif
204#ifdef FEATURE_WLAN_WAPI
205 WLAN_CIPHER_SUITE_SMS4,
206#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700207#ifdef WLAN_FEATURE_11W
208 WLAN_CIPHER_SUITE_AES_CMAC,
209#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700210};
211
Agrawal Ashish97dec502015-11-26 20:20:58 +0530212const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530213{
Jeff Johnson295189b2012-06-20 16:38:30 -0700214 HDD2GHZCHAN(2412, 1, 0) ,
215 HDD2GHZCHAN(2417, 2, 0) ,
216 HDD2GHZCHAN(2422, 3, 0) ,
217 HDD2GHZCHAN(2427, 4, 0) ,
218 HDD2GHZCHAN(2432, 5, 0) ,
219 HDD2GHZCHAN(2437, 6, 0) ,
220 HDD2GHZCHAN(2442, 7, 0) ,
221 HDD2GHZCHAN(2447, 8, 0) ,
222 HDD2GHZCHAN(2452, 9, 0) ,
223 HDD2GHZCHAN(2457, 10, 0) ,
224 HDD2GHZCHAN(2462, 11, 0) ,
225 HDD2GHZCHAN(2467, 12, 0) ,
226 HDD2GHZCHAN(2472, 13, 0) ,
227 HDD2GHZCHAN(2484, 14, 0) ,
228};
229
Agrawal Ashish97dec502015-11-26 20:20:58 +0530230const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700231{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700232 HDD5GHZCHAN(4920, 240, 0) ,
233 HDD5GHZCHAN(4940, 244, 0) ,
234 HDD5GHZCHAN(4960, 248, 0) ,
235 HDD5GHZCHAN(4980, 252, 0) ,
236 HDD5GHZCHAN(5040, 208, 0) ,
237 HDD5GHZCHAN(5060, 212, 0) ,
238 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 HDD5GHZCHAN(5180, 36, 0) ,
240 HDD5GHZCHAN(5200, 40, 0) ,
241 HDD5GHZCHAN(5220, 44, 0) ,
242 HDD5GHZCHAN(5240, 48, 0) ,
243 HDD5GHZCHAN(5260, 52, 0) ,
244 HDD5GHZCHAN(5280, 56, 0) ,
245 HDD5GHZCHAN(5300, 60, 0) ,
246 HDD5GHZCHAN(5320, 64, 0) ,
247 HDD5GHZCHAN(5500,100, 0) ,
248 HDD5GHZCHAN(5520,104, 0) ,
249 HDD5GHZCHAN(5540,108, 0) ,
250 HDD5GHZCHAN(5560,112, 0) ,
251 HDD5GHZCHAN(5580,116, 0) ,
252 HDD5GHZCHAN(5600,120, 0) ,
253 HDD5GHZCHAN(5620,124, 0) ,
254 HDD5GHZCHAN(5640,128, 0) ,
255 HDD5GHZCHAN(5660,132, 0) ,
256 HDD5GHZCHAN(5680,136, 0) ,
257 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800258#ifdef FEATURE_WLAN_CH144
259 HDD5GHZCHAN(5720,144, 0) ,
260#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 HDD5GHZCHAN(5745,149, 0) ,
262 HDD5GHZCHAN(5765,153, 0) ,
263 HDD5GHZCHAN(5785,157, 0) ,
264 HDD5GHZCHAN(5805,161, 0) ,
265 HDD5GHZCHAN(5825,165, 0) ,
266};
267
268static struct ieee80211_rate g_mode_rates[] =
269{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530270 HDD_G_MODE_RATETAB(10, 0x1, 0),
271 HDD_G_MODE_RATETAB(20, 0x2, 0),
272 HDD_G_MODE_RATETAB(55, 0x4, 0),
273 HDD_G_MODE_RATETAB(110, 0x8, 0),
274 HDD_G_MODE_RATETAB(60, 0x10, 0),
275 HDD_G_MODE_RATETAB(90, 0x20, 0),
276 HDD_G_MODE_RATETAB(120, 0x40, 0),
277 HDD_G_MODE_RATETAB(180, 0x80, 0),
278 HDD_G_MODE_RATETAB(240, 0x100, 0),
279 HDD_G_MODE_RATETAB(360, 0x200, 0),
280 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530282};
Jeff Johnson295189b2012-06-20 16:38:30 -0700283
284static struct ieee80211_rate a_mode_rates[] =
285{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530286 HDD_G_MODE_RATETAB(60, 0x10, 0),
287 HDD_G_MODE_RATETAB(90, 0x20, 0),
288 HDD_G_MODE_RATETAB(120, 0x40, 0),
289 HDD_G_MODE_RATETAB(180, 0x80, 0),
290 HDD_G_MODE_RATETAB(240, 0x100, 0),
291 HDD_G_MODE_RATETAB(360, 0x200, 0),
292 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 HDD_G_MODE_RATETAB(540, 0x800, 0),
294};
295
296static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
297{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530298 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700299 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530300 .band = HDD_NL80211_BAND_2GHZ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700301 .bitrates = g_mode_rates,
302 .n_bitrates = g_mode_rates_size,
303 .ht_cap.ht_supported = 1,
304 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
305 | IEEE80211_HT_CAP_GRN_FLD
306 | IEEE80211_HT_CAP_DSSSCCK40
307 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
308 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
309 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
310 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
311 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
312 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
313};
314
Jeff Johnson295189b2012-06-20 16:38:30 -0700315static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
316{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530317 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700318 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530319 .band = HDD_NL80211_BAND_5GHZ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700320 .bitrates = a_mode_rates,
321 .n_bitrates = a_mode_rates_size,
322 .ht_cap.ht_supported = 1,
323 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
324 | IEEE80211_HT_CAP_GRN_FLD
325 | IEEE80211_HT_CAP_DSSSCCK40
326 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
327 | IEEE80211_HT_CAP_SGI_40
328 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
329 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
330 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
331 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
332 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
333 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
334};
335
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530336/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700337 TX/RX direction for each kind of interface */
338static const struct ieee80211_txrx_stypes
339wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
340 [NL80211_IFTYPE_STATION] = {
341 .tx = 0xffff,
342 .rx = BIT(SIR_MAC_MGMT_ACTION) |
343 BIT(SIR_MAC_MGMT_PROBE_REQ),
344 },
345 [NL80211_IFTYPE_AP] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
348 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
349 BIT(SIR_MAC_MGMT_PROBE_REQ) |
350 BIT(SIR_MAC_MGMT_DISASSOC) |
351 BIT(SIR_MAC_MGMT_AUTH) |
352 BIT(SIR_MAC_MGMT_DEAUTH) |
353 BIT(SIR_MAC_MGMT_ACTION),
354 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700355 [NL80211_IFTYPE_ADHOC] = {
356 .tx = 0xffff,
357 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
358 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
359 BIT(SIR_MAC_MGMT_PROBE_REQ) |
360 BIT(SIR_MAC_MGMT_DISASSOC) |
361 BIT(SIR_MAC_MGMT_AUTH) |
362 BIT(SIR_MAC_MGMT_DEAUTH) |
363 BIT(SIR_MAC_MGMT_ACTION),
364 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700365 [NL80211_IFTYPE_P2P_CLIENT] = {
366 .tx = 0xffff,
367 .rx = BIT(SIR_MAC_MGMT_ACTION) |
368 BIT(SIR_MAC_MGMT_PROBE_REQ),
369 },
370 [NL80211_IFTYPE_P2P_GO] = {
371 /* This is also same as for SoftAP */
372 .tx = 0xffff,
373 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
374 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
375 BIT(SIR_MAC_MGMT_PROBE_REQ) |
376 BIT(SIR_MAC_MGMT_DISASSOC) |
377 BIT(SIR_MAC_MGMT_AUTH) |
378 BIT(SIR_MAC_MGMT_DEAUTH) |
379 BIT(SIR_MAC_MGMT_ACTION),
380 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700381};
382
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800383#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800384static const struct ieee80211_iface_limit
385wlan_hdd_iface_limit[] = {
386 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800387 /* max = 3 ; Our driver create two interfaces during driver init
388 * wlan0 and p2p0 interfaces. p2p0 is considered as station
389 * interface until a group is formed. In JB architecture, once the
390 * group is formed, interface type of p2p0 is changed to P2P GO or
391 * Client.
392 * When supplicant remove the group, it first issue a set interface
393 * cmd to change the mode back to Station. In JB this works fine as
394 * we advertize two station type interface during driver init.
395 * Some vendors create separate interface for P2P GO/Client,
396 * after group formation(Third one). But while group remove
397 * supplicant first tries to change the mode(3rd interface) to STATION
398 * But as we advertized only two sta type interfaces nl80211 was
399 * returning error for the third one which was leading to failure in
400 * delete interface. Ideally while removing the group, supplicant
401 * should not try to change the 3rd interface mode to Station type.
402 * Till we get a fix in wpa_supplicant, we advertize max STA
403 * interface type to 3
404 */
405 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800406 .types = BIT(NL80211_IFTYPE_STATION),
407 },
408 {
409 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700410 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 },
412 {
413 .max = 1,
414 .types = BIT(NL80211_IFTYPE_P2P_GO) |
415 BIT(NL80211_IFTYPE_P2P_CLIENT),
416 },
417};
418
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530419/* interface limits for sta + monitor SCC */
420static const struct ieee80211_iface_limit
421wlan_hdd_iface_sta_mon_limit[] = {
422 {
423 .max = 1,
424 .types = BIT(NL80211_IFTYPE_STATION),
425 },
426 {
427 .max = 1, /* Monitor interface */
428 .types = BIT(NL80211_IFTYPE_MONITOR),
429 },
430};
431
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800432/* By default, only single channel concurrency is allowed */
433static struct ieee80211_iface_combination
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530434wlan_hdd_iface_combination[] = {
435 {
436 .limits = wlan_hdd_iface_limit,
437 .num_different_channels = 1,
438 /*
439 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
440 * and p2p0 interfaces during driver init
441 * Some vendors create separate interface for P2P operations.
442 * wlan0: STA interface
443 * p2p0: P2P Device interface, action frames goes
444 * through this interface.
445 * p2p-xx: P2P interface, After GO negotiation this interface is
446 * created for p2p operations(GO/CLIENT interface).
447 */
448 .max_interfaces = WLAN_MAX_INTERFACES,
449 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
450 .beacon_int_infra_match = false,
451 },
452 {
453 .limits = wlan_hdd_iface_sta_mon_limit,
454 .num_different_channels = 1,
455 .max_interfaces = WLAN_STA_AND_MON_INTERFACES,
456 .n_limits = ARRAY_SIZE(wlan_hdd_iface_sta_mon_limit),
457 .beacon_int_infra_match = false,
458 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800459};
460#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800461
Jeff Johnson295189b2012-06-20 16:38:30 -0700462static struct cfg80211_ops wlan_hdd_cfg80211_ops;
463
464/* Data rate 100KBPS based on IE Index */
465struct index_data_rate_type
466{
467 v_U8_t beacon_rate_index;
468 v_U16_t supported_rate[4];
469};
470
471/* 11B, 11G Rate table include Basic rate and Extended rate
472 The IDX field is the rate index
473 The HI field is the rate when RSSI is strong or being ignored
474 (in this case we report actual rate)
475 The MID field is the rate when RSSI is moderate
476 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
477 The LO field is the rate when RSSI is low
478 (in this case we don't report rates, actual current rate used)
479 */
480static const struct
481{
482 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700483 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700484} supported_data_rate[] =
485{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700486/* IDX HI HM LM LO (RSSI-based index */
487 {2, { 10, 10, 10, 0}},
488 {4, { 20, 20, 10, 0}},
489 {11, { 55, 20, 10, 0}},
490 {12, { 60, 55, 20, 0}},
491 {18, { 90, 55, 20, 0}},
492 {22, {110, 55, 20, 0}},
493 {24, {120, 90, 60, 0}},
494 {36, {180, 120, 60, 0}},
495 {44, {220, 180, 60, 0}},
496 {48, {240, 180, 90, 0}},
497 {66, {330, 180, 90, 0}},
498 {72, {360, 240, 90, 0}},
499 {96, {480, 240, 120, 0}},
500 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700501};
502
503/* MCS Based rate table */
504static struct index_data_rate_type supported_mcs_rate[] =
505{
506/* MCS L20 L40 S20 S40 */
507 {0, {65, 135, 72, 150}},
508 {1, {130, 270, 144, 300}},
509 {2, {195, 405, 217, 450}},
510 {3, {260, 540, 289, 600}},
511 {4, {390, 810, 433, 900}},
512 {5, {520, 1080, 578, 1200}},
513 {6, {585, 1215, 650, 1350}},
514 {7, {650, 1350, 722, 1500}}
515};
516
Leo Chang6f8870f2013-03-26 18:11:36 -0700517#ifdef WLAN_FEATURE_11AC
518
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530519#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700520
521struct index_vht_data_rate_type
522{
523 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530524 v_U16_t supported_VHT80_rate[2];
525 v_U16_t supported_VHT40_rate[2];
526 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700527};
528
529typedef enum
530{
531 DATA_RATE_11AC_MAX_MCS_7,
532 DATA_RATE_11AC_MAX_MCS_8,
533 DATA_RATE_11AC_MAX_MCS_9,
534 DATA_RATE_11AC_MAX_MCS_NA
535} eDataRate11ACMaxMcs;
536
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530537/* SSID broadcast type */
538typedef enum eSSIDBcastType
539{
540 eBCAST_UNKNOWN = 0,
541 eBCAST_NORMAL = 1,
542 eBCAST_HIDDEN = 2,
543} tSSIDBcastType;
544
Leo Chang6f8870f2013-03-26 18:11:36 -0700545/* MCS Based VHT rate table */
546static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
547{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530548/* MCS L80 S80 L40 S40 L20 S40*/
549 {0, {293, 325}, {135, 150}, {65, 72}},
550 {1, {585, 650}, {270, 300}, {130, 144}},
551 {2, {878, 975}, {405, 450}, {195, 217}},
552 {3, {1170, 1300}, {540, 600}, {260, 289}},
553 {4, {1755, 1950}, {810, 900}, {390, 433}},
554 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
555 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
556 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
557 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
558 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700559};
560#endif /* WLAN_FEATURE_11AC */
561
c_hpothu79aab322014-07-14 21:11:01 +0530562/*array index points to MCS and array value points respective rssi*/
563static int rssiMcsTbl[][10] =
564{
565/*MCS 0 1 2 3 4 5 6 7 8 9*/
566 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
567 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
568 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
569};
570
Jeff Johnson295189b2012-06-20 16:38:30 -0700571extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530572#ifdef FEATURE_WLAN_SCAN_PNO
573static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
574#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700575
Leo Chang9056f462013-08-01 19:21:11 -0700576#ifdef WLAN_NL80211_TESTMODE
577enum wlan_hdd_tm_attr
578{
579 WLAN_HDD_TM_ATTR_INVALID = 0,
580 WLAN_HDD_TM_ATTR_CMD = 1,
581 WLAN_HDD_TM_ATTR_DATA = 2,
582 WLAN_HDD_TM_ATTR_TYPE = 3,
583 /* keep last */
584 WLAN_HDD_TM_ATTR_AFTER_LAST,
585 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
586};
587
588enum wlan_hdd_tm_cmd
589{
590 WLAN_HDD_TM_CMD_WLAN_HB = 1,
591};
592
593#define WLAN_HDD_TM_DATA_MAX_LEN 5000
594
595static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
596{
597 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
598 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
599 .len = WLAN_HDD_TM_DATA_MAX_LEN },
600};
601#endif /* WLAN_NL80211_TESTMODE */
602
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800603#ifdef FEATURE_WLAN_CH_AVOID
604/*
605 * FUNCTION: wlan_hdd_send_avoid_freq_event
606 * This is called when wlan driver needs to send vendor specific
607 * avoid frequency range event to userspace
608 */
609int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
610 tHddAvoidFreqList *pAvoidFreqList)
611{
612 struct sk_buff *vendor_event;
613
614 ENTER();
615
616 if (!pHddCtx)
617 {
618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
619 "%s: HDD context is null", __func__);
620 return -1;
621 }
622
623 if (!pAvoidFreqList)
624 {
625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
626 "%s: pAvoidFreqList is null", __func__);
627 return -1;
628 }
629
630 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530631#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
632 NULL,
633#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800634 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530635 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800636 GFP_KERNEL);
637 if (!vendor_event)
638 {
639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
640 "%s: cfg80211_vendor_event_alloc failed", __func__);
641 return -1;
642 }
643
644 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
645 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
646
647 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
648
649 EXIT();
650 return 0;
651}
652#endif /* FEATURE_WLAN_CH_AVOID */
653
Srinivas Dasari030bad32015-02-18 23:23:54 +0530654/*
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +0530655 * define short names for the global vendor params
656 * used by QCA_NL80211_VENDOR_SUBCMD_HANG
657 */
658#define HANG_REASON_INDEX QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX
659
660/**
661 * hdd_convert_hang_reason() - Convert cds recovery reason to vendor specific
662 * hang reason
663 * @reason: cds recovery reason
664 *
665 * Return: Vendor specific reason code
666 */
667static enum qca_wlan_vendor_hang_reason
668hdd_convert_hang_reason(enum vos_hang_reason reason)
669{
670 unsigned int ret_val;
671
672 switch (reason) {
673 case VOS_GET_MSG_BUFF_FAILURE:
674 ret_val = QCA_WLAN_HANG_GET_MSG_BUFF_FAILURE;
675 break;
676 case VOS_ACTIVE_LIST_TIMEOUT:
677 ret_val = QCA_WLAN_HANG_ACTIVE_LIST_TIMEOUT;
678 break;
679 case VOS_SCAN_REQ_EXPIRED:
680 ret_val = QCA_WLAN_HANG_SCAN_REQ_EXPIRED;
681 break;
682 case VOS_TRANSMISSIONS_TIMEOUT:
683 ret_val = QCA_WLAN_HANG_TRANSMISSIONS_TIMEOUT;
684 break;
685 case VOS_DXE_FAILURE:
686 ret_val = QCA_WLAN_HANG_DXE_FAILURE;
687 break;
688 case VOS_WDI_FAILURE:
689 ret_val = QCA_WLAN_HANG_WDI_FAILURE;
690 break;
691 case VOS_REASON_UNSPECIFIED:
692 default:
693 ret_val = QCA_WLAN_HANG_REASON_UNSPECIFIED;
694 }
695 return ret_val;
696}
697
698/**
699 * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace
700 * @hdd_ctx: Pointer to hdd context
701 * @reason: cds recovery reason
702 *
703 * Return: 0 on success or failure reason
704 */
705int wlan_hdd_send_hang_reason_event(hdd_context_t *hdd_ctx,
706 enum vos_hang_reason reason)
707{
708 struct sk_buff *vendor_event;
709 enum qca_wlan_vendor_hang_reason hang_reason;
710
711 ENTER();
712
713 if (!hdd_ctx) {
714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
715 "HDD context is null");
716 return -EINVAL;
717 }
718
719 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
720#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
721 NULL,
722#endif
723 sizeof(unsigned int),
724 HANG_REASON_INDEX,
725 GFP_KERNEL);
726 if (!vendor_event) {
727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
728 "cfg80211_vendor_event_alloc failed");
729 return -ENOMEM;
730 }
731
732 hang_reason = hdd_convert_hang_reason(reason);
733
734 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_HANG_REASON,
735 (unsigned int) hang_reason)) {
736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
737 "QCA_WLAN_VENDOR_ATTR_HANG_REASON put fail");
738 kfree_skb(vendor_event);
739 return -EINVAL;
740 }
741
742 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
743
744 EXIT();
745 return 0;
746}
747#undef HANG_REASON_INDEX
748
749/*
Srinivas Dasari030bad32015-02-18 23:23:54 +0530750 * FUNCTION: __wlan_hdd_cfg80211_nan_request
751 * This is called when wlan driver needs to send vendor specific
752 * nan request event.
753 */
754static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
755 struct wireless_dev *wdev,
756 const void *data, int data_len)
757{
758 tNanRequestReq nan_req;
759 VOS_STATUS status;
760 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530761 struct net_device *dev = wdev->netdev;
762 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
763 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530764 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
765
766 if (0 == data_len)
767 {
768 hddLog(VOS_TRACE_LEVEL_ERROR,
769 FL("NAN - Invalid Request, length = 0"));
770 return ret_val;
771 }
772
773 if (NULL == data)
774 {
775 hddLog(VOS_TRACE_LEVEL_ERROR,
776 FL("NAN - Invalid Request, data is NULL"));
777 return ret_val;
778 }
779
780 status = wlan_hdd_validate_context(pHddCtx);
781 if (0 != status)
782 {
783 hddLog(VOS_TRACE_LEVEL_ERROR,
784 FL("HDD context is not valid"));
785 return -EINVAL;
786 }
787
788 hddLog(LOG1, FL("Received NAN command"));
789 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
790 (tANI_U8 *)data, data_len);
791
792 /* check the NAN Capability */
793 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
794 {
795 hddLog(VOS_TRACE_LEVEL_ERROR,
796 FL("NAN is not supported by Firmware"));
797 return -EINVAL;
798 }
799
800 nan_req.request_data_len = data_len;
801 nan_req.request_data = data;
802
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530803 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530804 if (VOS_STATUS_SUCCESS == status)
805 {
806 ret_val = 0;
807 }
808 return ret_val;
809}
810
811/*
812 * FUNCTION: wlan_hdd_cfg80211_nan_request
813 * Wrapper to protect the nan vendor command from ssr
814 */
815static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
816 struct wireless_dev *wdev,
817 const void *data, int data_len)
818{
819 int ret;
820
821 vos_ssr_protect(__func__);
822 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
823 vos_ssr_unprotect(__func__);
824
825 return ret;
826}
827
828/*
829 * FUNCTION: wlan_hdd_cfg80211_nan_callback
830 * This is a callback function and it gets called
831 * when we need to report nan response event to
832 * upper layers.
833 */
834static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
835{
836 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
837 struct sk_buff *vendor_event;
838 int status;
839 tSirNanEvent *data;
840
841 ENTER();
842 if (NULL == msg)
843 {
844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
845 FL(" msg received here is null"));
846 return;
847 }
848 data = msg;
849
850 status = wlan_hdd_validate_context(pHddCtx);
851
852 if (0 != status)
853 {
854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
855 FL("HDD context is not valid"));
856 return;
857 }
858
859 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530860#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
861 NULL,
862#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530863 data->event_data_len +
864 NLMSG_HDRLEN,
865 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
866 GFP_KERNEL);
867
868 if (!vendor_event)
869 {
870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
871 FL("cfg80211_vendor_event_alloc failed"));
872 return;
873 }
874 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
875 data->event_data_len, data->event_data))
876 {
877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
878 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
879 kfree_skb(vendor_event);
880 return;
881 }
882 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
883 EXIT();
884}
885
886/*
887 * FUNCTION: wlan_hdd_cfg80211_nan_init
888 * This function is called to register the callback to sme layer
889 */
890inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
891{
892 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
893}
894
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530895/*
896 * define short names for the global vendor params
897 * used by __wlan_hdd_cfg80211_get_station_cmd()
898 */
899#define STATION_INVALID \
900 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
901#define STATION_INFO \
902 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
903#define STATION_ASSOC_FAIL_REASON \
904 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +0530905#define STATION_REMOTE \
906 QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530907#define STATION_MAX \
908 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
909
910static const struct nla_policy
911hdd_get_station_policy[STATION_MAX + 1] = {
912 [STATION_INFO] = {.type = NLA_FLAG},
913 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
914};
915
916/**
917 * hdd_get_station_assoc_fail() - Handle get station assoc fail
918 * @hdd_ctx: HDD context within host driver
919 * @wdev: wireless device
920 *
921 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
922 * Validate cmd attributes and send the station info to upper layers.
923 *
924 * Return: Success(0) or reason code for failure
925 */
926static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
927 hdd_adapter_t *adapter)
928{
929 struct sk_buff *skb = NULL;
930 uint32_t nl_buf_len;
931 hdd_station_ctx_t *hdd_sta_ctx;
932
933 nl_buf_len = NLMSG_HDRLEN;
934 nl_buf_len += sizeof(uint32_t);
935 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
936
937 if (!skb) {
938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
939 return -ENOMEM;
940 }
941
942 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
943
944 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
945 hdd_sta_ctx->conn_info.assoc_status_code)) {
946 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
947 goto fail;
948 }
949 return cfg80211_vendor_cmd_reply(skb);
950fail:
951 if (skb)
952 kfree_skb(skb);
953 return -EINVAL;
954}
955
956/**
957 * hdd_map_auth_type() - transform auth type specific to
958 * vendor command
959 * @auth_type: csr auth type
960 *
961 * Return: Success(0) or reason code for failure
962 */
963static int hdd_convert_auth_type(uint32_t auth_type)
964{
965 uint32_t ret_val;
966
967 switch (auth_type) {
968 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
969 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
970 break;
971 case eCSR_AUTH_TYPE_SHARED_KEY:
972 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
973 break;
974 case eCSR_AUTH_TYPE_WPA:
975 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
976 break;
977 case eCSR_AUTH_TYPE_WPA_PSK:
978 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
979 break;
980 case eCSR_AUTH_TYPE_AUTOSWITCH:
981 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
982 break;
983 case eCSR_AUTH_TYPE_WPA_NONE:
984 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
985 break;
986 case eCSR_AUTH_TYPE_RSN:
987 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
988 break;
989 case eCSR_AUTH_TYPE_RSN_PSK:
990 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
991 break;
992 case eCSR_AUTH_TYPE_FT_RSN:
993 ret_val = QCA_WLAN_AUTH_TYPE_FT;
994 break;
995 case eCSR_AUTH_TYPE_FT_RSN_PSK:
996 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
997 break;
998 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
999 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
1000 break;
1001 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
1002 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
1003 break;
1004#ifdef FEATURE_WLAN_ESE
1005 case eCSR_AUTH_TYPE_CCKM_WPA:
1006 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
1007 break;
1008 case eCSR_AUTH_TYPE_CCKM_RSN:
1009 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
1010 break;
1011#endif
1012 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
1013 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
1014 break;
1015 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
1016 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
1017 break;
1018 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
1019 case eCSR_AUTH_TYPE_FAILED:
1020 case eCSR_AUTH_TYPE_NONE:
1021 default:
1022 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
1023 break;
1024 }
1025 return ret_val;
1026}
1027
1028/**
1029 * hdd_map_dot_11_mode() - transform dot11mode type specific to
1030 * vendor command
1031 * @dot11mode: dot11mode
1032 *
1033 * Return: Success(0) or reason code for failure
1034 */
1035static int hdd_convert_dot11mode(uint32_t dot11mode)
1036{
1037 uint32_t ret_val;
1038
1039 switch (dot11mode) {
1040 case eCSR_CFG_DOT11_MODE_11A:
1041 ret_val = QCA_WLAN_802_11_MODE_11A;
1042 break;
1043 case eCSR_CFG_DOT11_MODE_11B:
1044 ret_val = QCA_WLAN_802_11_MODE_11B;
1045 break;
1046 case eCSR_CFG_DOT11_MODE_11G:
1047 ret_val = QCA_WLAN_802_11_MODE_11G;
1048 break;
1049 case eCSR_CFG_DOT11_MODE_11N:
1050 ret_val = QCA_WLAN_802_11_MODE_11N;
1051 break;
1052 case eCSR_CFG_DOT11_MODE_11AC:
1053 ret_val = QCA_WLAN_802_11_MODE_11AC;
1054 break;
1055 case eCSR_CFG_DOT11_MODE_AUTO:
1056 case eCSR_CFG_DOT11_MODE_ABG:
1057 default:
1058 ret_val = QCA_WLAN_802_11_MODE_INVALID;
1059 }
1060 return ret_val;
1061}
1062
1063/**
1064 * hdd_add_tx_bitrate() - add tx bitrate attribute
1065 * @skb: pointer to sk buff
1066 * @hdd_sta_ctx: pointer to hdd station context
1067 * @idx: attribute index
1068 *
1069 * Return: Success(0) or reason code for failure
1070 */
1071static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
1072 hdd_station_ctx_t *hdd_sta_ctx,
1073 int idx)
1074{
1075 struct nlattr *nla_attr;
1076 uint32_t bitrate, bitrate_compat;
1077
1078 nla_attr = nla_nest_start(skb, idx);
1079 if (!nla_attr)
1080 goto fail;
1081 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301082 bitrate = cfg80211_calculate_bitrate(
1083 &hdd_sta_ctx->cache_conn_info.txrate);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301084
1085 /* report 16-bit bitrate only if we can */
1086 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
1087 if (bitrate > 0 &&
1088 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
1089 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1090 goto fail;
1091 }
1092 if (bitrate_compat > 0 &&
1093 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
1094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1095 goto fail;
1096 }
1097 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301098 hdd_sta_ctx->cache_conn_info.txrate.nss)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1100 goto fail;
1101 }
1102 nla_nest_end(skb, nla_attr);
1103 return 0;
1104fail:
1105 return -EINVAL;
1106}
1107
1108/**
1109 * hdd_add_sta_info() - add station info attribute
1110 * @skb: pointer to sk buff
1111 * @hdd_sta_ctx: pointer to hdd station context
1112 * @idx: attribute index
1113 *
1114 * Return: Success(0) or reason code for failure
1115 */
1116static int32_t hdd_add_sta_info(struct sk_buff *skb,
1117 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1118{
1119 struct nlattr *nla_attr;
1120
1121 nla_attr = nla_nest_start(skb, idx);
1122 if (!nla_attr)
1123 goto fail;
1124 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301125 (hdd_sta_ctx->cache_conn_info.signal + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1127 goto fail;
1128 }
1129 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1130 goto fail;
1131 nla_nest_end(skb, nla_attr);
1132 return 0;
1133fail:
1134 return -EINVAL;
1135}
1136
1137/**
1138 * hdd_add_survey_info() - add survey info attribute
1139 * @skb: pointer to sk buff
1140 * @hdd_sta_ctx: pointer to hdd station context
1141 * @idx: attribute index
1142 *
1143 * Return: Success(0) or reason code for failure
1144 */
1145static int32_t hdd_add_survey_info(struct sk_buff *skb,
1146 hdd_station_ctx_t *hdd_sta_ctx,
1147 int idx)
1148{
1149 struct nlattr *nla_attr;
1150
1151 nla_attr = nla_nest_start(skb, idx);
1152 if (!nla_attr)
1153 goto fail;
1154 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301155 hdd_sta_ctx->cache_conn_info.freq) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301156 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301157 (hdd_sta_ctx->cache_conn_info.noise + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1159 goto fail;
1160 }
1161 nla_nest_end(skb, nla_attr);
1162 return 0;
1163fail:
1164 return -EINVAL;
1165}
1166
1167/**
1168 * hdd_add_link_standard_info() - add link info attribute
1169 * @skb: pointer to sk buff
1170 * @hdd_sta_ctx: pointer to hdd station context
1171 * @idx: attribute index
1172 *
1173 * Return: Success(0) or reason code for failure
1174 */
1175static int32_t
1176hdd_add_link_standard_info(struct sk_buff *skb,
1177 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1178{
1179 struct nlattr *nla_attr;
1180
1181 nla_attr = nla_nest_start(skb, idx);
1182 if (!nla_attr)
1183 goto fail;
1184 if (nla_put(skb,
1185 NL80211_ATTR_SSID,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301186 hdd_sta_ctx->cache_conn_info.SSID.SSID.length,
1187 hdd_sta_ctx->cache_conn_info.SSID.SSID.ssId)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1189 goto fail;
1190 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301191 if (nla_put(skb, NL80211_ATTR_MAC, VOS_MAC_ADDR_SIZE,
1192 hdd_sta_ctx->cache_conn_info.bssId))
1193 goto fail;
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301194 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1195 goto fail;
1196 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1197 goto fail;
1198 nla_nest_end(skb, nla_attr);
1199 return 0;
1200fail:
1201 return -EINVAL;
1202}
1203
1204/**
1205 * hdd_add_ap_standard_info() - add ap info attribute
1206 * @skb: pointer to sk buff
1207 * @hdd_sta_ctx: pointer to hdd station context
1208 * @idx: attribute index
1209 *
1210 * Return: Success(0) or reason code for failure
1211 */
1212static int32_t
1213hdd_add_ap_standard_info(struct sk_buff *skb,
1214 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1215{
1216 struct nlattr *nla_attr;
1217
1218 nla_attr = nla_nest_start(skb, idx);
1219 if (!nla_attr)
1220 goto fail;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301221 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301222 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301223 sizeof(hdd_sta_ctx->cache_conn_info.vht_caps),
1224 &hdd_sta_ctx->cache_conn_info.vht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1226 goto fail;
1227 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301228 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301229 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301230 sizeof(hdd_sta_ctx->cache_conn_info.ht_caps),
1231 &hdd_sta_ctx->cache_conn_info.ht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1233 goto fail;
1234 }
1235 nla_nest_end(skb, nla_attr);
1236 return 0;
1237fail:
1238 return -EINVAL;
1239}
1240
1241/**
1242 * hdd_get_station_info() - send BSS information to supplicant
1243 * @hdd_ctx: pointer to hdd context
1244 * @adapter: pointer to adapter
1245 *
1246 * Return: 0 if success else error status
1247 */
1248static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1249 hdd_adapter_t *adapter)
1250{
1251 struct sk_buff *skb = NULL;
1252 uint8_t *tmp_hs20 = NULL;
1253 uint32_t nl_buf_len;
1254 hdd_station_ctx_t *hdd_sta_ctx;
1255
1256 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1257
1258 nl_buf_len = NLMSG_HDRLEN;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301259
1260 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.SSID.SSID.length) +
1261 VOS_MAC_ADDR_SIZE +
1262 sizeof(hdd_sta_ctx->cache_conn_info.freq) +
1263 sizeof(hdd_sta_ctx->cache_conn_info.noise) +
1264 sizeof(hdd_sta_ctx->cache_conn_info.signal) +
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301265 (sizeof(uint32_t) * 2) +
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301266 sizeof(hdd_sta_ctx->cache_conn_info.txrate.nss) +
1267 sizeof(hdd_sta_ctx->cache_conn_info.roam_count) +
1268 sizeof(hdd_sta_ctx->cache_conn_info.authType) +
1269 sizeof(hdd_sta_ctx->cache_conn_info.dot11Mode);
1270 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
1271 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.vht_caps);
1272 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
1273 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_caps);
1274 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) {
1275 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->
1276 cache_conn_info.hs20vendor_ie);
1277 nl_buf_len +=
1278 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie) -
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301279 1);
1280 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301281 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
1282 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_operation);
1283 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
1284 nl_buf_len +=
1285 sizeof(hdd_sta_ctx->cache_conn_info.vht_operation);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301286
1287
1288 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1289 if (!skb) {
1290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1291 __func__, __LINE__);
1292 return -ENOMEM;
1293 }
1294
1295 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1296 LINK_INFO_STANDARD_NL80211_ATTR)) {
1297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1298 goto fail;
1299 }
1300 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1301 AP_INFO_STANDARD_NL80211_ATTR)) {
1302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1303 goto fail;
1304 }
1305 if (nla_put_u32(skb, INFO_ROAM_COUNT,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301306 hdd_sta_ctx->cache_conn_info.roam_count) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301307 nla_put_u32(skb, INFO_AKM,
1308 hdd_convert_auth_type(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301309 hdd_sta_ctx->cache_conn_info.authType)) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301310 nla_put_u32(skb, WLAN802_11_MODE,
1311 hdd_convert_dot11mode(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301312 hdd_sta_ctx->cache_conn_info.dot11Mode))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1314 goto fail;
1315 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301316 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301317 if (nla_put(skb, HT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301318 (sizeof(hdd_sta_ctx->cache_conn_info.ht_operation)),
1319 &hdd_sta_ctx->cache_conn_info.ht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1321 goto fail;
1322 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301323 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301324 if (nla_put(skb, VHT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301325 (sizeof(hdd_sta_ctx->
1326 cache_conn_info.vht_operation)),
1327 &hdd_sta_ctx->cache_conn_info.vht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1329 goto fail;
1330 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301331 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301332 if (nla_put(skb, AP_INFO_HS20_INDICATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301333 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie)
1334 - 1), tmp_hs20 + 1)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1336 goto fail;
1337 }
1338
1339 return cfg80211_vendor_cmd_reply(skb);
1340fail:
1341 if (skb)
1342 kfree_skb(skb);
1343 return -EINVAL;
1344}
1345
1346/**
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301347 * hdd_add_survey_info_sap_get_len - get data length used in
1348 * hdd_add_survey_info_sap()
1349 *
1350 * This function calculates the data length used in hdd_add_survey_info_sap()
1351 *
1352 * Return: total data length used in hdd_add_survey_info_sap()
1353 */
1354static uint32_t hdd_add_survey_info_sap_get_len(void)
1355{
1356 return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
1357}
1358
1359/**
1360 * hdd_add_survey_info - add survey info attribute
1361 * @skb: pointer to response skb buffer
1362 * @stainfo: station information
1363 * @idx: attribute type index for nla_next_start()
1364 *
1365 * This function adds survey info attribute to response skb buffer
1366 *
1367 * Return : 0 on success and errno on failure
1368 */
1369static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
1370 struct hdd_cache_sta_info *stainfo,
1371 int idx)
1372{
1373 struct nlattr *nla_attr;
1374
1375 nla_attr = nla_nest_start(skb, idx);
1376 if (!nla_attr)
1377 goto fail;
1378 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1379 stainfo->freq)) {
1380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1381 FL("put fail"));
1382 goto fail;
1383 }
1384 nla_nest_end(skb, nla_attr);
1385 return 0;
1386fail:
1387 return -EINVAL;
1388}
1389
1390/**
1391 * hdd_add_tx_bitrate_sap_get_len - get data length used in
1392 * hdd_add_tx_bitrate_sap()
1393 *
1394 * This function calculates the data length used in hdd_add_tx_bitrate_sap()
1395 *
1396 * Return: total data length used in hdd_add_tx_bitrate_sap()
1397 */
1398static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
1399{
1400 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
1401}
1402
1403/**
1404 * hdd_add_tx_bitrate_sap - add vht nss info attribute
1405 * @skb: pointer to response skb buffer
1406 * @stainfo: station information
1407 * @idx: attribute type index for nla_next_start()
1408 *
1409 * This function adds vht nss attribute to response skb buffer
1410 *
1411 * Return : 0 on success and errno on failure
1412 */
1413static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
1414 struct hdd_cache_sta_info *stainfo,
1415 int idx)
1416{
1417 struct nlattr *nla_attr;
1418
1419 nla_attr = nla_nest_start(skb, idx);
1420 if (!nla_attr)
1421 goto fail;
1422
1423 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1424 stainfo->nss)) {
1425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1426 FL("put fail"));
1427 goto fail;
1428 }
1429 nla_nest_end(skb, nla_attr);
1430 return 0;
1431fail:
1432 return -EINVAL;
1433}
1434
1435/**
1436 * hdd_add_sta_info_sap_get_len - get data length used in
1437 * hdd_add_sta_info_sap()
1438 *
1439 * This function calculates the data length used in hdd_add_sta_info_sap()
1440 *
1441 * Return: total data length used in hdd_add_sta_info_sap()
1442 */
1443static uint32_t hdd_add_sta_info_sap_get_len(void)
1444{
1445 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
1446 hdd_add_tx_bitrate_sap_get_len());
1447}
1448
1449/**
1450 * hdd_add_sta_info_sap - add sta signal info attribute
1451 * @skb: pointer to response skb buffer
1452 * @rssi: peer rssi value
1453 * @stainfo: station information
1454 * @idx: attribute type index for nla_next_start()
1455 *
1456 * This function adds sta signal attribute to response skb buffer
1457 *
1458 * Return : 0 on success and errno on failure
1459 */
1460static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
1461 struct hdd_cache_sta_info *stainfo, int idx)
1462{
1463 struct nlattr *nla_attr;
1464
1465 nla_attr = nla_nest_start(skb, idx);
1466 if (!nla_attr)
1467 goto fail;
1468
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05301469 /* upperlayer expects positive rssi value */
1470 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, (rssi + 96))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1472 FL("put fail"));
1473 goto fail;
1474 }
1475 if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE)) {
1476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1477 FL("put fail"));
1478 goto fail;
1479 }
1480
1481 nla_nest_end(skb, nla_attr);
1482 return 0;
1483fail:
1484 return -EINVAL;
1485}
1486
1487/**
1488 * hdd_add_link_standard_info_sap_get_len - get data length used in
1489 * hdd_add_link_standard_info_sap()
1490 *
1491 * This function calculates the data length used in
1492 * hdd_add_link_standard_info_sap()
1493 *
1494 * Return: total data length used in hdd_add_link_standard_info_sap()
1495 */
1496static uint32_t hdd_add_link_standard_info_sap_get_len(void)
1497{
1498 return ((NLA_HDRLEN) +
1499 hdd_add_survey_info_sap_get_len() +
1500 hdd_add_sta_info_sap_get_len() +
1501 (sizeof(uint32_t) + NLA_HDRLEN));
1502}
1503
1504/**
1505 * hdd_add_link_standard_info_sap - add add link info attribut
1506 * @skb: pointer to response skb buffer
1507 * @stainfo: station information
1508 * @idx: attribute type index for nla_next_start()
1509 *
1510 * This function adds link info attribut to response skb buffer
1511 *
1512 * Return : 0 on success and errno on failure
1513 */
1514static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
1515 struct hdd_cache_sta_info *stainfo,
1516 int idx)
1517{
1518 struct nlattr *nla_attr;
1519
1520 nla_attr = nla_nest_start(skb, idx);
1521 if (!nla_attr)
1522 goto fail;
1523 if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
1524 goto fail;
1525 if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
1526 goto fail;
1527
1528 if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
1529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1530 FL("put fail"));
1531 goto fail;
1532 }
1533
1534 nla_nest_end(skb, nla_attr);
1535 return 0;
1536fail:
1537 return -EINVAL;
1538}
1539
1540/**
1541 * hdd_add_ap_standard_info_sap_get_len - get data length used in
1542 * hdd_add_ap_standard_info_sap()
1543 * @stainfo: station information
1544 *
1545 * This function calculates the data length used in
1546 * hdd_add_ap_standard_info_sap()
1547 *
1548 * Return: total data length used in hdd_add_ap_standard_info_sap()
1549 */
1550static uint32_t hdd_add_ap_standard_info_sap_get_len(
1551 struct hdd_cache_sta_info *stainfo)
1552{
1553 uint32_t len;
1554
1555 len = NLA_HDRLEN;
1556 if (stainfo->vht_present)
1557 len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
1558 if (stainfo->ht_present)
1559 len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
1560
1561 return len;
1562}
1563
1564/**
1565 * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
1566 * @skb: pointer to response skb buffer
1567 * @stainfo: station information
1568 * @idx: attribute type index for nla_next_start()
1569 *
1570 * This function adds HT and VHT info attributes to response skb buffer
1571 *
1572 * Return : 0 on success and errno on failure
1573 */
1574static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
1575 struct hdd_cache_sta_info *stainfo,
1576 int idx)
1577{
1578 struct nlattr *nla_attr;
1579
1580 nla_attr = nla_nest_start(skb, idx);
1581 if (!nla_attr)
1582 goto fail;
1583
1584 if (stainfo->vht_present) {
1585 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1586 sizeof(stainfo->vht_caps),
1587 &stainfo->vht_caps)) {
1588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1589 FL("put fail"));
1590 goto fail;
1591 }
1592 }
1593 if (stainfo->ht_present) {
1594 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1595 sizeof(stainfo->ht_caps),
1596 &stainfo->ht_caps)) {
1597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1598 FL("put fail"));
1599 goto fail;
1600 }
1601 }
1602 nla_nest_end(skb, nla_attr);
1603 return 0;
1604fail:
1605 return -EINVAL;
1606}
1607
1608/**
1609 * hdd_decode_ch_width - decode channel band width based
1610 * @ch_width: encoded enum value holding channel band width
1611 *
1612 * This function decodes channel band width from the given encoded enum value.
1613 *
1614 * Returns: decoded channel band width.
1615 */
1616static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
1617{
1618 switch (ch_width) {
1619 case 0:
1620 return 20;
1621 case 1:
1622 return 40;
1623 case 2:
1624 return 80;
1625 default:
1626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1627 "invalid enum: %d", ch_width);
1628 return 20;
1629 }
1630}
1631
1632/**
1633 * hdd_get_cached_station_remote() - get cached(deleted) peer's info
1634 * @hdd_ctx: hdd context
1635 * @adapter: hostapd interface
1636 * @mac_addr: mac address of requested peer
1637 *
1638 * This function collect and indicate the cached(deleted) peer's info
1639 *
1640 * Return: 0 on success, otherwise error value
1641 */
1642static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx,
1643 hdd_adapter_t *adapter,
1644 v_MACADDR_t mac_addr)
1645{
1646 struct hdd_cache_sta_info *stainfo;
1647 struct sk_buff *skb = NULL;
1648 uint32_t nl_buf_len;
1649 uint8_t cw;
1650 ptSapContext sap_ctx;
1651 v_CONTEXT_t vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
1652
1653 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
1654 if(sap_ctx == NULL){
1655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1656 FL("psapCtx is NULL"));
1657 return -ENOENT;
1658 }
1659
1660 stainfo = hdd_get_cache_stainfo(sap_ctx->cache_sta_info,
1661 mac_addr.bytes);
1662 if (!stainfo) {
1663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1664 "peer " MAC_ADDRESS_STR " not found",
1665 MAC_ADDR_ARRAY(mac_addr.bytes));
1666 return -EINVAL;
1667 }
1668 if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE) {
1669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1670 "peer " MAC_ADDRESS_STR " is in connected state",
1671 MAC_ADDR_ARRAY(mac_addr.bytes));
1672 return -EINVAL;
1673 }
1674
1675
1676 nl_buf_len = NLMSG_HDRLEN + hdd_add_link_standard_info_sap_get_len() +
1677 hdd_add_ap_standard_info_sap_get_len(stainfo) +
1678 (sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
1679 (sizeof(cw) + NLA_HDRLEN) +
1680 (sizeof(stainfo->rx_rate) + NLA_HDRLEN);
1681
1682 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1683 if (!skb) {
1684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "cfg80211_vendor_cmd_alloc_reply_skb failed");
1685 return -ENOMEM;
1686 }
1687
1688 if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
1689 LINK_INFO_STANDARD_NL80211_ATTR)) {
1690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "link standard put fail");
1691 goto fail;
1692 }
1693
1694 if (hdd_add_ap_standard_info_sap(skb, stainfo,
1695 AP_INFO_STANDARD_NL80211_ATTR)) {
1696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ap standard put fail");
1697 goto fail;
1698 }
1699
1700 /* upper layer expects decoded channel BW */
1701 cw = hdd_decode_ch_width(stainfo->ch_width);
1702 if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE, stainfo->dot11_mode) ||
1703 nla_put_u8(skb, REMOTE_CH_WIDTH, cw)) {
1704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "remote ch put fail");
1705 goto fail;
1706 }
Hanumanth Reddy Pothula504fe152018-01-02 20:41:03 +05301707 if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, (stainfo->rx_rate * 100))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "rx rate put fail");
1709 goto fail;
1710 }
1711
1712 vos_mem_zero(stainfo, sizeof(*stainfo));
1713
1714 return cfg80211_vendor_cmd_reply(skb);
1715fail:
1716 if (skb)
1717 kfree_skb(skb);
1718
1719 return -EINVAL;
1720}
1721
1722/**
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301723 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1724 * @wiphy: corestack handler
1725 * @wdev: wireless device
1726 * @data: data
1727 * @data_len: data length
1728 *
1729 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1730 * Validate cmd attributes and send the station info to upper layers.
1731 *
1732 * Return: Success(0) or reason code for failure
1733 */
1734static int32_t
1735__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1736 struct wireless_dev *wdev,
1737 const void *data,
1738 int data_len)
1739{
1740 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1741 struct net_device *dev = wdev->netdev;
1742 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1743 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1744 int32_t status;
1745
1746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1747 if (VOS_FTM_MODE == hdd_get_conparam()) {
1748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1749 status = -EPERM;
1750 goto out;
1751 }
1752
1753 status = wlan_hdd_validate_context(hdd_ctx);
1754 if (0 != status)
1755 goto out;
1756
1757
1758 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1759 data, data_len, NULL);
1760 if (status) {
1761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1762 goto out;
1763 }
1764
1765 /* Parse and fetch Command Type*/
1766 if (tb[STATION_INFO]) {
1767 status = hdd_get_station_info(hdd_ctx, adapter);
1768 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1769 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301770 } else if (tb[STATION_REMOTE]) {
1771 v_MACADDR_t mac_addr;
1772
1773 if (adapter->device_mode != WLAN_HDD_SOFTAP &&
1774 adapter->device_mode != WLAN_HDD_P2P_GO) {
1775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"invalid device_mode:%d",
1776 adapter->device_mode);
1777 status = -EINVAL;
1778 goto out;
1779 }
1780
1781 nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
1782 VOS_MAC_ADDRESS_LEN);
1783
1784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "STATION_REMOTE "MAC_ADDRESS_STR"",
1785 MAC_ADDR_ARRAY(mac_addr.bytes));
1786
1787 status = hdd_get_cached_station_remote(hdd_ctx, adapter,
1788 mac_addr);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301789 } else {
1790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1791 status = -EINVAL;
1792 goto out;
1793 }
1794 EXIT();
1795out:
1796 return status;
1797}
1798
1799/**
1800 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1801 * @wiphy: corestack handler
1802 * @wdev: wireless device
1803 * @data: data
1804 * @data_len: data length
1805 *
1806 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1807 * Validate cmd attributes and send the station info to upper layers.
1808 *
1809 * Return: Success(0) or reason code for failure
1810 */
1811static int32_t
1812hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1813 struct wireless_dev *wdev,
1814 const void *data,
1815 int data_len)
1816{
1817 int ret;
1818
1819 vos_ssr_protect(__func__);
1820 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1821 vos_ssr_unprotect(__func__);
1822
1823 return ret;
1824}
1825
1826/*
1827 * undef short names defined for get station command
1828 * used by __wlan_hdd_cfg80211_get_station_cmd()
1829 */
1830#undef STATION_INVALID
1831#undef STATION_INFO
1832#undef STATION_ASSOC_FAIL_REASON
1833#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301834
Sunil Duttc69bccb2014-05-26 21:30:20 +05301835#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1836
1837static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1838 struct sk_buff *vendor_event)
1839{
1840 if (nla_put_u8(vendor_event,
1841 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1842 stats->rate.preamble) ||
1843 nla_put_u8(vendor_event,
1844 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1845 stats->rate.nss) ||
1846 nla_put_u8(vendor_event,
1847 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1848 stats->rate.bw) ||
1849 nla_put_u8(vendor_event,
1850 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1851 stats->rate.rateMcsIdx) ||
1852 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1853 stats->rate.bitrate ) ||
1854 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1855 stats->txMpdu ) ||
1856 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1857 stats->rxMpdu ) ||
1858 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1859 stats->mpduLost ) ||
1860 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1861 stats->retries) ||
1862 nla_put_u32(vendor_event,
1863 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1864 stats->retriesShort ) ||
1865 nla_put_u32(vendor_event,
1866 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1867 stats->retriesLong))
1868 {
1869 hddLog(VOS_TRACE_LEVEL_ERROR,
1870 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1871 return FALSE;
1872 }
1873 return TRUE;
1874}
1875
1876static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1877 struct sk_buff *vendor_event)
1878{
1879 u32 i = 0;
1880 struct nlattr *rateInfo;
1881 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1882 stats->type) ||
1883 nla_put(vendor_event,
1884 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1885 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1886 nla_put_u32(vendor_event,
1887 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1888 stats->capabilities) ||
1889 nla_put_u32(vendor_event,
1890 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1891 stats->numRate))
1892 {
1893 hddLog(VOS_TRACE_LEVEL_ERROR,
1894 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1895 goto error;
1896 }
1897
1898 rateInfo = nla_nest_start(vendor_event,
1899 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301900 if(!rateInfo)
1901 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301902 for (i = 0; i < stats->numRate; i++)
1903 {
1904 struct nlattr *rates;
1905 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1906 stats->rateStats +
1907 (i * sizeof(tSirWifiRateStat)));
1908 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301909 if(!rates)
1910 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301911
1912 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1913 {
1914 hddLog(VOS_TRACE_LEVEL_ERROR,
1915 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1916 return FALSE;
1917 }
1918 nla_nest_end(vendor_event, rates);
1919 }
1920 nla_nest_end(vendor_event, rateInfo);
1921
1922 return TRUE;
1923error:
1924 return FALSE;
1925}
1926
1927static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1928 struct sk_buff *vendor_event)
1929{
1930 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1931 stats->ac ) ||
1932 nla_put_u32(vendor_event,
1933 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1934 stats->txMpdu ) ||
1935 nla_put_u32(vendor_event,
1936 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1937 stats->rxMpdu ) ||
1938 nla_put_u32(vendor_event,
1939 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1940 stats->txMcast ) ||
1941 nla_put_u32(vendor_event,
1942 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1943 stats->rxMcast ) ||
1944 nla_put_u32(vendor_event,
1945 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1946 stats->rxAmpdu ) ||
1947 nla_put_u32(vendor_event,
1948 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1949 stats->txAmpdu ) ||
1950 nla_put_u32(vendor_event,
1951 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1952 stats->mpduLost )||
1953 nla_put_u32(vendor_event,
1954 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1955 stats->retries ) ||
1956 nla_put_u32(vendor_event,
1957 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1958 stats->retriesShort ) ||
1959 nla_put_u32(vendor_event,
1960 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1961 stats->retriesLong ) ||
1962 nla_put_u32(vendor_event,
1963 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1964 stats->contentionTimeMin ) ||
1965 nla_put_u32(vendor_event,
1966 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1967 stats->contentionTimeMax ) ||
1968 nla_put_u32(vendor_event,
1969 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1970 stats->contentionTimeAvg ) ||
1971 nla_put_u32(vendor_event,
1972 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1973 stats->contentionNumSamples ))
1974 {
1975 hddLog(VOS_TRACE_LEVEL_ERROR,
1976 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1977 return FALSE;
1978 }
1979 return TRUE;
1980}
1981
1982static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1983 struct sk_buff *vendor_event)
1984{
Dino Myclec8f3f332014-07-21 16:48:27 +05301985 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301986 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1987 nla_put(vendor_event,
1988 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
1989 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
1990 nla_put_u32(vendor_event,
1991 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
1992 stats->state ) ||
1993 nla_put_u32(vendor_event,
1994 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
1995 stats->roaming ) ||
1996 nla_put_u32(vendor_event,
1997 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
1998 stats->capabilities ) ||
1999 nla_put(vendor_event,
2000 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
2001 strlen(stats->ssid), stats->ssid) ||
2002 nla_put(vendor_event,
2003 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
2004 WNI_CFG_BSSID_LEN, stats->bssid) ||
2005 nla_put(vendor_event,
2006 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
2007 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
2008 nla_put(vendor_event,
2009 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
2010 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
2011 )
2012 {
2013 hddLog(VOS_TRACE_LEVEL_ERROR,
2014 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2015 return FALSE;
2016 }
2017 return TRUE;
2018}
2019
Dino Mycle3b9536d2014-07-09 22:05:24 +05302020static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
2021 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302022 struct sk_buff *vendor_event)
2023{
2024 int i = 0;
2025 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302026 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2027 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302028 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302029
Sunil Duttc69bccb2014-05-26 21:30:20 +05302030 if (FALSE == put_wifi_interface_info(
2031 &pWifiIfaceStat->info,
2032 vendor_event))
2033 {
2034 hddLog(VOS_TRACE_LEVEL_ERROR,
2035 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2036 return FALSE;
2037
2038 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05302039 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
2040 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
2041 if (NULL == pWifiIfaceStatTL)
2042 {
2043 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2044 return FALSE;
2045 }
2046
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302047 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
2048 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
2049 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
2050 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
2051
2052 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
2053 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
2054 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
2055 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302056
2057 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
2058 {
2059 if (VOS_STATUS_SUCCESS ==
2060 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2061 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
2062 {
2063 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
2064 * obtained from TL structure
2065 */
2066
2067 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
2068 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302069 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
2070
Srinivas Dasari98947432014-11-07 19:41:24 +05302071 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
2072 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
2073 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
2074 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
2075 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
2076 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
2077 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
2078 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302079
Srinivas Dasari98947432014-11-07 19:41:24 +05302080 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
2081 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
2082 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
2083 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
2084 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
2085 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
2086 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
2087 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302088
Srinivas Dasari98947432014-11-07 19:41:24 +05302089 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
2090 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
2091 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
2092 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
2093 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
2094 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
2095 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
2096 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302097 }
2098 else
2099 {
2100 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
2101 }
2102
Dino Mycle3b9536d2014-07-09 22:05:24 +05302103 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
2104 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
2105 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
2106 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
2107 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
2108 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
2109 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
2110 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
2111 }
2112 else
2113 {
2114 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
2115 }
2116
2117
Sunil Duttc69bccb2014-05-26 21:30:20 +05302118
2119 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302120 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2121 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
2122 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302123 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
2124 pWifiIfaceStat->beaconRx) ||
2125 nla_put_u32(vendor_event,
2126 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
2127 pWifiIfaceStat->mgmtRx) ||
2128 nla_put_u32(vendor_event,
2129 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
2130 pWifiIfaceStat->mgmtActionRx) ||
2131 nla_put_u32(vendor_event,
2132 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
2133 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302134 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302135 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
2136 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302137 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302138 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
2139 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302140 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302141 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
2142 pWifiIfaceStat->rssiAck))
2143 {
2144 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302145 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2146 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302147 return FALSE;
2148 }
2149
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302150#ifdef FEATURE_EXT_LL_STAT
2151 /*
2152 * Ensure when EXT_LL_STAT is supported by both host and fwr,
2153 * then host should send Leaky AP stats to upper layer,
2154 * otherwise no need to send these stats.
2155 */
2156 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
2157 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
2158 )
2159 {
2160 hddLog(VOS_TRACE_LEVEL_INFO,
2161 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
2162 pWifiIfaceStat->leakyApStat.is_leaky_ap,
2163 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
2164 pWifiIfaceStat->leakyApStat.rx_leak_window,
2165 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
2166 if (nla_put_u32(vendor_event,
2167 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
2168 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
2169 nla_put_u32(vendor_event,
2170 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
2171 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
2172 nla_put_u32(vendor_event,
2173 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
2174 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05302175 hdd_wlan_nla_put_u64(vendor_event,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302176 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
2177 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
2178 {
2179 hddLog(VOS_TRACE_LEVEL_ERROR,
2180 FL("EXT_LL_STAT put fail"));
2181 vos_mem_free(pWifiIfaceStatTL);
2182 return FALSE;
2183 }
2184 }
2185#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05302186 wmmInfo = nla_nest_start(vendor_event,
2187 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302188 if(!wmmInfo)
2189 {
2190 vos_mem_free(pWifiIfaceStatTL);
2191 return FALSE;
2192 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302193 for (i = 0; i < WIFI_AC_MAX; i++)
2194 {
2195 struct nlattr *wmmStats;
2196 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302197 if(!wmmStats)
2198 {
2199 vos_mem_free(pWifiIfaceStatTL);
2200 return FALSE;
2201 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302202 if (FALSE == put_wifi_wmm_ac_stat(
2203 &pWifiIfaceStat->AccessclassStats[i],
2204 vendor_event))
2205 {
2206 hddLog(VOS_TRACE_LEVEL_ERROR,
2207 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05302208 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302209 return FALSE;
2210 }
2211
2212 nla_nest_end(vendor_event, wmmStats);
2213 }
2214 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05302215 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302216 return TRUE;
2217}
2218
2219static tSirWifiInterfaceMode
2220 hdd_map_device_to_ll_iface_mode ( int deviceMode )
2221{
2222 switch (deviceMode)
2223 {
2224 case WLAN_HDD_INFRA_STATION:
2225 return WIFI_INTERFACE_STA;
2226 case WLAN_HDD_SOFTAP:
2227 return WIFI_INTERFACE_SOFTAP;
2228 case WLAN_HDD_P2P_CLIENT:
2229 return WIFI_INTERFACE_P2P_CLIENT;
2230 case WLAN_HDD_P2P_GO:
2231 return WIFI_INTERFACE_P2P_GO;
2232 case WLAN_HDD_IBSS:
2233 return WIFI_INTERFACE_IBSS;
2234 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05302235 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302236 }
2237}
2238
2239static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
2240 tpSirWifiInterfaceInfo pInfo)
2241{
2242 v_U8_t *staMac = NULL;
2243 hdd_station_ctx_t *pHddStaCtx;
2244 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2245 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
2246
2247 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
2248
2249 vos_mem_copy(pInfo->macAddr,
2250 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
2251
2252 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2253 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
2254 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
2255 {
2256 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2257 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
2258 {
2259 pInfo->state = WIFI_DISCONNECTED;
2260 }
2261 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
2262 {
2263 hddLog(VOS_TRACE_LEVEL_ERROR,
2264 "%s: Session ID %d, Connection is in progress", __func__,
2265 pAdapter->sessionId);
2266 pInfo->state = WIFI_ASSOCIATING;
2267 }
2268 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
2269 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
2270 {
2271 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
2272 hddLog(VOS_TRACE_LEVEL_ERROR,
2273 "%s: client " MAC_ADDRESS_STR
2274 " is in the middle of WPS/EAPOL exchange.", __func__,
2275 MAC_ADDR_ARRAY(staMac));
2276 pInfo->state = WIFI_AUTHENTICATING;
2277 }
2278 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
2279 {
2280 pInfo->state = WIFI_ASSOCIATED;
2281 vos_mem_copy(pInfo->bssid,
2282 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
2283 vos_mem_copy(pInfo->ssid,
2284 pHddStaCtx->conn_info.SSID.SSID.ssId,
2285 pHddStaCtx->conn_info.SSID.SSID.length);
2286 //NULL Terminate the string.
2287 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
2288 }
2289 }
2290 vos_mem_copy(pInfo->countryStr,
2291 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2292
2293 vos_mem_copy(pInfo->apCountryStr,
2294 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2295
2296 return TRUE;
2297}
2298
2299/*
2300 * hdd_link_layer_process_peer_stats () - This function is called after
2301 * receiving Link Layer Peer statistics from FW.This function converts
2302 * the firmware data to the NL data and sends the same to the kernel/upper
2303 * layers.
2304 */
2305static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
2306 v_VOID_t *pData)
2307{
2308 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302309 tpSirWifiPeerStat pWifiPeerStat;
2310 tpSirWifiPeerInfo pWifiPeerInfo;
2311 struct nlattr *peerInfo;
2312 struct sk_buff *vendor_event;
2313 int status, i;
2314
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302315 ENTER();
2316
Sunil Duttc69bccb2014-05-26 21:30:20 +05302317 status = wlan_hdd_validate_context(pHddCtx);
2318 if (0 != status)
2319 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302320 return;
2321 }
2322
2323 pWifiPeerStat = (tpSirWifiPeerStat) pData;
2324
2325 hddLog(VOS_TRACE_LEVEL_INFO,
2326 "LL_STATS_PEER_ALL : numPeers %u",
2327 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302328 /*
2329 * Allocate a size of 4096 for the peer stats comprising
2330 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
2331 * sizeof (tSirWifiRateStat).Each field is put with an
2332 * NL attribute.The size of 4096 is considered assuming
2333 * that number of rates shall not exceed beyond 50 with
2334 * the sizeof (tSirWifiRateStat) being 32.
2335 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302336 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2337 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302338 if (!vendor_event)
2339 {
2340 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302341 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05302342 __func__);
2343 return;
2344 }
2345 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302346 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2347 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
2348 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302349 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
2350 pWifiPeerStat->numPeers))
2351 {
2352 hddLog(VOS_TRACE_LEVEL_ERROR,
2353 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
2354 kfree_skb(vendor_event);
2355 return;
2356 }
2357
2358 peerInfo = nla_nest_start(vendor_event,
2359 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302360 if(!peerInfo)
2361 {
2362 hddLog(VOS_TRACE_LEVEL_ERROR,
2363 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
2364 __func__);
2365 kfree_skb(vendor_event);
2366 return;
2367 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302368
2369 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2370 pWifiPeerStat->peerInfo);
2371
2372 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
2373 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302374 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302375 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302376
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302377 if(!peers)
2378 {
2379 hddLog(VOS_TRACE_LEVEL_ERROR,
2380 "%s: peer stats put fail",
2381 __func__);
2382 kfree_skb(vendor_event);
2383 return;
2384 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302385 if (FALSE == put_wifi_peer_info(
2386 pWifiPeerInfo, vendor_event))
2387 {
2388 hddLog(VOS_TRACE_LEVEL_ERROR,
2389 "%s: put_wifi_peer_info put fail", __func__);
2390 kfree_skb(vendor_event);
2391 return;
2392 }
2393
2394 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2395 pWifiPeerStat->peerInfo +
2396 (i * sizeof(tSirWifiPeerInfo)) +
2397 (numRate * sizeof (tSirWifiRateStat)));
2398 nla_nest_end(vendor_event, peers);
2399 }
2400 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302401 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302402 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302403}
2404
2405/*
2406 * hdd_link_layer_process_iface_stats () - This function is called after
2407 * receiving Link Layer Interface statistics from FW.This function converts
2408 * the firmware data to the NL data and sends the same to the kernel/upper
2409 * layers.
2410 */
2411static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
2412 v_VOID_t *pData)
2413{
2414 tpSirWifiIfaceStat pWifiIfaceStat;
2415 struct sk_buff *vendor_event;
2416 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2417 int status;
2418
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302419 ENTER();
2420
Sunil Duttc69bccb2014-05-26 21:30:20 +05302421 status = wlan_hdd_validate_context(pHddCtx);
2422 if (0 != status)
2423 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302424 return;
2425 }
2426 /*
2427 * Allocate a size of 4096 for the interface stats comprising
2428 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
2429 * assuming that all these fit with in the limit.Please take
2430 * a call on the limit based on the data requirements on
2431 * interface statistics.
2432 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302433 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2434 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302435 if (!vendor_event)
2436 {
2437 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302438 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302439 return;
2440 }
2441
2442 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
2443
Dino Mycle3b9536d2014-07-09 22:05:24 +05302444
2445 if (FALSE == hdd_get_interface_info( pAdapter,
2446 &pWifiIfaceStat->info))
2447 {
2448 hddLog(VOS_TRACE_LEVEL_ERROR,
2449 FL("hdd_get_interface_info get fail") );
2450 kfree_skb(vendor_event);
2451 return;
2452 }
2453
2454 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
2455 vendor_event))
2456 {
2457 hddLog(VOS_TRACE_LEVEL_ERROR,
2458 FL("put_wifi_iface_stats fail") );
2459 kfree_skb(vendor_event);
2460 return;
2461 }
2462
Sunil Duttc69bccb2014-05-26 21:30:20 +05302463 hddLog(VOS_TRACE_LEVEL_INFO,
2464 "WMI_LINK_STATS_IFACE Data");
2465
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302466 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302467
2468 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302469}
2470
2471/*
2472 * hdd_link_layer_process_radio_stats () - This function is called after
2473 * receiving Link Layer Radio statistics from FW.This function converts
2474 * the firmware data to the NL data and sends the same to the kernel/upper
2475 * layers.
2476 */
2477static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
2478 v_VOID_t *pData)
2479{
2480 int status, i;
2481 tpSirWifiRadioStat pWifiRadioStat;
2482 tpSirWifiChannelStats pWifiChannelStats;
2483 struct sk_buff *vendor_event;
2484 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2485 struct nlattr *chList;
2486
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302487 ENTER();
2488
Sunil Duttc69bccb2014-05-26 21:30:20 +05302489 status = wlan_hdd_validate_context(pHddCtx);
2490 if (0 != status)
2491 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302492 return;
2493 }
2494 pWifiRadioStat = (tpSirWifiRadioStat) pData;
2495
2496 hddLog(VOS_TRACE_LEVEL_INFO,
2497 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302498 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05302499 " radio is %d onTime is %u "
2500 " txTime is %u rxTime is %u "
2501 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05302502 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05302503 " onTimePnoScan is %u onTimeHs20 is %u "
2504 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302505 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302506 pWifiRadioStat->radio, pWifiRadioStat->onTime,
2507 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
2508 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302509 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302510 pWifiRadioStat->onTimeRoamScan,
2511 pWifiRadioStat->onTimePnoScan,
2512 pWifiRadioStat->onTimeHs20,
2513 pWifiRadioStat->numChannels);
2514 /*
2515 * Allocate a size of 4096 for the Radio stats comprising
2516 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
2517 * (tSirWifiChannelStats).Each channel data is put with an
2518 * NL attribute.The size of 4096 is considered assuming that
2519 * number of channels shall not exceed beyond 60 with the
2520 * sizeof (tSirWifiChannelStats) being 24 bytes.
2521 */
2522
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302523 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2524 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302525 if (!vendor_event)
2526 {
2527 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302528 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302529 return;
2530 }
2531
2532 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302533 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2534 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2535 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302536 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2537 pWifiRadioStat->radio) ||
2538 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302539 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2540 NUM_RADIOS) ||
2541 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302542 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2543 pWifiRadioStat->onTime) ||
2544 nla_put_u32(vendor_event,
2545 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2546 pWifiRadioStat->txTime) ||
2547 nla_put_u32(vendor_event,
2548 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2549 pWifiRadioStat->rxTime) ||
2550 nla_put_u32(vendor_event,
2551 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2552 pWifiRadioStat->onTimeScan) ||
2553 nla_put_u32(vendor_event,
2554 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2555 pWifiRadioStat->onTimeNbd) ||
2556 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302557 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2558 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302559 nla_put_u32(vendor_event,
2560 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2561 pWifiRadioStat->onTimeRoamScan) ||
2562 nla_put_u32(vendor_event,
2563 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2564 pWifiRadioStat->onTimePnoScan) ||
2565 nla_put_u32(vendor_event,
2566 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2567 pWifiRadioStat->onTimeHs20) ||
2568 nla_put_u32(vendor_event,
2569 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2570 pWifiRadioStat->numChannels))
2571 {
2572 hddLog(VOS_TRACE_LEVEL_ERROR,
2573 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2574 kfree_skb(vendor_event);
2575 return ;
2576 }
2577
2578 chList = nla_nest_start(vendor_event,
2579 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302580 if(!chList)
2581 {
2582 hddLog(VOS_TRACE_LEVEL_ERROR,
2583 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2584 __func__);
2585 kfree_skb(vendor_event);
2586 return;
2587 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302588 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2589 {
2590 struct nlattr *chInfo;
2591
2592 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2593 pWifiRadioStat->channels +
2594 (i * sizeof(tSirWifiChannelStats)));
2595
Sunil Duttc69bccb2014-05-26 21:30:20 +05302596 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302597 if(!chInfo)
2598 {
2599 hddLog(VOS_TRACE_LEVEL_ERROR,
2600 "%s: failed to put chInfo",
2601 __func__);
2602 kfree_skb(vendor_event);
2603 return;
2604 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302605
2606 if (nla_put_u32(vendor_event,
2607 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2608 pWifiChannelStats->channel.width) ||
2609 nla_put_u32(vendor_event,
2610 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2611 pWifiChannelStats->channel.centerFreq) ||
2612 nla_put_u32(vendor_event,
2613 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2614 pWifiChannelStats->channel.centerFreq0) ||
2615 nla_put_u32(vendor_event,
2616 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2617 pWifiChannelStats->channel.centerFreq1) ||
2618 nla_put_u32(vendor_event,
2619 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2620 pWifiChannelStats->onTime) ||
2621 nla_put_u32(vendor_event,
2622 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2623 pWifiChannelStats->ccaBusyTime))
2624 {
2625 hddLog(VOS_TRACE_LEVEL_ERROR,
2626 FL("cfg80211_vendor_event_alloc failed") );
2627 kfree_skb(vendor_event);
2628 return ;
2629 }
2630 nla_nest_end(vendor_event, chInfo);
2631 }
2632 nla_nest_end(vendor_event, chList);
2633
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302634 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302635
2636 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302637 return;
2638}
2639
2640/*
2641 * hdd_link_layer_stats_ind_callback () - This function is called after
2642 * receiving Link Layer indications from FW.This callback converts the firmware
2643 * data to the NL data and send the same to the kernel/upper layers.
2644 */
2645static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2646 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302647 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302648{
Dino Mycled3d50022014-07-07 12:58:25 +05302649 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2650 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302651 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302652 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302653 int status;
2654
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302655 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302656
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302657 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302658 if (0 != status)
2659 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302660 return;
2661 }
2662
Dino Mycled3d50022014-07-07 12:58:25 +05302663 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2664 if (NULL == pAdapter)
2665 {
2666 hddLog(VOS_TRACE_LEVEL_ERROR,
2667 FL(" MAC address %pM does not exist with host"),
2668 macAddr);
2669 return;
2670 }
2671
Sunil Duttc69bccb2014-05-26 21:30:20 +05302672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302673 "%s: Interface: %s LLStats indType: %d", __func__,
2674 pAdapter->dev->name, indType);
2675
Sunil Duttc69bccb2014-05-26 21:30:20 +05302676 switch (indType)
2677 {
2678 case SIR_HAL_LL_STATS_RESULTS_RSP:
2679 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302680 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302681 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2682 "respId = %u, moreResultToFollow = %u",
2683 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2684 macAddr, linkLayerStatsResults->respId,
2685 linkLayerStatsResults->moreResultToFollow);
2686
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302687 spin_lock(&hdd_context_lock);
2688 context = &pHddCtx->ll_stats_context;
2689 /* validate response received from target */
2690 if ((context->request_id != linkLayerStatsResults->respId) ||
2691 !(context->request_bitmap & linkLayerStatsResults->paramId))
2692 {
2693 spin_unlock(&hdd_context_lock);
2694 hddLog(LOGE,
2695 FL("Error : Request id %d response id %d request bitmap 0x%x"
2696 "response bitmap 0x%x"),
2697 context->request_id, linkLayerStatsResults->respId,
2698 context->request_bitmap, linkLayerStatsResults->paramId);
2699 return;
2700 }
2701 spin_unlock(&hdd_context_lock);
2702
Sunil Duttc69bccb2014-05-26 21:30:20 +05302703 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2704 {
2705 hdd_link_layer_process_radio_stats(pAdapter,
2706 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302707 spin_lock(&hdd_context_lock);
2708 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2709 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302710 }
2711 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2712 {
2713 hdd_link_layer_process_iface_stats(pAdapter,
2714 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302715 spin_lock(&hdd_context_lock);
2716 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2717 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302718 }
2719 else if ( linkLayerStatsResults->paramId &
2720 WMI_LINK_STATS_ALL_PEER )
2721 {
2722 hdd_link_layer_process_peer_stats(pAdapter,
2723 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302724 spin_lock(&hdd_context_lock);
2725 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2726 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302727 } /* WMI_LINK_STATS_ALL_PEER */
2728 else
2729 {
2730 hddLog(VOS_TRACE_LEVEL_ERROR,
2731 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2732 }
2733
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302734 spin_lock(&hdd_context_lock);
2735 /* complete response event if all requests are completed */
2736 if (0 == context->request_bitmap)
2737 complete(&context->response_event);
2738 spin_unlock(&hdd_context_lock);
2739
Sunil Duttc69bccb2014-05-26 21:30:20 +05302740 break;
2741 }
2742 default:
2743 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2744 break;
2745 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302746
2747 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302748 return;
2749}
2750
2751const struct
2752nla_policy
2753qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2754{
2755 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2756 { .type = NLA_U32 },
2757 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2758 { .type = NLA_U32 },
2759};
2760
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302761static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2762 struct wireless_dev *wdev,
2763 const void *data,
2764 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302765{
2766 int status;
2767 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302768 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302769 struct net_device *dev = wdev->netdev;
2770 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2771 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2772
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302773 ENTER();
2774
Sunil Duttc69bccb2014-05-26 21:30:20 +05302775 status = wlan_hdd_validate_context(pHddCtx);
2776 if (0 != status)
2777 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302778 return -EINVAL;
2779 }
2780
2781 if (NULL == pAdapter)
2782 {
2783 hddLog(VOS_TRACE_LEVEL_ERROR,
2784 FL("HDD adapter is Null"));
2785 return -ENODEV;
2786 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302787 /* check the LLStats Capability */
2788 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2789 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2790 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302791 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302792 FL("Link Layer Statistics not supported by Firmware"));
2793 return -EINVAL;
2794 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302795
2796 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2797 (struct nlattr *)data,
2798 data_len, qca_wlan_vendor_ll_set_policy))
2799 {
2800 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2801 return -EINVAL;
2802 }
2803 if (!tb_vendor
2804 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2805 {
2806 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2807 return -EINVAL;
2808 }
2809 if (!tb_vendor[
2810 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2811 {
2812 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2813 return -EINVAL;
2814 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302815 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302816 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302817
Dino Mycledf0a5d92014-07-04 09:41:55 +05302818 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302819 nla_get_u32(
2820 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2821
Dino Mycledf0a5d92014-07-04 09:41:55 +05302822 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302823 nla_get_u32(
2824 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2825
Dino Mycled3d50022014-07-07 12:58:25 +05302826 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2827 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302828
2829
2830 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302831 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2832 "Statistics Gathering = %d ",
2833 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2834 linkLayerStatsSetReq.mpduSizeThreshold,
2835 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302836
2837 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2838 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302839 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302840 {
2841 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2842 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302843 return -EINVAL;
2844
2845 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302846
Sunil Duttc69bccb2014-05-26 21:30:20 +05302847 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302848 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302849 {
2850 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2851 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302852 return -EINVAL;
2853 }
2854
2855 pAdapter->isLinkLayerStatsSet = 1;
2856
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302857 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302858 return 0;
2859}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302860static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2861 struct wireless_dev *wdev,
2862 const void *data,
2863 int data_len)
2864{
2865 int ret = 0;
2866
2867 vos_ssr_protect(__func__);
2868 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2869 vos_ssr_unprotect(__func__);
2870
2871 return ret;
2872}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302873
2874const struct
2875nla_policy
2876qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2877{
2878 /* Unsigned 32bit value provided by the caller issuing the GET stats
2879 * command. When reporting
2880 * the stats results, the driver uses the same value to indicate
2881 * which GET request the results
2882 * correspond to.
2883 */
2884 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2885
2886 /* Unsigned 32bit value . bit mask to identify what statistics are
2887 requested for retrieval */
2888 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2889};
2890
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302891static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2892 struct wireless_dev *wdev,
2893 const void *data,
2894 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302895{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302896 unsigned long rc;
2897 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302898 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2899 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302900 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302901 struct net_device *dev = wdev->netdev;
2902 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302903 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302904 int status;
2905
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302906 ENTER();
2907
Sunil Duttc69bccb2014-05-26 21:30:20 +05302908 status = wlan_hdd_validate_context(pHddCtx);
2909 if (0 != status)
2910 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302911 return -EINVAL ;
2912 }
2913
2914 if (NULL == pAdapter)
2915 {
2916 hddLog(VOS_TRACE_LEVEL_FATAL,
2917 "%s: HDD adapter is Null", __func__);
2918 return -ENODEV;
2919 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302920
2921 if (pHddStaCtx == NULL)
2922 {
2923 hddLog(VOS_TRACE_LEVEL_FATAL,
2924 "%s: HddStaCtx is Null", __func__);
2925 return -ENODEV;
2926 }
2927
Dino Mycledf0a5d92014-07-04 09:41:55 +05302928 /* check the LLStats Capability */
2929 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2930 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2931 {
2932 hddLog(VOS_TRACE_LEVEL_ERROR,
2933 FL("Link Layer Statistics not supported by Firmware"));
2934 return -EINVAL;
2935 }
2936
Sunil Duttc69bccb2014-05-26 21:30:20 +05302937
2938 if (!pAdapter->isLinkLayerStatsSet)
2939 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302940 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302941 "%s: isLinkLayerStatsSet : %d",
2942 __func__, pAdapter->isLinkLayerStatsSet);
2943 return -EINVAL;
2944 }
2945
Mukul Sharma10313ba2015-07-29 19:14:39 +05302946 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2947 {
2948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2949 "%s: Roaming in progress, so unable to proceed this request", __func__);
2950 return -EBUSY;
2951 }
2952
Sunil Duttc69bccb2014-05-26 21:30:20 +05302953 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2954 (struct nlattr *)data,
2955 data_len, qca_wlan_vendor_ll_get_policy))
2956 {
2957 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2958 return -EINVAL;
2959 }
2960
2961 if (!tb_vendor
2962 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2963 {
2964 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2965 return -EINVAL;
2966 }
2967
2968 if (!tb_vendor
2969 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2970 {
2971 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2972 return -EINVAL;
2973 }
2974
Sunil Duttc69bccb2014-05-26 21:30:20 +05302975
Dino Mycledf0a5d92014-07-04 09:41:55 +05302976 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302977 nla_get_u32( tb_vendor[
2978 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302979 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302980 nla_get_u32( tb_vendor[
2981 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2982
Dino Mycled3d50022014-07-07 12:58:25 +05302983 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2984 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302985
2986 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302987 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
2988 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302989 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302990
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302991 spin_lock(&hdd_context_lock);
2992 context = &pHddCtx->ll_stats_context;
2993 context->request_id = linkLayerStatsGetReq.reqId;
2994 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
2995 INIT_COMPLETION(context->response_event);
2996 spin_unlock(&hdd_context_lock);
2997
Sunil Duttc69bccb2014-05-26 21:30:20 +05302998 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302999 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303000 {
3001 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3002 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303003 return -EINVAL;
3004 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303005
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303006 rc = wait_for_completion_timeout(&context->response_event,
3007 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
3008 if (!rc)
3009 {
3010 hddLog(LOGE,
3011 FL("Target response timed out request id %d request bitmap 0x%x"),
3012 context->request_id, context->request_bitmap);
3013 return -ETIMEDOUT;
3014 }
3015
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303016 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303017 return 0;
3018}
3019
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303020static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
3021 struct wireless_dev *wdev,
3022 const void *data,
3023 int data_len)
3024{
3025 int ret = 0;
3026
3027 vos_ssr_protect(__func__);
3028 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
3029 vos_ssr_unprotect(__func__);
3030
3031 return ret;
3032}
3033
Sunil Duttc69bccb2014-05-26 21:30:20 +05303034const struct
3035nla_policy
3036qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
3037{
3038 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
3039 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
3040 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
3041 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
3042};
3043
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303044static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3045 struct wireless_dev *wdev,
3046 const void *data,
3047 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303048{
3049 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3050 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05303051 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303052 struct net_device *dev = wdev->netdev;
3053 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3054 u32 statsClearReqMask;
3055 u8 stopReq;
3056 int status;
3057
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303058 ENTER();
3059
Sunil Duttc69bccb2014-05-26 21:30:20 +05303060 status = wlan_hdd_validate_context(pHddCtx);
3061 if (0 != status)
3062 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303063 return -EINVAL;
3064 }
3065
3066 if (NULL == pAdapter)
3067 {
3068 hddLog(VOS_TRACE_LEVEL_FATAL,
3069 "%s: HDD adapter is Null", __func__);
3070 return -ENODEV;
3071 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05303072 /* check the LLStats Capability */
3073 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
3074 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
3075 {
3076 hddLog(VOS_TRACE_LEVEL_ERROR,
3077 FL("Enable LLStats Capability"));
3078 return -EINVAL;
3079 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05303080
3081 if (!pAdapter->isLinkLayerStatsSet)
3082 {
3083 hddLog(VOS_TRACE_LEVEL_FATAL,
3084 "%s: isLinkLayerStatsSet : %d",
3085 __func__, pAdapter->isLinkLayerStatsSet);
3086 return -EINVAL;
3087 }
3088
3089 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
3090 (struct nlattr *)data,
3091 data_len, qca_wlan_vendor_ll_clr_policy))
3092 {
3093 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
3094 return -EINVAL;
3095 }
3096
3097 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
3098
3099 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
3100 {
3101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
3102 return -EINVAL;
3103
3104 }
3105
Sunil Duttc69bccb2014-05-26 21:30:20 +05303106
Dino Mycledf0a5d92014-07-04 09:41:55 +05303107 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303108 nla_get_u32(
3109 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
3110
Dino Mycledf0a5d92014-07-04 09:41:55 +05303111 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303112 nla_get_u8(
3113 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
3114
3115 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05303116 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303117
Dino Mycled3d50022014-07-07 12:58:25 +05303118 vos_mem_copy(linkLayerStatsClearReq.macAddr,
3119 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05303120
3121 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05303122 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
3123 "statsClearReqMask = 0x%X, stopReq = %d",
3124 linkLayerStatsClearReq.reqId,
3125 linkLayerStatsClearReq.macAddr,
3126 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303127 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303128
3129 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303130 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303131 {
3132 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05303133 hdd_station_ctx_t *pHddStaCtx;
3134
3135 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3136 if (VOS_STATUS_SUCCESS !=
3137 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
3138 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
3139 {
3140 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3141 "WLANTL_ClearInterfaceStats Failed", __func__);
3142 return -EINVAL;
3143 }
3144 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
3145 (statsClearReqMask & WIFI_STATS_IFACE)) {
3146 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
3147 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
3148 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
3149 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
3150 }
3151
Sunil Duttc69bccb2014-05-26 21:30:20 +05303152 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
3153 2 * sizeof(u32) +
3154 NLMSG_HDRLEN);
3155
3156 if (temp_skbuff != NULL)
3157 {
3158
3159 if (nla_put_u32(temp_skbuff,
3160 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
3161 statsClearReqMask) ||
3162 nla_put_u32(temp_skbuff,
3163 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
3164 stopReq))
3165 {
3166 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
3167 kfree_skb(temp_skbuff);
3168 return -EINVAL;
3169 }
3170 /* If the ask is to stop the stats collection as part of clear
3171 * (stopReq = 1) , ensure that no further requests of get
3172 * go to the firmware by having isLinkLayerStatsSet set to 0.
3173 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303174 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05303175 * case the firmware is just asked to clear the statistics.
3176 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05303177 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303178 pAdapter->isLinkLayerStatsSet = 0;
3179 return cfg80211_vendor_cmd_reply(temp_skbuff);
3180 }
3181 return -ENOMEM;
3182 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303183
3184 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303185 return -EINVAL;
3186}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303187static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3188 struct wireless_dev *wdev,
3189 const void *data,
3190 int data_len)
3191{
3192 int ret = 0;
3193
3194 vos_ssr_protect(__func__);
3195 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
3196 vos_ssr_unprotect(__func__);
3197
3198 return ret;
3199
3200
3201}
Sunil Duttc69bccb2014-05-26 21:30:20 +05303202#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
3203
Dino Mycle6fb96c12014-06-10 11:52:40 +05303204#ifdef WLAN_FEATURE_EXTSCAN
3205static const struct nla_policy
3206wlan_hdd_extscan_config_policy
3207 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
3208{
3209 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
3210 { .type = NLA_U32 },
3211 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
3212 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05303213 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
3214 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303215 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
3216 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
3217 { .type = NLA_U32 },
3218 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
3219 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
3220
3221 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
3222 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
3223 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
3224 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
3225 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303226 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
3227 { .type = NLA_U32 },
3228 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
3229 { .type = NLA_U32 },
3230 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
3231 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303232 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
3233 { .type = NLA_U32 },
3234 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
3235 { .type = NLA_U32 },
3236 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
3237 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303238 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
3239 { .type = NLA_U8 },
3240 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303241 { .type = NLA_U8 },
3242 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
3243 { .type = NLA_U8 },
3244 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
3245 { .type = NLA_U8 },
3246
3247 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
3248 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05303249 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
3250 .type = NLA_UNSPEC,
3251 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05303252 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
3253 { .type = NLA_S32 },
3254 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
3255 { .type = NLA_S32 },
3256 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
3257 { .type = NLA_U32 },
3258 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
3259 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303260 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
3261 { .type = NLA_U32 },
3262 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
3263 { .type = NLA_BINARY,
3264 .len = IEEE80211_MAX_SSID_LEN + 1 },
3265 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303266 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303267 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
3268 { .type = NLA_U32 },
3269 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
3270 { .type = NLA_U8 },
3271 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
3272 { .type = NLA_S32 },
3273 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
3274 { .type = NLA_S32 },
3275 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
3276 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303277};
3278
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303279/**
3280 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
3281 * @ctx: hdd global context
3282 * @data: capabilities data
3283 *
3284 * Return: none
3285 */
3286static void
3287wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303288{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303289 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303290 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303291 tSirEXTScanCapabilitiesEvent *data =
3292 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303293
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303294 ENTER();
3295
3296 if (wlan_hdd_validate_context(pHddCtx))
3297 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303298 return;
3299 }
3300
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303301 if (!pMsg)
3302 {
3303 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3304 return;
3305 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303306
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303307 vos_spin_lock_acquire(&hdd_context_lock);
3308
3309 context = &pHddCtx->ext_scan_context;
3310 /* validate response received from target*/
3311 if (context->request_id != data->requestId)
3312 {
3313 vos_spin_lock_release(&hdd_context_lock);
3314 hddLog(LOGE,
3315 FL("Target response id did not match: request_id %d resposne_id %d"),
3316 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303317 return;
3318 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303319 else
3320 {
3321 context->capability_response = *data;
3322 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303323 }
3324
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303325 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303326
Dino Mycle6fb96c12014-06-10 11:52:40 +05303327 return;
3328}
3329
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303330/*
3331 * define short names for the global vendor params
3332 * used by wlan_hdd_send_ext_scan_capability()
3333 */
3334#define PARAM_REQUEST_ID \
3335 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3336#define PARAM_STATUS \
3337 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
3338#define MAX_SCAN_CACHE_SIZE \
3339 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
3340#define MAX_SCAN_BUCKETS \
3341 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
3342#define MAX_AP_CACHE_PER_SCAN \
3343 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
3344#define MAX_RSSI_SAMPLE_SIZE \
3345 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
3346#define MAX_SCAN_RPT_THRHOLD \
3347 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
3348#define MAX_HOTLIST_BSSIDS \
3349 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
3350#define MAX_BSSID_HISTORY_ENTRIES \
3351 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
3352#define MAX_HOTLIST_SSIDS \
3353 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303354#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
3355 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303356
3357static int wlan_hdd_send_ext_scan_capability(void *ctx)
3358{
3359 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3360 struct sk_buff *skb = NULL;
3361 int ret;
3362 tSirEXTScanCapabilitiesEvent *data;
3363 tANI_U32 nl_buf_len;
3364
3365 ret = wlan_hdd_validate_context(pHddCtx);
3366 if (0 != ret)
3367 {
3368 return ret;
3369 }
3370
3371 data = &(pHddCtx->ext_scan_context.capability_response);
3372
3373 nl_buf_len = NLMSG_HDRLEN;
3374 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
3375 (sizeof(data->status) + NLA_HDRLEN) +
3376 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
3377 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
3378 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
3379 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
3380 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
3381 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
3382 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
3383 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
3384
3385 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
3386
3387 if (!skb)
3388 {
3389 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
3390 return -ENOMEM;
3391 }
3392
3393 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
3394 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
3395 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
3396 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
3397 data->maxRssiSampleSize, data->maxScanReportingThreshold);
3398 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
3399 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
3400 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
3401
3402 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
3403 nla_put_u32(skb, PARAM_STATUS, data->status) ||
3404 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
3405 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
3406 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
3407 data->maxApPerScan) ||
3408 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
3409 data->maxRssiSampleSize) ||
3410 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
3411 data->maxScanReportingThreshold) ||
3412 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
3413 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
3414 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303415 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
3416 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303417 {
3418 hddLog(LOGE, FL("nla put fail"));
3419 goto nla_put_failure;
3420 }
3421
3422 cfg80211_vendor_cmd_reply(skb);
3423 return 0;
3424
3425nla_put_failure:
3426 kfree_skb(skb);
3427 return -EINVAL;;
3428}
3429
3430/*
3431 * done with short names for the global vendor params
3432 * used by wlan_hdd_send_ext_scan_capability()
3433 */
3434#undef PARAM_REQUEST_ID
3435#undef PARAM_STATUS
3436#undef MAX_SCAN_CACHE_SIZE
3437#undef MAX_SCAN_BUCKETS
3438#undef MAX_AP_CACHE_PER_SCAN
3439#undef MAX_RSSI_SAMPLE_SIZE
3440#undef MAX_SCAN_RPT_THRHOLD
3441#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303442#undef MAX_BSSID_HISTORY_ENTRIES
3443#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05303444
3445static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
3446{
3447 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
3448 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303449 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303450 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303451
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303452 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303453
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303454 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303455 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303456
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303457 if (!pMsg)
3458 {
3459 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460 return;
3461 }
3462
Dino Mycle6fb96c12014-06-10 11:52:40 +05303463 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3464 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
3465
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303466 context = &pHddCtx->ext_scan_context;
3467 spin_lock(&hdd_context_lock);
3468 if (context->request_id == pData->requestId) {
3469 context->response_status = pData->status ? -EINVAL : 0;
3470 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303471 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303472 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303473
3474 /*
3475 * Store the Request ID for comparing with the requestID obtained
3476 * in other requests.HDD shall return a failure is the extscan_stop
3477 * request is issued with a different requestId as that of the
3478 * extscan_start request. Also, This requestId shall be used while
3479 * indicating the full scan results to the upper layers.
3480 * The requestId is stored with the assumption that the firmware
3481 * shall return the ext scan start request's requestId in ext scan
3482 * start response.
3483 */
3484 if (pData->status == 0)
3485 pMac->sme.extScanStartReqId = pData->requestId;
3486
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303487 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303488 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303489}
3490
3491
3492static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
3493{
3494 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
3495 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303496 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303497
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303498 ENTER();
3499
3500 if (wlan_hdd_validate_context(pHddCtx)){
3501 return;
3502 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303503
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303504 if (!pMsg)
3505 {
3506 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303507 return;
3508 }
3509
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303510 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3511 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303512
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303513 context = &pHddCtx->ext_scan_context;
3514 spin_lock(&hdd_context_lock);
3515 if (context->request_id == pData->requestId) {
3516 context->response_status = pData->status ? -EINVAL : 0;
3517 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303518 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303519 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303520
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303521 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303522 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303523}
3524
Dino Mycle6fb96c12014-06-10 11:52:40 +05303525static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3526 void *pMsg)
3527{
3528 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303529 tpSirEXTScanSetBssidHotListRspParams pData =
3530 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303531 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303532
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303533 ENTER();
3534
3535 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303536 return;
3537 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303538
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303539 if (!pMsg)
3540 {
3541 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3542 return;
3543 }
3544
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303545 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3546 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303547
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303548 context = &pHddCtx->ext_scan_context;
3549 spin_lock(&hdd_context_lock);
3550 if (context->request_id == pData->requestId) {
3551 context->response_status = pData->status ? -EINVAL : 0;
3552 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303553 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303554 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303555
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303556 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303557 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303558}
3559
3560static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3561 void *pMsg)
3562{
3563 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303564 tpSirEXTScanResetBssidHotlistRspParams pData =
3565 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303566 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303567
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303568 ENTER();
3569
3570 if (wlan_hdd_validate_context(pHddCtx)) {
3571 return;
3572 }
3573 if (!pMsg)
3574 {
3575 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303576 return;
3577 }
3578
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303579 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3580 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303581
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303582 context = &pHddCtx->ext_scan_context;
3583 spin_lock(&hdd_context_lock);
3584 if (context->request_id == pData->requestId) {
3585 context->response_status = pData->status ? -EINVAL : 0;
3586 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303587 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303588 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303589
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303590 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303591 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303592}
3593
Dino Mycle6fb96c12014-06-10 11:52:40 +05303594static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3595 void *pMsg)
3596{
3597 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3598 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303599 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303600 tANI_S32 totalResults;
3601 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303602 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3603 struct hdd_ext_scan_context *context;
3604 bool ignore_cached_results = false;
3605 tExtscanCachedScanResult *result;
3606 struct nlattr *nla_results;
3607 tANI_U16 ieLength= 0;
3608 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303609
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303610 ENTER();
3611
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303612 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303613 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303614
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303615 if (!pMsg)
3616 {
3617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3618 return;
3619 }
3620
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303621 spin_lock(&hdd_context_lock);
3622 context = &pHddCtx->ext_scan_context;
3623 ignore_cached_results = context->ignore_cached_results;
3624 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303625
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303626 if (ignore_cached_results) {
3627 hddLog(LOGE,
3628 FL("Ignore the cached results received after timeout"));
3629 return;
3630 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303631
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303632 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3633 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303634
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303635 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303636
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303637 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3638 scan_id_index++) {
3639 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303640
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303641 totalResults = result->num_results;
3642 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3643 result->scan_id, result->flags, totalResults);
3644 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303645
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303646 do{
3647 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3648 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3649 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303650
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303651 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3652 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3653
3654 if (!skb) {
3655 hddLog(VOS_TRACE_LEVEL_ERROR,
3656 FL("cfg80211_vendor_event_alloc failed"));
3657 return;
3658 }
3659
3660 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3661
3662 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3663 pData->requestId) ||
3664 nla_put_u32(skb,
3665 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3666 resultsPerEvent)) {
3667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3668 goto fail;
3669 }
3670 if (nla_put_u8(skb,
3671 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3672 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303673 {
3674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3675 goto fail;
3676 }
3677
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303678 if (nla_put_u32(skb,
3679 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3680 result->scan_id)) {
3681 hddLog(LOGE, FL("put fail"));
3682 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303683 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303684
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303685 nla_results = nla_nest_start(skb,
3686 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3687 if (!nla_results)
3688 goto fail;
3689
3690 if (resultsPerEvent) {
3691 struct nlattr *aps;
3692 struct nlattr *nla_result;
3693
3694 nla_result = nla_nest_start(skb, scan_id_index);
3695 if(!nla_result)
3696 goto fail;
3697
3698 if (nla_put_u32(skb,
3699 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3700 result->scan_id) ||
3701 nla_put_u32(skb,
3702 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3703 result->flags) ||
3704 nla_put_u32(skb,
3705 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3706 totalResults)) {
3707 hddLog(LOGE, FL("put fail"));
3708 goto fail;
3709 }
3710
3711 aps = nla_nest_start(skb,
3712 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3713 if (!aps)
3714 {
3715 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3716 goto fail;
3717 }
3718
3719 head_ptr = (tpSirWifiScanResult) &(result->ap);
3720
3721 for (j = 0; j < resultsPerEvent; j++, i++) {
3722 struct nlattr *ap;
3723 pSirWifiScanResult = head_ptr + i;
3724
3725 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303726 * Firmware returns timestamp from extscan_start till
3727 * BSSID was cached (in micro seconds). Add this with
3728 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303729 * to derive the time since boot when the
3730 * BSSID was cached.
3731 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303732 pSirWifiScanResult->ts +=
3733 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303734 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3735 "Ssid (%s)"
3736 "Bssid: %pM "
3737 "Channel (%u)"
3738 "Rssi (%d)"
3739 "RTT (%u)"
3740 "RTT_SD (%u)"
3741 "Beacon Period %u"
3742 "Capability 0x%x "
3743 "Ie length %d",
3744 i,
3745 pSirWifiScanResult->ts,
3746 pSirWifiScanResult->ssid,
3747 pSirWifiScanResult->bssid,
3748 pSirWifiScanResult->channel,
3749 pSirWifiScanResult->rssi,
3750 pSirWifiScanResult->rtt,
3751 pSirWifiScanResult->rtt_sd,
3752 pSirWifiScanResult->beaconPeriod,
3753 pSirWifiScanResult->capability,
3754 ieLength);
3755
3756 ap = nla_nest_start(skb, j + 1);
3757 if (!ap)
3758 {
3759 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3760 goto fail;
3761 }
3762
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303763 if (hdd_wlan_nla_put_u64(skb,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303764 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3765 pSirWifiScanResult->ts) )
3766 {
3767 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3768 goto fail;
3769 }
3770 if (nla_put(skb,
3771 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3772 sizeof(pSirWifiScanResult->ssid),
3773 pSirWifiScanResult->ssid) )
3774 {
3775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3776 goto fail;
3777 }
3778 if (nla_put(skb,
3779 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3780 sizeof(pSirWifiScanResult->bssid),
3781 pSirWifiScanResult->bssid) )
3782 {
3783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3784 goto fail;
3785 }
3786 if (nla_put_u32(skb,
3787 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3788 pSirWifiScanResult->channel) )
3789 {
3790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3791 goto fail;
3792 }
3793 if (nla_put_s32(skb,
3794 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3795 pSirWifiScanResult->rssi) )
3796 {
3797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3798 goto fail;
3799 }
3800 if (nla_put_u32(skb,
3801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3802 pSirWifiScanResult->rtt) )
3803 {
3804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3805 goto fail;
3806 }
3807 if (nla_put_u32(skb,
3808 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3809 pSirWifiScanResult->rtt_sd))
3810 {
3811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3812 goto fail;
3813 }
3814 if (nla_put_u32(skb,
3815 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3816 pSirWifiScanResult->beaconPeriod))
3817 {
3818 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3819 goto fail;
3820 }
3821 if (nla_put_u32(skb,
3822 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3823 pSirWifiScanResult->capability))
3824 {
3825 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3826 goto fail;
3827 }
3828 if (nla_put_u32(skb,
3829 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3830 ieLength))
3831 {
3832 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3833 goto fail;
3834 }
3835
3836 if (ieLength)
3837 if (nla_put(skb,
3838 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3839 ieLength, ie)) {
3840 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3841 goto fail;
3842 }
3843
3844 nla_nest_end(skb, ap);
3845 }
3846 nla_nest_end(skb, aps);
3847 nla_nest_end(skb, nla_result);
3848 }
3849
3850 nla_nest_end(skb, nla_results);
3851
3852 cfg80211_vendor_cmd_reply(skb);
3853
3854 } while (totalResults > 0);
3855 }
3856
3857 if (!pData->moreData) {
3858 spin_lock(&hdd_context_lock);
3859 context->response_status = 0;
3860 complete(&context->response_event);
3861 spin_unlock(&hdd_context_lock);
3862 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303863
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303864 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303865 return;
3866fail:
3867 kfree_skb(skb);
3868 return;
3869}
3870
3871static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3872 void *pMsg)
3873{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303874 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303875 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3876 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303877 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303878
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303879 ENTER();
3880
3881 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303882 hddLog(LOGE,
3883 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303884 return;
3885 }
3886 if (!pMsg)
3887 {
3888 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303889 return;
3890 }
3891
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303892 if (pData->bss_found)
3893 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3894 else
3895 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3896
Dino Mycle6fb96c12014-06-10 11:52:40 +05303897 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303898#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3899 NULL,
3900#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303901 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303902 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303903
3904 if (!skb) {
3905 hddLog(VOS_TRACE_LEVEL_ERROR,
3906 FL("cfg80211_vendor_event_alloc failed"));
3907 return;
3908 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303909
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303910 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3911 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3912 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3913 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3914
3915 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303916 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3917 "Ssid (%s) "
3918 "Bssid (" MAC_ADDRESS_STR ") "
3919 "Channel (%u) "
3920 "Rssi (%d) "
3921 "RTT (%u) "
3922 "RTT_SD (%u) ",
3923 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303924 pData->bssHotlist[i].ts,
3925 pData->bssHotlist[i].ssid,
3926 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3927 pData->bssHotlist[i].channel,
3928 pData->bssHotlist[i].rssi,
3929 pData->bssHotlist[i].rtt,
3930 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303931 }
3932
3933 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3934 pData->requestId) ||
3935 nla_put_u32(skb,
3936 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303937 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3939 goto fail;
3940 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303941 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303942 struct nlattr *aps;
3943
3944 aps = nla_nest_start(skb,
3945 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3946 if (!aps)
3947 goto fail;
3948
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303949 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303950 struct nlattr *ap;
3951
3952 ap = nla_nest_start(skb, i + 1);
3953 if (!ap)
3954 goto fail;
3955
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303956 if (hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303957 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303958 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303959 nla_put(skb,
3960 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303961 sizeof(pData->bssHotlist[i].ssid),
3962 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303963 nla_put(skb,
3964 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303965 sizeof(pData->bssHotlist[i].bssid),
3966 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303967 nla_put_u32(skb,
3968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303969 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303970 nla_put_s32(skb,
3971 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303972 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303973 nla_put_u32(skb,
3974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303975 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303976 nla_put_u32(skb,
3977 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303978 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303979 goto fail;
3980
3981 nla_nest_end(skb, ap);
3982 }
3983 nla_nest_end(skb, aps);
3984
3985 if (nla_put_u8(skb,
3986 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3987 pData->moreData))
3988 goto fail;
3989 }
3990
3991 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303992 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303993 return;
3994
3995fail:
3996 kfree_skb(skb);
3997 return;
3998
3999}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304000
4001static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
4002 void *pMsg)
4003{
4004 struct sk_buff *skb;
4005 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4006 tpSirWifiFullScanResultEvent pData =
4007 (tpSirWifiFullScanResultEvent) (pMsg);
4008
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304009 ENTER();
4010
4011 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304012 hddLog(LOGE,
4013 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304014 return;
4015 }
4016 if (!pMsg)
4017 {
4018 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304019 return;
4020 }
4021
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304022 /*
4023 * If the full scan result including IE data exceeds NL 4K size
4024 * limitation, drop that beacon/probe rsp frame.
4025 */
4026 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
4027 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
4028 return;
4029 }
4030
Dino Mycle6fb96c12014-06-10 11:52:40 +05304031 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304032#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4033 NULL,
4034#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304035 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4036 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
4037 GFP_KERNEL);
4038
4039 if (!skb) {
4040 hddLog(VOS_TRACE_LEVEL_ERROR,
4041 FL("cfg80211_vendor_event_alloc failed"));
4042 return;
4043 }
4044
Dino Mycle6fb96c12014-06-10 11:52:40 +05304045 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
4046 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
4047 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
4048 "Ssid (%s)"
4049 "Bssid (" MAC_ADDRESS_STR ")"
4050 "Channel (%u)"
4051 "Rssi (%d)"
4052 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304053 "RTT_SD (%u)"
4054 "Bcn Period %d"
4055 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05304056 pData->ap.ts,
4057 pData->ap.ssid,
4058 MAC_ADDR_ARRAY(pData->ap.bssid),
4059 pData->ap.channel,
4060 pData->ap.rssi,
4061 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304062 pData->ap.rtt_sd,
4063 pData->ap.beaconPeriod,
4064 pData->ap.capability);
4065
Dino Mycle6fb96c12014-06-10 11:52:40 +05304066 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
4067 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4068 pData->requestId) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304069 hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304070 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
4071 pData->ap.ts) ||
4072 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
4073 sizeof(pData->ap.ssid),
4074 pData->ap.ssid) ||
4075 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
4076 WNI_CFG_BSSID_LEN,
4077 pData->ap.bssid) ||
4078 nla_put_u32(skb,
4079 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
4080 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05304081 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304082 pData->ap.rssi) ||
4083 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
4084 pData->ap.rtt) ||
4085 nla_put_u32(skb,
4086 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
4087 pData->ap.rtt_sd) ||
4088 nla_put_u16(skb,
4089 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
4090 pData->ap.beaconPeriod) ||
4091 nla_put_u16(skb,
4092 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
4093 pData->ap.capability) ||
4094 nla_put_u32(skb,
4095 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304096 pData->ieLength) ||
4097 nla_put_u8(skb,
4098 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
4099 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304100 {
4101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4102 goto nla_put_failure;
4103 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304104
4105 if (pData->ieLength) {
4106 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
4107 pData->ieLength,
4108 pData->ie))
4109 {
4110 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4111 goto nla_put_failure;
4112 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304113 }
4114
4115 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304116 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304117 return;
4118
4119nla_put_failure:
4120 kfree_skb(skb);
4121 return;
4122}
4123
4124static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
4125 void *pMsg)
4126{
4127 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4128 struct sk_buff *skb = NULL;
4129 tpSirEXTScanResultsAvailableIndParams pData =
4130 (tpSirEXTScanResultsAvailableIndParams) pMsg;
4131
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304132 ENTER();
4133
4134 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304135 hddLog(LOGE,
4136 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304137 return;
4138 }
4139 if (!pMsg)
4140 {
4141 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304142 return;
4143 }
4144
4145 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304146#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4147 NULL,
4148#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304149 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4150 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
4151 GFP_KERNEL);
4152
4153 if (!skb) {
4154 hddLog(VOS_TRACE_LEVEL_ERROR,
4155 FL("cfg80211_vendor_event_alloc failed"));
4156 return;
4157 }
4158
Dino Mycle6fb96c12014-06-10 11:52:40 +05304159 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
4160 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
4161 pData->numResultsAvailable);
4162 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4163 pData->requestId) ||
4164 nla_put_u32(skb,
4165 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
4166 pData->numResultsAvailable)) {
4167 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4168 goto nla_put_failure;
4169 }
4170
4171 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304172 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304173 return;
4174
4175nla_put_failure:
4176 kfree_skb(skb);
4177 return;
4178}
4179
4180static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
4181{
4182 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4183 struct sk_buff *skb = NULL;
4184 tpSirEXTScanProgressIndParams pData =
4185 (tpSirEXTScanProgressIndParams) pMsg;
4186
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304187 ENTER();
4188
4189 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304190 hddLog(LOGE,
4191 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304192 return;
4193 }
4194 if (!pMsg)
4195 {
4196 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304197 return;
4198 }
4199
4200 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304201#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4202 NULL,
4203#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304204 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4205 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
4206 GFP_KERNEL);
4207
4208 if (!skb) {
4209 hddLog(VOS_TRACE_LEVEL_ERROR,
4210 FL("cfg80211_vendor_event_alloc failed"));
4211 return;
4212 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304213 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304214 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
4215 pData->extScanEventType);
4216 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
4217 pData->status);
4218
4219 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
4220 pData->extScanEventType) ||
4221 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05304222 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4223 pData->requestId) ||
4224 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304225 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
4226 pData->status)) {
4227 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4228 goto nla_put_failure;
4229 }
4230
4231 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304232 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304233 return;
4234
4235nla_put_failure:
4236 kfree_skb(skb);
4237 return;
4238}
4239
4240void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
4241 void *pMsg)
4242{
4243 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4244
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304245 ENTER();
4246
Dino Mycle6fb96c12014-06-10 11:52:40 +05304247 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304248 return;
4249 }
4250
4251 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
4252
4253
4254 switch(evType) {
4255 case SIR_HAL_EXTSCAN_START_RSP:
4256 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
4257 break;
4258
4259 case SIR_HAL_EXTSCAN_STOP_RSP:
4260 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
4261 break;
4262 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
4263 /* There is no need to send this response to upper layer
4264 Just log the message */
4265 hddLog(VOS_TRACE_LEVEL_INFO,
4266 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
4267 break;
4268 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
4269 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
4270 break;
4271
4272 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
4273 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
4274 break;
4275
Dino Mycle6fb96c12014-06-10 11:52:40 +05304276 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304277 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304278 break;
4279 case SIR_HAL_EXTSCAN_PROGRESS_IND:
4280 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
4281 break;
4282 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
4283 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
4284 break;
4285 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
4286 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
4287 break;
4288 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
4289 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
4290 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304291 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
4292 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
4293 break;
4294 default:
4295 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
4296 break;
4297 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304298 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304299}
4300
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304301static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4302 struct wireless_dev *wdev,
4303 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304304{
Dino Myclee8843b32014-07-04 14:21:45 +05304305 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304306 struct net_device *dev = wdev->netdev;
4307 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4308 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4309 struct nlattr
4310 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4311 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304312 struct hdd_ext_scan_context *context;
4313 unsigned long rc;
4314 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304315
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304316 ENTER();
4317
Dino Mycle6fb96c12014-06-10 11:52:40 +05304318 status = wlan_hdd_validate_context(pHddCtx);
4319 if (0 != status)
4320 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304321 return -EINVAL;
4322 }
Dino Myclee8843b32014-07-04 14:21:45 +05304323 /* check the EXTScan Capability */
4324 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304325 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4326 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304327 {
4328 hddLog(VOS_TRACE_LEVEL_ERROR,
4329 FL("EXTScan not enabled/supported by Firmware"));
4330 return -EINVAL;
4331 }
4332
Dino Mycle6fb96c12014-06-10 11:52:40 +05304333 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4334 data, dataLen,
4335 wlan_hdd_extscan_config_policy)) {
4336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4337 return -EINVAL;
4338 }
4339
4340 /* Parse and fetch request Id */
4341 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4342 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4343 return -EINVAL;
4344 }
4345
Dino Myclee8843b32014-07-04 14:21:45 +05304346 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304347 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304348 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304349
Dino Myclee8843b32014-07-04 14:21:45 +05304350 reqMsg.sessionId = pAdapter->sessionId;
4351 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304352
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304353 vos_spin_lock_acquire(&hdd_context_lock);
4354 context = &pHddCtx->ext_scan_context;
4355 context->request_id = reqMsg.requestId;
4356 INIT_COMPLETION(context->response_event);
4357 vos_spin_lock_release(&hdd_context_lock);
4358
Dino Myclee8843b32014-07-04 14:21:45 +05304359 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304360 if (!HAL_STATUS_SUCCESS(status)) {
4361 hddLog(VOS_TRACE_LEVEL_ERROR,
4362 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304363 return -EINVAL;
4364 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304365
4366 rc = wait_for_completion_timeout(&context->response_event,
4367 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4368 if (!rc) {
4369 hddLog(LOGE, FL("Target response timed out"));
4370 return -ETIMEDOUT;
4371 }
4372
4373 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
4374 if (ret)
4375 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
4376
4377 return ret;
4378
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304379 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304380 return 0;
4381}
4382
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304383static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4384 struct wireless_dev *wdev,
4385 const void *data, int dataLen)
4386{
4387 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304388
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304389 vos_ssr_protect(__func__);
4390 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
4391 vos_ssr_unprotect(__func__);
4392
4393 return ret;
4394}
4395
4396static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4397 struct wireless_dev *wdev,
4398 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304399{
Dino Myclee8843b32014-07-04 14:21:45 +05304400 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304401 struct net_device *dev = wdev->netdev;
4402 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4403 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4404 struct nlattr
4405 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4406 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304407 struct hdd_ext_scan_context *context;
4408 unsigned long rc;
4409 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304410
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304411 ENTER();
4412
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304413 if (VOS_FTM_MODE == hdd_get_conparam()) {
4414 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4415 return -EINVAL;
4416 }
4417
Dino Mycle6fb96c12014-06-10 11:52:40 +05304418 status = wlan_hdd_validate_context(pHddCtx);
4419 if (0 != status)
4420 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304421 return -EINVAL;
4422 }
Dino Myclee8843b32014-07-04 14:21:45 +05304423 /* check the EXTScan Capability */
4424 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304425 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4426 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304427 {
4428 hddLog(VOS_TRACE_LEVEL_ERROR,
4429 FL("EXTScan not enabled/supported by Firmware"));
4430 return -EINVAL;
4431 }
4432
Dino Mycle6fb96c12014-06-10 11:52:40 +05304433 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4434 data, dataLen,
4435 wlan_hdd_extscan_config_policy)) {
4436 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4437 return -EINVAL;
4438 }
4439 /* Parse and fetch request Id */
4440 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4441 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4442 return -EINVAL;
4443 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304444
Dino Myclee8843b32014-07-04 14:21:45 +05304445 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304446 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4447
Dino Myclee8843b32014-07-04 14:21:45 +05304448 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304449
Dino Myclee8843b32014-07-04 14:21:45 +05304450 reqMsg.sessionId = pAdapter->sessionId;
4451 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304452
4453 /* Parse and fetch flush parameter */
4454 if (!tb
4455 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
4456 {
4457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
4458 goto failed;
4459 }
Dino Myclee8843b32014-07-04 14:21:45 +05304460 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304461 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
4462
Dino Myclee8843b32014-07-04 14:21:45 +05304463 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304464
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304465 spin_lock(&hdd_context_lock);
4466 context = &pHddCtx->ext_scan_context;
4467 context->request_id = reqMsg.requestId;
4468 context->ignore_cached_results = false;
4469 INIT_COMPLETION(context->response_event);
4470 spin_unlock(&hdd_context_lock);
4471
Dino Myclee8843b32014-07-04 14:21:45 +05304472 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304473 if (!HAL_STATUS_SUCCESS(status)) {
4474 hddLog(VOS_TRACE_LEVEL_ERROR,
4475 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304476 return -EINVAL;
4477 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304478
4479 rc = wait_for_completion_timeout(&context->response_event,
4480 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4481 if (!rc) {
4482 hddLog(LOGE, FL("Target response timed out"));
4483 retval = -ETIMEDOUT;
4484 spin_lock(&hdd_context_lock);
4485 context->ignore_cached_results = true;
4486 spin_unlock(&hdd_context_lock);
4487 } else {
4488 spin_lock(&hdd_context_lock);
4489 retval = context->response_status;
4490 spin_unlock(&hdd_context_lock);
4491 }
4492
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304493 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304494 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304495
4496failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05304497 return -EINVAL;
4498}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304499static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4500 struct wireless_dev *wdev,
4501 const void *data, int dataLen)
4502{
4503 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304504
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304505 vos_ssr_protect(__func__);
4506 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
4507 vos_ssr_unprotect(__func__);
4508
4509 return ret;
4510}
4511
4512static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304513 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05304514 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304515{
4516 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
4517 struct net_device *dev = wdev->netdev;
4518 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4519 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4520 struct nlattr
4521 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4522 struct nlattr
4523 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4524 struct nlattr *apTh;
4525 eHalStatus status;
4526 tANI_U8 i = 0;
4527 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304528 struct hdd_ext_scan_context *context;
4529 tANI_U32 request_id;
4530 unsigned long rc;
4531 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304532
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304533 ENTER();
4534
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304535 if (VOS_FTM_MODE == hdd_get_conparam()) {
4536 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4537 return -EINVAL;
4538 }
4539
Dino Mycle6fb96c12014-06-10 11:52:40 +05304540 status = wlan_hdd_validate_context(pHddCtx);
4541 if (0 != status)
4542 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304543 return -EINVAL;
4544 }
Dino Myclee8843b32014-07-04 14:21:45 +05304545 /* check the EXTScan Capability */
4546 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304547 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4548 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304549 {
4550 hddLog(VOS_TRACE_LEVEL_ERROR,
4551 FL("EXTScan not enabled/supported by Firmware"));
4552 return -EINVAL;
4553 }
4554
Dino Mycle6fb96c12014-06-10 11:52:40 +05304555 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4556 data, dataLen,
4557 wlan_hdd_extscan_config_policy)) {
4558 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4559 return -EINVAL;
4560 }
4561
4562 /* Parse and fetch request Id */
4563 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4564 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4565 return -EINVAL;
4566 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304567 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4568 vos_mem_malloc(sizeof(*pReqMsg));
4569 if (!pReqMsg) {
4570 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4571 return -ENOMEM;
4572 }
4573
Dino Myclee8843b32014-07-04 14:21:45 +05304574
Dino Mycle6fb96c12014-06-10 11:52:40 +05304575 pReqMsg->requestId = nla_get_u32(
4576 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4577 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4578
4579 /* Parse and fetch number of APs */
4580 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4582 goto fail;
4583 }
4584
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304585 /* Parse and fetch lost ap sample size */
4586 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4587 hddLog(LOGE, FL("attr lost ap sample size failed"));
4588 goto fail;
4589 }
4590
4591 pReqMsg->lostBssidSampleSize = nla_get_u32(
4592 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4593 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4594
Dino Mycle6fb96c12014-06-10 11:52:40 +05304595 pReqMsg->sessionId = pAdapter->sessionId;
4596 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4597
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304598 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304599 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304600 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4601 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4602 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4603 goto fail;
4604 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304605 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304606
4607 nla_for_each_nested(apTh,
4608 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304609 if (i == pReqMsg->numBssid) {
4610 hddLog(LOGW, FL("Ignoring excess AP"));
4611 break;
4612 }
4613
Dino Mycle6fb96c12014-06-10 11:52:40 +05304614 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4615 nla_data(apTh), nla_len(apTh),
4616 NULL)) {
4617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4618 goto fail;
4619 }
4620
4621 /* Parse and fetch MAC address */
4622 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4623 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4624 goto fail;
4625 }
4626 memcpy(pReqMsg->ap[i].bssid, nla_data(
4627 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4628 sizeof(tSirMacAddr));
4629 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4630
4631 /* Parse and fetch low RSSI */
4632 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4633 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4634 goto fail;
4635 }
4636 pReqMsg->ap[i].low = nla_get_s32(
4637 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4638 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4639
4640 /* Parse and fetch high RSSI */
4641 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4642 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4643 goto fail;
4644 }
4645 pReqMsg->ap[i].high = nla_get_s32(
4646 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4647 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4648 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304649 i++;
4650 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304651
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304652 if (i < pReqMsg->numBssid) {
4653 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4654 i, pReqMsg->numBssid);
4655 pReqMsg->numBssid = i;
4656 }
4657
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304658 context = &pHddCtx->ext_scan_context;
4659 spin_lock(&hdd_context_lock);
4660 INIT_COMPLETION(context->response_event);
4661 context->request_id = request_id = pReqMsg->requestId;
4662 spin_unlock(&hdd_context_lock);
4663
Dino Mycle6fb96c12014-06-10 11:52:40 +05304664 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4665 if (!HAL_STATUS_SUCCESS(status)) {
4666 hddLog(VOS_TRACE_LEVEL_ERROR,
4667 FL("sme_SetBssHotlist failed(err=%d)"), status);
4668 vos_mem_free(pReqMsg);
4669 return -EINVAL;
4670 }
4671
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304672 /* request was sent -- wait for the response */
4673 rc = wait_for_completion_timeout(&context->response_event,
4674 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4675
4676 if (!rc) {
4677 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4678 retval = -ETIMEDOUT;
4679 } else {
4680 spin_lock(&hdd_context_lock);
4681 if (context->request_id == request_id)
4682 retval = context->response_status;
4683 else
4684 retval = -EINVAL;
4685 spin_unlock(&hdd_context_lock);
4686 }
4687
Dino Myclee8843b32014-07-04 14:21:45 +05304688 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304689 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304690 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304691
4692fail:
4693 vos_mem_free(pReqMsg);
4694 return -EINVAL;
4695}
4696
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304697static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4698 struct wireless_dev *wdev,
4699 const void *data, int dataLen)
4700{
4701 int ret = 0;
4702
4703 vos_ssr_protect(__func__);
4704 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4705 dataLen);
4706 vos_ssr_unprotect(__func__);
4707
4708 return ret;
4709}
4710
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304711static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304712 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304713 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304714{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304715 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4716 struct net_device *dev = wdev->netdev;
4717 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4718 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4719 uint8_t num_channels = 0;
4720 uint8_t num_chan_new = 0;
4721 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304722 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304723 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304724 tWifiBand wifiBand;
4725 eHalStatus status;
4726 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304727 tANI_U8 i,j,k;
4728 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304729
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304730 ENTER();
4731
Dino Mycle6fb96c12014-06-10 11:52:40 +05304732 status = wlan_hdd_validate_context(pHddCtx);
4733 if (0 != status)
4734 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304735 return -EINVAL;
4736 }
Dino Myclee8843b32014-07-04 14:21:45 +05304737
Dino Mycle6fb96c12014-06-10 11:52:40 +05304738 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4739 data, dataLen,
4740 wlan_hdd_extscan_config_policy)) {
4741 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4742 return -EINVAL;
4743 }
4744
4745 /* Parse and fetch request Id */
4746 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4747 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4748 return -EINVAL;
4749 }
4750 requestId = nla_get_u32(
4751 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4752 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4753
4754 /* Parse and fetch wifi band */
4755 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4756 {
4757 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4758 return -EINVAL;
4759 }
4760 wifiBand = nla_get_u32(
4761 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4762 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4763
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304764 /* Parse and fetch max channels */
4765 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4766 {
4767 hddLog(LOGE, FL("attr max channels failed"));
4768 return -EINVAL;
4769 }
4770 maxChannels = nla_get_u32(
4771 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4772 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4773
Dino Mycle6fb96c12014-06-10 11:52:40 +05304774 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304775 wifiBand, chan_list,
4776 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304777 if (eHAL_STATUS_SUCCESS != status) {
4778 hddLog(VOS_TRACE_LEVEL_ERROR,
4779 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4780 return -EINVAL;
4781 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304782
Agrawal Ashish16abf782016-08-18 22:42:59 +05304783 num_channels = VOS_MIN(num_channels, maxChannels);
4784 num_chan_new = num_channels;
4785 /* remove the indoor only channels if iface is SAP */
4786 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4787 {
4788 num_chan_new = 0;
4789 for (i = 0; i < num_channels; i++)
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304790 for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) {
Agrawal Ashish16abf782016-08-18 22:42:59 +05304791 if (wiphy->bands[j] == NULL)
4792 continue;
4793 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4794 if ((chan_list[i] ==
4795 wiphy->bands[j]->channels[k].center_freq) &&
4796 (!(wiphy->bands[j]->channels[k].flags &
4797 IEEE80211_CHAN_INDOOR_ONLY))) {
4798 chan_list[num_chan_new] = chan_list[i];
4799 num_chan_new++;
4800 }
4801 }
4802 }
4803 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304804
Agrawal Ashish16abf782016-08-18 22:42:59 +05304805 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4806 for (i = 0; i < num_chan_new; i++)
4807 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4808 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304809
4810 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304811 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304812 NLMSG_HDRLEN);
4813
4814 if (!replySkb) {
4815 hddLog(VOS_TRACE_LEVEL_ERROR,
4816 FL("valid channels: buffer alloc fail"));
4817 return -EINVAL;
4818 }
4819 if (nla_put_u32(replySkb,
4820 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304821 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304822 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304823 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304824
4825 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4826 kfree_skb(replySkb);
4827 return -EINVAL;
4828 }
4829
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304830 ret = cfg80211_vendor_cmd_reply(replySkb);
4831
4832 EXIT();
4833 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304834}
4835
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304836static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4837 struct wireless_dev *wdev,
4838 const void *data, int dataLen)
4839{
4840 int ret = 0;
4841
4842 vos_ssr_protect(__func__);
4843 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4844 dataLen);
4845 vos_ssr_unprotect(__func__);
4846
4847 return ret;
4848}
4849
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304850static int hdd_extscan_start_fill_bucket_channel_spec(
4851 hdd_context_t *pHddCtx,
4852 tpSirEXTScanStartReqParams pReqMsg,
4853 struct nlattr **tb)
4854{
4855 struct nlattr *bucket[
4856 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4857 struct nlattr *channel[
4858 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4859 struct nlattr *buckets;
4860 struct nlattr *channels;
4861 int rem1, rem2;
4862 eHalStatus status;
4863 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304864 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304865 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4866 tANI_U32 passive_max_chn_time, active_max_chn_time;
4867
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304868 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304869 bktIndex = 0;
4870
4871 nla_for_each_nested(buckets,
4872 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304873 if (bktIndex >= expected_buckets) {
4874 hddLog(LOGW, FL("ignoring excess buckets"));
4875 break;
4876 }
4877
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304878 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304879 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4880 nla_data(buckets), nla_len(buckets),
4881 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304882 hddLog(LOGE, FL("nla_parse failed"));
4883 return -EINVAL;
4884 }
4885
4886 /* Parse and fetch bucket spec */
4887 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4888 hddLog(LOGE, FL("attr bucket index failed"));
4889 return -EINVAL;
4890 }
4891 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4892 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4893 hddLog(LOG1, FL("Bucket spec Index %d"),
4894 pReqMsg->buckets[bktIndex].bucket);
4895
4896 /* Parse and fetch wifi band */
4897 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4898 hddLog(LOGE, FL("attr wifi band failed"));
4899 return -EINVAL;
4900 }
4901 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4902 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4903 hddLog(LOG1, FL("Wifi band %d"),
4904 pReqMsg->buckets[bktIndex].band);
4905
4906 /* Parse and fetch period */
4907 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4908 hddLog(LOGE, FL("attr period failed"));
4909 return -EINVAL;
4910 }
4911 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4912 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4913 hddLog(LOG1, FL("period %d"),
4914 pReqMsg->buckets[bktIndex].period);
4915
4916 /* Parse and fetch report events */
4917 if (!bucket[
4918 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4919 hddLog(LOGE, FL("attr report events failed"));
4920 return -EINVAL;
4921 }
4922 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4923 bucket[
4924 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4925 hddLog(LOG1, FL("report events %d"),
4926 pReqMsg->buckets[bktIndex].reportEvents);
4927
4928 /* Parse and fetch max period */
4929 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4930 hddLog(LOGE, FL("attr max period failed"));
4931 return -EINVAL;
4932 }
4933 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4934 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4935 hddLog(LOG1, FL("max period %u"),
4936 pReqMsg->buckets[bktIndex].max_period);
4937
4938 /* Parse and fetch exponent */
4939 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4940 hddLog(LOGE, FL("attr exponent failed"));
4941 return -EINVAL;
4942 }
4943 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4944 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4945 hddLog(LOG1, FL("exponent %u"),
4946 pReqMsg->buckets[bktIndex].exponent);
4947
4948 /* Parse and fetch step count */
4949 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4950 hddLog(LOGE, FL("attr step count failed"));
4951 return -EINVAL;
4952 }
4953 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4954 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4955 hddLog(LOG1, FL("Step count %u"),
4956 pReqMsg->buckets[bktIndex].step_count);
4957
4958 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4959 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4960
4961 /* Framework shall pass the channel list if the input WiFi band is
4962 * WIFI_BAND_UNSPECIFIED.
4963 * If the input WiFi band is specified (any value other than
4964 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4965 */
4966 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4967 numChannels = 0;
4968 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4969 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4970 pReqMsg->buckets[bktIndex].band,
4971 chanList, &numChannels);
4972 if (!HAL_STATUS_SUCCESS(status)) {
4973 hddLog(LOGE,
4974 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4975 status);
4976 return -EINVAL;
4977 }
4978
4979 pReqMsg->buckets[bktIndex].numChannels =
4980 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4981 hddLog(LOG1, FL("Num channels %d"),
4982 pReqMsg->buckets[bktIndex].numChannels);
4983
4984 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4985 j++) {
4986 pReqMsg->buckets[bktIndex].channels[j].channel =
4987 chanList[j];
4988 pReqMsg->buckets[bktIndex].channels[j].
4989 chnlClass = 0;
4990 if (CSR_IS_CHANNEL_DFS(
4991 vos_freq_to_chan(chanList[j]))) {
4992 pReqMsg->buckets[bktIndex].channels[j].
4993 passive = 1;
4994 pReqMsg->buckets[bktIndex].channels[j].
4995 dwellTimeMs = passive_max_chn_time;
4996 } else {
4997 pReqMsg->buckets[bktIndex].channels[j].
4998 passive = 0;
4999 pReqMsg->buckets[bktIndex].channels[j].
5000 dwellTimeMs = active_max_chn_time;
5001 }
5002
5003 hddLog(LOG1,
5004 "Channel %u Passive %u Dwell time %u ms",
5005 pReqMsg->buckets[bktIndex].channels[j].channel,
5006 pReqMsg->buckets[bktIndex].channels[j].passive,
5007 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5008 }
5009
5010 bktIndex++;
5011 continue;
5012 }
5013
5014 /* Parse and fetch number of channels */
5015 if (!bucket[
5016 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
5017 hddLog(LOGE, FL("attr num channels failed"));
5018 return -EINVAL;
5019 }
5020
5021 pReqMsg->buckets[bktIndex].numChannels =
5022 nla_get_u32(bucket[
5023 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
5024 hddLog(LOG1, FL("num channels %d"),
5025 pReqMsg->buckets[bktIndex].numChannels);
5026
5027 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
5028 hddLog(LOGE, FL("attr channel spec failed"));
5029 return -EINVAL;
5030 }
5031
5032 j = 0;
5033 nla_for_each_nested(channels,
5034 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
5035 if (nla_parse(channel,
5036 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5037 nla_data(channels), nla_len(channels),
5038 wlan_hdd_extscan_config_policy)) {
5039 hddLog(LOGE, FL("nla_parse failed"));
5040 return -EINVAL;
5041 }
5042
5043 /* Parse and fetch channel */
5044 if (!channel[
5045 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
5046 hddLog(LOGE, FL("attr channel failed"));
5047 return -EINVAL;
5048 }
5049 pReqMsg->buckets[bktIndex].channels[j].channel =
5050 nla_get_u32(channel[
5051 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
5052 hddLog(LOG1, FL("channel %u"),
5053 pReqMsg->buckets[bktIndex].channels[j].channel);
5054
5055 /* Parse and fetch dwell time */
5056 if (!channel[
5057 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
5058 hddLog(LOGE, FL("attr dwelltime failed"));
5059 return -EINVAL;
5060 }
5061 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
5062 nla_get_u32(channel[
5063 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
5064
5065 hddLog(LOG1, FL("Dwell time (%u ms)"),
5066 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5067
5068
5069 /* Parse and fetch channel spec passive */
5070 if (!channel[
5071 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
5072 hddLog(LOGE,
5073 FL("attr channel spec passive failed"));
5074 return -EINVAL;
5075 }
5076 pReqMsg->buckets[bktIndex].channels[j].passive =
5077 nla_get_u8(channel[
5078 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
5079 hddLog(LOG1, FL("Chnl spec passive %u"),
5080 pReqMsg->buckets[bktIndex].channels[j].passive);
5081
5082 j++;
5083 }
5084
5085 bktIndex++;
5086 }
5087
5088 return 0;
5089}
5090
5091
5092/*
5093 * define short names for the global vendor params
5094 * used by wlan_hdd_cfg80211_extscan_start()
5095 */
5096#define PARAM_MAX \
5097QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
5098#define PARAM_REQUEST_ID \
5099QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
5100#define PARAM_BASE_PERIOD \
5101QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
5102#define PARAM_MAX_AP_PER_SCAN \
5103QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
5104#define PARAM_RPT_THRHLD_PERCENT \
5105QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
5106#define PARAM_RPT_THRHLD_NUM_SCANS \
5107QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
5108#define PARAM_NUM_BUCKETS \
5109QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
5110
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305111static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305112 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305113 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305114{
Dino Myclee8843b32014-07-04 14:21:45 +05305115 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305116 struct net_device *dev = wdev->netdev;
5117 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5118 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5119 struct nlattr *tb[PARAM_MAX + 1];
5120 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305121 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305122 tANI_U32 request_id;
5123 struct hdd_ext_scan_context *context;
5124 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305125
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305126 ENTER();
5127
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305128 if (VOS_FTM_MODE == hdd_get_conparam()) {
5129 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5130 return -EINVAL;
5131 }
5132
Dino Mycle6fb96c12014-06-10 11:52:40 +05305133 status = wlan_hdd_validate_context(pHddCtx);
5134 if (0 != status)
5135 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305136 return -EINVAL;
5137 }
Dino Myclee8843b32014-07-04 14:21:45 +05305138 /* check the EXTScan Capability */
5139 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305140 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5141 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305142 {
5143 hddLog(VOS_TRACE_LEVEL_ERROR,
5144 FL("EXTScan not enabled/supported by Firmware"));
5145 return -EINVAL;
5146 }
5147
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305148 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305149 data, dataLen,
5150 wlan_hdd_extscan_config_policy)) {
5151 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5152 return -EINVAL;
5153 }
5154
5155 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305156 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305157 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5158 return -EINVAL;
5159 }
5160
Dino Myclee8843b32014-07-04 14:21:45 +05305161 pReqMsg = (tpSirEXTScanStartReqParams)
5162 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305163 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305164 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5165 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305166 }
5167
5168 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305169 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305170 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5171
5172 pReqMsg->sessionId = pAdapter->sessionId;
5173 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5174
5175 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305176 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305177 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5178 goto fail;
5179 }
5180 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305181 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305182 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5183 pReqMsg->basePeriod);
5184
5185 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305186 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305187 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5188 goto fail;
5189 }
5190 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305191 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305192 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5193 pReqMsg->maxAPperScan);
5194
5195 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305196 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305197 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5198 goto fail;
5199 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305200 pReqMsg->reportThresholdPercent = nla_get_u8(
5201 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305202 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305203 pReqMsg->reportThresholdPercent);
5204
5205 /* Parse and fetch report threshold num scans */
5206 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5207 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5208 goto fail;
5209 }
5210 pReqMsg->reportThresholdNumScans = nla_get_u8(
5211 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5212 hddLog(LOG1, FL("Report Threshold num scans %d"),
5213 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305214
5215 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305216 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305217 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5218 goto fail;
5219 }
5220 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305221 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305222 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5223 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5224 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5225 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5226 }
5227 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5228 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305229
Dino Mycle6fb96c12014-06-10 11:52:40 +05305230 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5231 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5232 goto fail;
5233 }
5234
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305235 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305236
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305237 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5238 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305239
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305240 context = &pHddCtx->ext_scan_context;
5241 spin_lock(&hdd_context_lock);
5242 INIT_COMPLETION(context->response_event);
5243 context->request_id = request_id = pReqMsg->requestId;
5244 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305245
Dino Mycle6fb96c12014-06-10 11:52:40 +05305246 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5247 if (!HAL_STATUS_SUCCESS(status)) {
5248 hddLog(VOS_TRACE_LEVEL_ERROR,
5249 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305250 goto fail;
5251 }
5252
Srinivas Dasari91727c12016-03-23 17:59:06 +05305253 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5254
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305255 /* request was sent -- wait for the response */
5256 rc = wait_for_completion_timeout(&context->response_event,
5257 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5258
5259 if (!rc) {
5260 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5261 retval = -ETIMEDOUT;
5262 } else {
5263 spin_lock(&hdd_context_lock);
5264 if (context->request_id == request_id)
5265 retval = context->response_status;
5266 else
5267 retval = -EINVAL;
5268 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305269 }
5270
Dino Myclee8843b32014-07-04 14:21:45 +05305271 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305272 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305273 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305274
5275fail:
5276 vos_mem_free(pReqMsg);
5277 return -EINVAL;
5278}
5279
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305280/*
5281 * done with short names for the global vendor params
5282 * used by wlan_hdd_cfg80211_extscan_start()
5283 */
5284#undef PARAM_MAX
5285#undef PARAM_REQUEST_ID
5286#undef PARAM_BASE_PERIOD
5287#undef PARAMS_MAX_AP_PER_SCAN
5288#undef PARAMS_RPT_THRHLD_PERCENT
5289#undef PARAMS_RPT_THRHLD_NUM_SCANS
5290#undef PARAMS_NUM_BUCKETS
5291
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305292static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5293 struct wireless_dev *wdev,
5294 const void *data, int dataLen)
5295{
5296 int ret = 0;
5297
5298 vos_ssr_protect(__func__);
5299 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5300 vos_ssr_unprotect(__func__);
5301
5302 return ret;
5303}
5304
5305static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305306 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305307 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305308{
Dino Myclee8843b32014-07-04 14:21:45 +05305309 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305310 struct net_device *dev = wdev->netdev;
5311 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5312 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5313 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5314 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305315 int retval;
5316 unsigned long rc;
5317 struct hdd_ext_scan_context *context;
5318 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305319
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305320 ENTER();
5321
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305322 if (VOS_FTM_MODE == hdd_get_conparam()) {
5323 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5324 return -EINVAL;
5325 }
5326
Dino Mycle6fb96c12014-06-10 11:52:40 +05305327 status = wlan_hdd_validate_context(pHddCtx);
5328 if (0 != status)
5329 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305330 return -EINVAL;
5331 }
Dino Myclee8843b32014-07-04 14:21:45 +05305332 /* check the EXTScan Capability */
5333 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305334 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5335 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305336 {
5337 hddLog(VOS_TRACE_LEVEL_ERROR,
5338 FL("EXTScan not enabled/supported by Firmware"));
5339 return -EINVAL;
5340 }
5341
Dino Mycle6fb96c12014-06-10 11:52:40 +05305342 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5343 data, dataLen,
5344 wlan_hdd_extscan_config_policy)) {
5345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5346 return -EINVAL;
5347 }
5348
5349 /* Parse and fetch request Id */
5350 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5352 return -EINVAL;
5353 }
5354
Dino Myclee8843b32014-07-04 14:21:45 +05305355 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305356 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305357 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305358
Dino Myclee8843b32014-07-04 14:21:45 +05305359 reqMsg.sessionId = pAdapter->sessionId;
5360 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305361
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305362 context = &pHddCtx->ext_scan_context;
5363 spin_lock(&hdd_context_lock);
5364 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305365 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305366 spin_unlock(&hdd_context_lock);
5367
Dino Myclee8843b32014-07-04 14:21:45 +05305368 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305369 if (!HAL_STATUS_SUCCESS(status)) {
5370 hddLog(VOS_TRACE_LEVEL_ERROR,
5371 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305372 return -EINVAL;
5373 }
5374
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305375 /* request was sent -- wait for the response */
5376 rc = wait_for_completion_timeout(&context->response_event,
5377 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5378
5379 if (!rc) {
5380 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5381 retval = -ETIMEDOUT;
5382 } else {
5383 spin_lock(&hdd_context_lock);
5384 if (context->request_id == request_id)
5385 retval = context->response_status;
5386 else
5387 retval = -EINVAL;
5388 spin_unlock(&hdd_context_lock);
5389 }
5390
5391 return retval;
5392
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305393 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305394 return 0;
5395}
5396
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305397static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5398 struct wireless_dev *wdev,
5399 const void *data, int dataLen)
5400{
5401 int ret = 0;
5402
5403 vos_ssr_protect(__func__);
5404 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5405 vos_ssr_unprotect(__func__);
5406
5407 return ret;
5408}
5409
5410static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305411 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305412 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305413{
Dino Myclee8843b32014-07-04 14:21:45 +05305414 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305415 struct net_device *dev = wdev->netdev;
5416 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5417 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5418 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5419 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305420 struct hdd_ext_scan_context *context;
5421 tANI_U32 request_id;
5422 unsigned long rc;
5423 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305424
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305425 ENTER();
5426
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305427 if (VOS_FTM_MODE == hdd_get_conparam()) {
5428 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5429 return -EINVAL;
5430 }
5431
Dino Mycle6fb96c12014-06-10 11:52:40 +05305432 status = wlan_hdd_validate_context(pHddCtx);
5433 if (0 != status)
5434 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305435 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305436 return -EINVAL;
5437 }
Dino Myclee8843b32014-07-04 14:21:45 +05305438 /* check the EXTScan Capability */
5439 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305440 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5441 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305442 {
5443 hddLog(VOS_TRACE_LEVEL_ERROR,
5444 FL("EXTScan not enabled/supported by Firmware"));
5445 return -EINVAL;
5446 }
5447
Dino Mycle6fb96c12014-06-10 11:52:40 +05305448 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5449 data, dataLen,
5450 wlan_hdd_extscan_config_policy)) {
5451 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5452 return -EINVAL;
5453 }
5454
5455 /* Parse and fetch request Id */
5456 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5458 return -EINVAL;
5459 }
5460
Dino Myclee8843b32014-07-04 14:21:45 +05305461 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305462 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305463 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305464
Dino Myclee8843b32014-07-04 14:21:45 +05305465 reqMsg.sessionId = pAdapter->sessionId;
5466 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305467
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305468 context = &pHddCtx->ext_scan_context;
5469 spin_lock(&hdd_context_lock);
5470 INIT_COMPLETION(context->response_event);
5471 context->request_id = request_id = reqMsg.requestId;
5472 spin_unlock(&hdd_context_lock);
5473
Dino Myclee8843b32014-07-04 14:21:45 +05305474 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305475 if (!HAL_STATUS_SUCCESS(status)) {
5476 hddLog(VOS_TRACE_LEVEL_ERROR,
5477 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305478 return -EINVAL;
5479 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305480
5481 /* request was sent -- wait for the response */
5482 rc = wait_for_completion_timeout(&context->response_event,
5483 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5484 if (!rc) {
5485 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5486 retval = -ETIMEDOUT;
5487 } else {
5488 spin_lock(&hdd_context_lock);
5489 if (context->request_id == request_id)
5490 retval = context->response_status;
5491 else
5492 retval = -EINVAL;
5493 spin_unlock(&hdd_context_lock);
5494 }
5495
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305496 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305497 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305498}
5499
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305500static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5501 struct wireless_dev *wdev,
5502 const void *data, int dataLen)
5503{
5504 int ret = 0;
5505
5506 vos_ssr_protect(__func__);
5507 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5508 vos_ssr_unprotect(__func__);
5509
5510 return ret;
5511}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305512#endif /* WLAN_FEATURE_EXTSCAN */
5513
Atul Mittal115287b2014-07-08 13:26:33 +05305514/*EXT TDLS*/
5515static const struct nla_policy
5516wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5517{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305518 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5519 .type = NLA_UNSPEC,
5520 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305521 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5522 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5523 {.type = NLA_S32 },
5524 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5525 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5526
5527};
5528
5529static const struct nla_policy
5530wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5531{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305532 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5533 .type = NLA_UNSPEC,
5534 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305535
5536};
5537
5538static const struct nla_policy
5539wlan_hdd_tdls_config_state_change_policy[
5540 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5541{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305542 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5543 .type = NLA_UNSPEC,
5544 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305545 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5546 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305547 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5548 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5549 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305550
5551};
5552
5553static const struct nla_policy
5554wlan_hdd_tdls_config_get_status_policy[
5555 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5556{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305557 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5558 .type = NLA_UNSPEC,
5559 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305560 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5561 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305562 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5563 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5564 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305565
5566};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305567
5568static const struct nla_policy
5569wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5570{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305571 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5572 .type = NLA_UNSPEC,
5573 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305574};
5575
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305576static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305577 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305578 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305579 int data_len)
5580{
5581
5582 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5583 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5584
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305585 ENTER();
5586
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305587 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305588 return -EINVAL;
5589 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305590 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305591 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305592 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305593 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305594 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305595 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305596 return -ENOTSUPP;
5597 }
5598
5599 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5600 data, data_len, wlan_hdd_mac_config)) {
5601 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5602 return -EINVAL;
5603 }
5604
5605 /* Parse and fetch mac address */
5606 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5607 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5608 return -EINVAL;
5609 }
5610
5611 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5612 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5613 VOS_MAC_ADDR_LAST_3_BYTES);
5614
Siddharth Bhal76972212014-10-15 16:22:51 +05305615 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5616
5617 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305618 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5619 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305620 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5621 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5622 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5623 {
5624 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5625 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5626 VOS_MAC_ADDRESS_LEN);
5627 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305628 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305629
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305630 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5631 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305632
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305633 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305634 return 0;
5635}
5636
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305637static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5638 struct wireless_dev *wdev,
5639 const void *data,
5640 int data_len)
5641{
5642 int ret = 0;
5643
5644 vos_ssr_protect(__func__);
5645 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5646 vos_ssr_unprotect(__func__);
5647
5648 return ret;
5649}
5650
5651static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305652 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305653 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305654 int data_len)
5655{
5656 u8 peer[6] = {0};
5657 struct net_device *dev = wdev->netdev;
5658 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5659 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5660 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5661 eHalStatus ret;
5662 tANI_S32 state;
5663 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305664 tANI_S32 global_operating_class = 0;
5665 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305666 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305667 int retVal;
5668
5669 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305670
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305671 if (!pAdapter) {
5672 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5673 return -EINVAL;
5674 }
5675
Atul Mittal115287b2014-07-08 13:26:33 +05305676 ret = wlan_hdd_validate_context(pHddCtx);
5677 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305678 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305679 return -EINVAL;
5680 }
5681 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305682 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305683 return -ENOTSUPP;
5684 }
5685 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5686 data, data_len,
5687 wlan_hdd_tdls_config_get_status_policy)) {
5688 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5689 return -EINVAL;
5690 }
5691
5692 /* Parse and fetch mac address */
5693 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5695 return -EINVAL;
5696 }
5697
5698 memcpy(peer, nla_data(
5699 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5700 sizeof(peer));
5701 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5702
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305703 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305704
Atul Mittal115287b2014-07-08 13:26:33 +05305705 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305706 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305707 NLMSG_HDRLEN);
5708
5709 if (!skb) {
5710 hddLog(VOS_TRACE_LEVEL_ERROR,
5711 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5712 return -EINVAL;
5713 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305714 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05305715 reason,
5716 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305717 global_operating_class,
5718 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305719 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305720 if (nla_put_s32(skb,
5721 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5722 state) ||
5723 nla_put_s32(skb,
5724 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5725 reason) ||
5726 nla_put_s32(skb,
5727 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5728 global_operating_class) ||
5729 nla_put_s32(skb,
5730 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5731 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305732
5733 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5734 goto nla_put_failure;
5735 }
5736
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305737 retVal = cfg80211_vendor_cmd_reply(skb);
5738 EXIT();
5739 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305740
5741nla_put_failure:
5742 kfree_skb(skb);
5743 return -EINVAL;
5744}
5745
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305746static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5747 struct wireless_dev *wdev,
5748 const void *data,
5749 int data_len)
5750{
5751 int ret = 0;
5752
5753 vos_ssr_protect(__func__);
5754 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5755 vos_ssr_unprotect(__func__);
5756
5757 return ret;
5758}
5759
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305760static int wlan_hdd_cfg80211_exttdls_callback(
5761#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5762 const tANI_U8* mac,
5763#else
5764 tANI_U8* mac,
5765#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305766 tANI_S32 state,
5767 tANI_S32 reason,
5768 void *ctx)
5769{
5770 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305771 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305772 tANI_S32 global_operating_class = 0;
5773 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305774 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305775
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305776 ENTER();
5777
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305778 if (!pAdapter) {
5779 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5780 return -EINVAL;
5781 }
5782
5783 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305784 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305785 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305786 return -EINVAL;
5787 }
5788
5789 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305791 return -ENOTSUPP;
5792 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305793 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5794#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5795 NULL,
5796#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305797 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5798 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5799 GFP_KERNEL);
5800
5801 if (!skb) {
5802 hddLog(VOS_TRACE_LEVEL_ERROR,
5803 FL("cfg80211_vendor_event_alloc failed"));
5804 return -EINVAL;
5805 }
5806 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305807 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5808 reason,
5809 state,
5810 global_operating_class,
5811 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305812 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5813 MAC_ADDR_ARRAY(mac));
5814
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305815 if (nla_put(skb,
5816 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5817 VOS_MAC_ADDR_SIZE, mac) ||
5818 nla_put_s32(skb,
5819 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5820 state) ||
5821 nla_put_s32(skb,
5822 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5823 reason) ||
5824 nla_put_s32(skb,
5825 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5826 channel) ||
5827 nla_put_s32(skb,
5828 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5829 global_operating_class)
5830 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305831 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5832 goto nla_put_failure;
5833 }
5834
5835 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305836 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305837 return (0);
5838
5839nla_put_failure:
5840 kfree_skb(skb);
5841 return -EINVAL;
5842}
5843
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305844static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305845 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305846 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305847 int data_len)
5848{
5849 u8 peer[6] = {0};
5850 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305851 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5852 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5853 eHalStatus status;
5854 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305855 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305856 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305857
5858 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305859
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305860 if (!dev) {
5861 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5862 return -EINVAL;
5863 }
5864
5865 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5866 if (!pAdapter) {
5867 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5868 return -EINVAL;
5869 }
5870
Atul Mittal115287b2014-07-08 13:26:33 +05305871 status = wlan_hdd_validate_context(pHddCtx);
5872 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305873 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305874 return -EINVAL;
5875 }
5876 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305877 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305878 return -ENOTSUPP;
5879 }
5880 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5881 data, data_len,
5882 wlan_hdd_tdls_config_enable_policy)) {
5883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5884 return -EINVAL;
5885 }
5886
5887 /* Parse and fetch mac address */
5888 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5890 return -EINVAL;
5891 }
5892
5893 memcpy(peer, nla_data(
5894 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5895 sizeof(peer));
5896 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5897
5898 /* Parse and fetch channel */
5899 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5900 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5901 return -EINVAL;
5902 }
5903 pReqMsg.channel = nla_get_s32(
5904 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5905 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5906
5907 /* Parse and fetch global operating class */
5908 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5909 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5910 return -EINVAL;
5911 }
5912 pReqMsg.global_operating_class = nla_get_s32(
5913 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5914 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5915 pReqMsg.global_operating_class);
5916
5917 /* Parse and fetch latency ms */
5918 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5919 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5920 return -EINVAL;
5921 }
5922 pReqMsg.max_latency_ms = nla_get_s32(
5923 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5924 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5925 pReqMsg.max_latency_ms);
5926
5927 /* Parse and fetch required bandwidth kbps */
5928 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5929 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5930 return -EINVAL;
5931 }
5932
5933 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5934 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5935 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5936 pReqMsg.min_bandwidth_kbps);
5937
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305938 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305939 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305940 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305941 wlan_hdd_cfg80211_exttdls_callback);
5942
5943 EXIT();
5944 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305945}
5946
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305947static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5948 struct wireless_dev *wdev,
5949 const void *data,
5950 int data_len)
5951{
5952 int ret = 0;
5953
5954 vos_ssr_protect(__func__);
5955 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5956 vos_ssr_unprotect(__func__);
5957
5958 return ret;
5959}
5960
5961static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305962 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305963 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305964 int data_len)
5965{
5966 u8 peer[6] = {0};
5967 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305968 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5969 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5970 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305971 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305972 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305973
5974 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305975
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305976 if (!dev) {
5977 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5978 return -EINVAL;
5979 }
5980
5981 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5982 if (!pAdapter) {
5983 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5984 return -EINVAL;
5985 }
5986
Atul Mittal115287b2014-07-08 13:26:33 +05305987 status = wlan_hdd_validate_context(pHddCtx);
5988 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305989 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305990 return -EINVAL;
5991 }
5992 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305994 return -ENOTSUPP;
5995 }
5996 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5997 data, data_len,
5998 wlan_hdd_tdls_config_disable_policy)) {
5999 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6000 return -EINVAL;
6001 }
6002 /* Parse and fetch mac address */
6003 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
6004 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
6005 return -EINVAL;
6006 }
6007
6008 memcpy(peer, nla_data(
6009 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
6010 sizeof(peer));
6011 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
6012
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306013 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
6014
6015 EXIT();
6016 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05306017}
6018
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306019static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
6020 struct wireless_dev *wdev,
6021 const void *data,
6022 int data_len)
6023{
6024 int ret = 0;
6025
6026 vos_ssr_protect(__func__);
6027 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
6028 vos_ssr_unprotect(__func__);
6029
6030 return ret;
6031}
6032
Dasari Srinivas7875a302014-09-26 17:50:57 +05306033static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306034__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05306035 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306036 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05306037{
6038 struct net_device *dev = wdev->netdev;
6039 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6040 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6041 struct sk_buff *skb = NULL;
6042 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306043 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306044
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306045 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306046
6047 ret = wlan_hdd_validate_context(pHddCtx);
6048 if (0 != ret)
6049 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306050 return ret;
6051 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306052 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
6053 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
6054 fset |= WIFI_FEATURE_INFRA;
6055 }
6056
6057 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
6058 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
6059 fset |= WIFI_FEATURE_INFRA_5G;
6060 }
6061
6062#ifdef WLAN_FEATURE_P2P
6063 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
6064 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
6065 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
6066 fset |= WIFI_FEATURE_P2P;
6067 }
6068#endif
6069
6070 /* Soft-AP is supported currently by default */
6071 fset |= WIFI_FEATURE_SOFT_AP;
6072
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05306073 /* HOTSPOT is a supplicant feature, enable it by default */
6074 fset |= WIFI_FEATURE_HOTSPOT;
6075
Dasari Srinivas7875a302014-09-26 17:50:57 +05306076#ifdef WLAN_FEATURE_EXTSCAN
6077 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05306078 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
6079 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
6080 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306081 fset |= WIFI_FEATURE_EXTSCAN;
6082 }
6083#endif
6084
Dasari Srinivas7875a302014-09-26 17:50:57 +05306085 if (sme_IsFeatureSupportedByFW(NAN)) {
6086 hddLog(LOG1, FL("NAN is supported by firmware"));
6087 fset |= WIFI_FEATURE_NAN;
6088 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306089
6090 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05306091 if (sme_IsFeatureSupportedByFW(RTT) &&
6092 pHddCtx->cfg_ini->enable_rtt_support) {
6093 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306094 fset |= WIFI_FEATURE_D2AP_RTT;
6095 }
6096
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05306097 if (sme_IsFeatureSupportedByFW(RTT3)) {
6098 hddLog(LOG1, FL("RTT3 is supported by firmware"));
6099 fset |= WIFI_FEATURE_RTT3;
6100 }
6101
Dasari Srinivas7875a302014-09-26 17:50:57 +05306102#ifdef FEATURE_WLAN_BATCH_SCAN
6103 if (fset & WIFI_FEATURE_EXTSCAN) {
6104 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
6105 fset &= ~WIFI_FEATURE_BATCH_SCAN;
6106 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
6107 hddLog(LOG1, FL("Batch scan is supported by firmware"));
6108 fset |= WIFI_FEATURE_BATCH_SCAN;
6109 }
6110#endif
6111
6112#ifdef FEATURE_WLAN_SCAN_PNO
6113 if (pHddCtx->cfg_ini->configPNOScanSupport &&
6114 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
6115 hddLog(LOG1, FL("PNO is supported by firmware"));
6116 fset |= WIFI_FEATURE_PNO;
6117 }
6118#endif
6119
6120 /* STA+STA is supported currently by default */
6121 fset |= WIFI_FEATURE_ADDITIONAL_STA;
6122
6123#ifdef FEATURE_WLAN_TDLS
6124 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6125 sme_IsFeatureSupportedByFW(TDLS)) {
6126 hddLog(LOG1, FL("TDLS is supported by firmware"));
6127 fset |= WIFI_FEATURE_TDLS;
6128 }
6129
6130 /* TDLS_OFFCHANNEL is not supported currently by default */
6131#endif
6132
6133#ifdef WLAN_AP_STA_CONCURRENCY
6134 /* AP+STA concurrency is supported currently by default */
6135 fset |= WIFI_FEATURE_AP_STA;
6136#endif
6137
Mukul Sharma5add0532015-08-17 15:57:47 +05306138#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306139 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6140 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306141 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6142 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306143 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306144#endif
6145
Dasari Srinivas7875a302014-09-26 17:50:57 +05306146 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6147 NLMSG_HDRLEN);
6148
6149 if (!skb) {
6150 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6151 return -EINVAL;
6152 }
6153 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6154
6155 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6156 hddLog(LOGE, FL("nla put fail"));
6157 goto nla_put_failure;
6158 }
6159
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306160 ret = cfg80211_vendor_cmd_reply(skb);
6161 EXIT();
6162 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306163
6164nla_put_failure:
6165 kfree_skb(skb);
6166 return -EINVAL;
6167}
6168
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306169static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306170wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6171 struct wireless_dev *wdev,
6172 const void *data, int data_len)
6173{
6174 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306175 vos_ssr_protect(__func__);
6176 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6177 vos_ssr_unprotect(__func__);
6178
6179 return ret;
6180}
6181
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306182
6183static const struct
6184nla_policy
6185qca_wlan_vendor_wifi_logger_get_ring_data_policy
6186[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6187 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6188 = {.type = NLA_U32 },
6189};
6190
6191static int
6192 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6193 struct wireless_dev *wdev,
6194 const void *data,
6195 int data_len)
6196{
6197 int ret;
6198 VOS_STATUS status;
6199 uint32_t ring_id;
6200 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6201 struct nlattr *tb
6202 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6203
6204 ENTER();
6205
6206 ret = wlan_hdd_validate_context(hdd_ctx);
6207 if (0 != ret) {
6208 return ret;
6209 }
6210
6211 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6212 data, data_len,
6213 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6214 hddLog(LOGE, FL("Invalid attribute"));
6215 return -EINVAL;
6216 }
6217
6218 /* Parse and fetch ring id */
6219 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6220 hddLog(LOGE, FL("attr ATTR failed"));
6221 return -EINVAL;
6222 }
6223
6224 ring_id = nla_get_u32(
6225 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6226
6227 hddLog(LOG1, FL("Bug report triggered by framework"));
6228
6229 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6230 WLAN_LOG_INDICATOR_FRAMEWORK,
6231 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306232 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306233 );
6234 if (VOS_STATUS_SUCCESS != status) {
6235 hddLog(LOGE, FL("Failed to trigger bug report"));
6236
6237 return -EINVAL;
6238 }
6239
6240 return 0;
6241
6242
6243}
6244
6245
6246static int
6247 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6248 struct wireless_dev *wdev,
6249 const void *data,
6250 int data_len)
6251{
6252 int ret = 0;
6253
6254 vos_ssr_protect(__func__);
6255 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6256 wdev, data, data_len);
6257 vos_ssr_unprotect(__func__);
6258
6259 return ret;
6260
6261}
6262
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306263#define MAX_CONCURRENT_MATRIX \
6264 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6265#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6266 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6267static const struct nla_policy
6268wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6269 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6270};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306271
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306272static int
6273__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306274 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306275 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306276{
6277 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6278 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306279 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306280 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306281 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6282 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306283
6284 ENTER();
6285
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306286 ret = wlan_hdd_validate_context(pHddCtx);
6287 if (0 != ret)
6288 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306289 return ret;
6290 }
6291
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306292 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6293 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306294 hddLog(LOGE, FL("Invalid ATTR"));
6295 return -EINVAL;
6296 }
6297
6298 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306299 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306300 hddLog(LOGE, FL("Attr max feature set size failed"));
6301 return -EINVAL;
6302 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306303 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306304 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6305
6306 /* Fill feature combination matrix */
6307 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306308 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6309 WIFI_FEATURE_P2P;
6310
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306311 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6312 WIFI_FEATURE_SOFT_AP;
6313
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306314 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6315 WIFI_FEATURE_SOFT_AP;
6316
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306317 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6318 WIFI_FEATURE_SOFT_AP |
6319 WIFI_FEATURE_P2P;
6320
6321 /* Add more feature combinations here */
6322
6323 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6324 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6325 hddLog(LOG1, "Feature set matrix");
6326 for (i = 0; i < feature_sets; i++)
6327 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6328
6329 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6330 sizeof(u32) * feature_sets +
6331 NLMSG_HDRLEN);
6332
6333 if (reply_skb) {
6334 if (nla_put_u32(reply_skb,
6335 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6336 feature_sets) ||
6337 nla_put(reply_skb,
6338 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6339 sizeof(u32) * feature_sets, feature_set_matrix)) {
6340 hddLog(LOGE, FL("nla put fail"));
6341 kfree_skb(reply_skb);
6342 return -EINVAL;
6343 }
6344
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306345 ret = cfg80211_vendor_cmd_reply(reply_skb);
6346 EXIT();
6347 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306348 }
6349 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6350 return -ENOMEM;
6351
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306352}
6353
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306354#undef MAX_CONCURRENT_MATRIX
6355#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6356
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306357static int
6358wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6359 struct wireless_dev *wdev,
6360 const void *data, int data_len)
6361{
6362 int ret = 0;
6363
6364 vos_ssr_protect(__func__);
6365 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6366 data_len);
6367 vos_ssr_unprotect(__func__);
6368
6369 return ret;
6370}
6371
c_manjeecfd1efb2015-09-25 19:32:34 +05306372
6373static int
6374__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6375 struct wireless_dev *wdev,
6376 const void *data, int data_len)
6377{
6378 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6379 int ret;
6380 ENTER();
6381
6382 ret = wlan_hdd_validate_context(pHddCtx);
6383 if (0 != ret)
6384 {
6385 return ret;
6386 }
6387
6388 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6389 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6390 {
6391 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306392 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306393 }
6394 /*call common API for FW mem dump req*/
6395 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6396
Abhishek Singhc783fa72015-12-09 18:07:34 +05306397 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306398 {
6399 /*indicate to userspace the status of fw mem dump */
6400 wlan_indicate_mem_dump_complete(true);
6401 }
6402 else
6403 {
6404 /*else send failure to userspace */
6405 wlan_indicate_mem_dump_complete(false);
6406 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306407 EXIT();
6408 return ret;
6409}
6410
6411/**
6412 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6413 * @wiphy: pointer to wireless wiphy structure.
6414 * @wdev: pointer to wireless_dev structure.
6415 * @data: Pointer to the NL data.
6416 * @data_len:Length of @data
6417 *
6418 * This is called when wlan driver needs to get the firmware memory dump
6419 * via vendor specific command.
6420 *
6421 * Return: 0 on success, error number otherwise.
6422 */
6423
6424static int
6425wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6426 struct wireless_dev *wdev,
6427 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306428{
6429 int ret = 0;
6430 vos_ssr_protect(__func__);
6431 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6432 data_len);
6433 vos_ssr_unprotect(__func__);
6434 return ret;
6435}
c_manjeecfd1efb2015-09-25 19:32:34 +05306436
Sushant Kaushik8e644982015-09-23 12:18:54 +05306437static const struct
6438nla_policy
6439qca_wlan_vendor_wifi_logger_start_policy
6440[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6441 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6442 = {.type = NLA_U32 },
6443 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6444 = {.type = NLA_U32 },
6445 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6446 = {.type = NLA_U32 },
6447};
6448
6449/**
6450 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6451 * or disable the collection of packet statistics from the firmware
6452 * @wiphy: WIPHY structure pointer
6453 * @wdev: Wireless device structure pointer
6454 * @data: Pointer to the data received
6455 * @data_len: Length of the data received
6456 *
6457 * This function is used to enable or disable the collection of packet
6458 * statistics from the firmware
6459 *
6460 * Return: 0 on success and errno on failure
6461 */
6462static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6463 struct wireless_dev *wdev,
6464 const void *data,
6465 int data_len)
6466{
6467 eHalStatus status;
6468 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6469 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6470 tAniWifiStartLog start_log;
6471
6472 status = wlan_hdd_validate_context(hdd_ctx);
6473 if (0 != status) {
6474 return -EINVAL;
6475 }
6476
6477 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6478 data, data_len,
6479 qca_wlan_vendor_wifi_logger_start_policy)) {
6480 hddLog(LOGE, FL("Invalid attribute"));
6481 return -EINVAL;
6482 }
6483
6484 /* Parse and fetch ring id */
6485 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6486 hddLog(LOGE, FL("attr ATTR failed"));
6487 return -EINVAL;
6488 }
6489 start_log.ringId = nla_get_u32(
6490 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6491 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6492
6493 /* Parse and fetch verbose level */
6494 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6495 hddLog(LOGE, FL("attr verbose_level failed"));
6496 return -EINVAL;
6497 }
6498 start_log.verboseLevel = nla_get_u32(
6499 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6500 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6501
6502 /* Parse and fetch flag */
6503 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6504 hddLog(LOGE, FL("attr flag failed"));
6505 return -EINVAL;
6506 }
6507 start_log.flag = nla_get_u32(
6508 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6509 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6510
6511 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306512 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6513 !vos_isPktStatsEnabled()))
6514
Sushant Kaushik8e644982015-09-23 12:18:54 +05306515 {
6516 hddLog(LOGE, FL("per pkt stats not enabled"));
6517 return -EINVAL;
6518 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306519
Sushant Kaushik33200572015-08-05 16:46:20 +05306520 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306521 return 0;
6522}
6523
6524/**
6525 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6526 * or disable the collection of packet statistics from the firmware
6527 * @wiphy: WIPHY structure pointer
6528 * @wdev: Wireless device structure pointer
6529 * @data: Pointer to the data received
6530 * @data_len: Length of the data received
6531 *
6532 * This function is used to enable or disable the collection of packet
6533 * statistics from the firmware
6534 *
6535 * Return: 0 on success and errno on failure
6536 */
6537static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6538 struct wireless_dev *wdev,
6539 const void *data,
6540 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306541{
6542 int ret = 0;
6543
6544 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306545
6546 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6547 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306548 vos_ssr_unprotect(__func__);
6549
6550 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306551}
6552
6553
Agarwal Ashish738843c2014-09-25 12:27:56 +05306554static const struct nla_policy
6555wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6556 +1] =
6557{
6558 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6559};
6560
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306561static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306562 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306563 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306564 int data_len)
6565{
6566 struct net_device *dev = wdev->netdev;
6567 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6568 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6569 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6570 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6571 eHalStatus status;
6572 u32 dfsFlag = 0;
6573
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306574 ENTER();
6575
Agarwal Ashish738843c2014-09-25 12:27:56 +05306576 status = wlan_hdd_validate_context(pHddCtx);
6577 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306578 return -EINVAL;
6579 }
6580 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6581 data, data_len,
6582 wlan_hdd_set_no_dfs_flag_config_policy)) {
6583 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6584 return -EINVAL;
6585 }
6586
6587 /* Parse and fetch required bandwidth kbps */
6588 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6589 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6590 return -EINVAL;
6591 }
6592
6593 dfsFlag = nla_get_u32(
6594 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6595 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6596 dfsFlag);
6597
6598 pHddCtx->disable_dfs_flag = dfsFlag;
6599
6600 sme_disable_dfs_channel(hHal, dfsFlag);
6601 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306602
6603 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306604 return 0;
6605}
Atul Mittal115287b2014-07-08 13:26:33 +05306606
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306607static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6608 struct wireless_dev *wdev,
6609 const void *data,
6610 int data_len)
6611{
6612 int ret = 0;
6613
6614 vos_ssr_protect(__func__);
6615 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6616 vos_ssr_unprotect(__func__);
6617
6618 return ret;
6619
6620}
6621
Mukul Sharma2a271632014-10-13 14:59:01 +05306622const struct
6623nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6624{
6625 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306626 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6627 .type = NLA_UNSPEC,
6628 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306629};
6630
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306631static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306632 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306633{
6634
6635 u8 bssid[6] = {0};
6636 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6637 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6638 eHalStatus status = eHAL_STATUS_SUCCESS;
6639 v_U32_t isFwrRoamEnabled = FALSE;
6640 int ret;
6641
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306642 ENTER();
6643
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306644 ret = wlan_hdd_validate_context(pHddCtx);
6645 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306646 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306647 }
6648
6649 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6650 data, data_len,
6651 qca_wlan_vendor_attr);
6652 if (ret){
6653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6654 return -EINVAL;
6655 }
6656
6657 /* Parse and fetch Enable flag */
6658 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6660 return -EINVAL;
6661 }
6662
6663 isFwrRoamEnabled = nla_get_u32(
6664 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6665
6666 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6667
6668 /* Parse and fetch bssid */
6669 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6670 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6671 return -EINVAL;
6672 }
6673
6674 memcpy(bssid, nla_data(
6675 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6676 sizeof(bssid));
6677 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6678
6679 //Update roaming
6680 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306681 if (!HAL_STATUS_SUCCESS(status)) {
6682 hddLog(LOGE,
6683 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6684 return -EINVAL;
6685 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306686 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306687 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306688}
6689
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306690static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6691 struct wireless_dev *wdev, const void *data, int data_len)
6692{
6693 int ret = 0;
6694
6695 vos_ssr_protect(__func__);
6696 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6697 vos_ssr_unprotect(__func__);
6698
6699 return ret;
6700}
6701
Sushant Kaushik847890c2015-09-28 16:05:17 +05306702static const struct
6703nla_policy
6704qca_wlan_vendor_get_wifi_info_policy[
6705 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6706 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6707 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6708};
6709
6710
6711/**
6712 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6713 * @wiphy: pointer to wireless wiphy structure.
6714 * @wdev: pointer to wireless_dev structure.
6715 * @data: Pointer to the data to be passed via vendor interface
6716 * @data_len:Length of the data to be passed
6717 *
6718 * This is called when wlan driver needs to send wifi driver related info
6719 * (driver/fw version) to the user space application upon request.
6720 *
6721 * Return: Return the Success or Failure code.
6722 */
6723static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6724 struct wireless_dev *wdev,
6725 const void *data, int data_len)
6726{
6727 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6728 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6729 tSirVersionString version;
6730 uint32 version_len;
6731 uint8 attr;
6732 int status;
6733 struct sk_buff *reply_skb = NULL;
6734
6735 if (VOS_FTM_MODE == hdd_get_conparam()) {
6736 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6737 return -EINVAL;
6738 }
6739
6740 status = wlan_hdd_validate_context(hdd_ctx);
6741 if (0 != status) {
6742 hddLog(LOGE, FL("HDD context is not valid"));
6743 return -EINVAL;
6744 }
6745
6746 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6747 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6748 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6749 return -EINVAL;
6750 }
6751
6752 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6753 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6754 QWLAN_VERSIONSTR);
6755 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6756 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6757 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6758 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6759 hdd_ctx->fw_Version);
6760 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6761 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6762 } else {
6763 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6764 return -EINVAL;
6765 }
6766
6767 version_len = strlen(version);
6768 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6769 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6770 if (!reply_skb) {
6771 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6772 return -ENOMEM;
6773 }
6774
6775 if (nla_put(reply_skb, attr, version_len, version)) {
6776 hddLog(LOGE, FL("nla put fail"));
6777 kfree_skb(reply_skb);
6778 return -EINVAL;
6779 }
6780
6781 return cfg80211_vendor_cmd_reply(reply_skb);
6782}
6783
6784/**
6785 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6786 * @wiphy: pointer to wireless wiphy structure.
6787 * @wdev: pointer to wireless_dev structure.
6788 * @data: Pointer to the data to be passed via vendor interface
6789 * @data_len:Length of the data to be passed
6790 * @data_len: Length of the data received
6791 *
6792 * This function is used to enable or disable the collection of packet
6793 * statistics from the firmware
6794 *
6795 * Return: 0 on success and errno on failure
6796 */
6797
6798static int
6799wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6800 struct wireless_dev *wdev,
6801 const void *data, int data_len)
6802
6803
6804{
6805 int ret = 0;
6806
6807 vos_ssr_protect(__func__);
6808 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6809 wdev, data, data_len);
6810 vos_ssr_unprotect(__func__);
6811
6812 return ret;
6813}
6814
6815
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306816/*
6817 * define short names for the global vendor params
6818 * used by __wlan_hdd_cfg80211_monitor_rssi()
6819 */
6820#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6821#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6822#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6823#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6824#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6825
6826/**---------------------------------------------------------------------------
6827
6828 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6829 monitor start is completed successfully.
6830
6831 \return - None
6832
6833 --------------------------------------------------------------------------*/
6834void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6835{
6836 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6837
6838 if (NULL == pHddCtx)
6839 {
6840 hddLog(VOS_TRACE_LEVEL_ERROR,
6841 "%s: HDD context is NULL",__func__);
6842 return;
6843 }
6844
6845 if (VOS_STATUS_SUCCESS == status)
6846 {
6847 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6848 }
6849 else
6850 {
6851 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6852 }
6853
6854 return;
6855}
6856
6857/**---------------------------------------------------------------------------
6858
6859 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6860 stop is completed successfully.
6861
6862 \return - None
6863
6864 --------------------------------------------------------------------------*/
6865void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6866{
6867 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6868
6869 if (NULL == pHddCtx)
6870 {
6871 hddLog(VOS_TRACE_LEVEL_ERROR,
6872 "%s: HDD context is NULL",__func__);
6873 return;
6874 }
6875
6876 if (VOS_STATUS_SUCCESS == status)
6877 {
6878 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6879 }
6880 else
6881 {
6882 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6883 }
6884
6885 return;
6886}
6887
6888/**
6889 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6890 * @wiphy: Pointer to wireless phy
6891 * @wdev: Pointer to wireless device
6892 * @data: Pointer to data
6893 * @data_len: Data length
6894 *
6895 * Return: 0 on success, negative errno on failure
6896 */
6897
6898static int
6899__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6900 struct wireless_dev *wdev,
6901 const void *data,
6902 int data_len)
6903{
6904 struct net_device *dev = wdev->netdev;
6905 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6906 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6907 hdd_station_ctx_t *pHddStaCtx;
6908 struct nlattr *tb[PARAM_MAX + 1];
6909 tpSirRssiMonitorReq pReq;
6910 eHalStatus status;
6911 int ret;
6912 uint32_t control;
6913 static const struct nla_policy policy[PARAM_MAX + 1] = {
6914 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6915 [PARAM_CONTROL] = { .type = NLA_U32 },
6916 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6917 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6918 };
6919
6920 ENTER();
6921
6922 ret = wlan_hdd_validate_context(hdd_ctx);
6923 if (0 != ret) {
6924 return -EINVAL;
6925 }
6926
6927 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6928 hddLog(LOGE, FL("Not in Connected state!"));
6929 return -ENOTSUPP;
6930 }
6931
6932 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6933 hddLog(LOGE, FL("Invalid ATTR"));
6934 return -EINVAL;
6935 }
6936
6937 if (!tb[PARAM_REQUEST_ID]) {
6938 hddLog(LOGE, FL("attr request id failed"));
6939 return -EINVAL;
6940 }
6941
6942 if (!tb[PARAM_CONTROL]) {
6943 hddLog(LOGE, FL("attr control failed"));
6944 return -EINVAL;
6945 }
6946
6947 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6948
6949 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6950 if(NULL == pReq)
6951 {
6952 hddLog(LOGE,
6953 FL("vos_mem_alloc failed "));
6954 return eHAL_STATUS_FAILED_ALLOC;
6955 }
6956 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6957
6958 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6959 pReq->sessionId = pAdapter->sessionId;
6960 pReq->rssiMonitorCbContext = hdd_ctx;
6961 control = nla_get_u32(tb[PARAM_CONTROL]);
6962 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6963
6964 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6965 pReq->requestId, pReq->sessionId, control);
6966
6967 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6968 if (!tb[PARAM_MIN_RSSI]) {
6969 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306970 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306971 }
6972
6973 if (!tb[PARAM_MAX_RSSI]) {
6974 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306975 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306976 }
6977
6978 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6979 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6980 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6981
6982 if (!(pReq->minRssi < pReq->maxRssi)) {
6983 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6984 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306985 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306986 }
6987 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6988 pReq->minRssi, pReq->maxRssi);
6989 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6990
6991 }
6992 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6993 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6994 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6995 }
6996 else {
6997 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306998 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306999 }
7000
7001 if (!HAL_STATUS_SUCCESS(status)) {
7002 hddLog(LOGE,
7003 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307004 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307005 }
7006
7007 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307008fail:
7009 vos_mem_free(pReq);
7010 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307011}
7012
7013/*
7014 * done with short names for the global vendor params
7015 * used by __wlan_hdd_cfg80211_monitor_rssi()
7016 */
7017#undef PARAM_MAX
7018#undef PARAM_CONTROL
7019#undef PARAM_REQUEST_ID
7020#undef PARAM_MAX_RSSI
7021#undef PARAM_MIN_RSSI
7022
7023/**
7024 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
7025 * @wiphy: wiphy structure pointer
7026 * @wdev: Wireless device structure pointer
7027 * @data: Pointer to the data received
7028 * @data_len: Length of @data
7029 *
7030 * Return: 0 on success; errno on failure
7031 */
7032static int
7033wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
7034 const void *data, int data_len)
7035{
7036 int ret;
7037
7038 vos_ssr_protect(__func__);
7039 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
7040 vos_ssr_unprotect(__func__);
7041
7042 return ret;
7043}
7044
7045/**
7046 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
7047 * @hddctx: HDD context
7048 * @data: rssi breached event data
7049 *
7050 * This function reads the rssi breached event %data and fill in the skb with
7051 * NL attributes and send up the NL event.
7052 * This callback execute in atomic context and must not invoke any
7053 * blocking calls.
7054 *
7055 * Return: none
7056 */
7057void hdd_rssi_threshold_breached_cb(void *hddctx,
7058 struct rssi_breach_event *data)
7059{
7060 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
7061 int status;
7062 struct sk_buff *skb;
7063
7064 ENTER();
7065 status = wlan_hdd_validate_context(pHddCtx);
7066
7067 if (0 != status) {
7068 return;
7069 }
7070
7071 if (!data) {
7072 hddLog(LOGE, FL("data is null"));
7073 return;
7074 }
7075
7076 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
7077#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7078 NULL,
7079#endif
7080 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
7081 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
7082 GFP_KERNEL);
7083
7084 if (!skb) {
7085 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
7086 return;
7087 }
7088
7089 hddLog(LOG1, "Req Id: %u Current rssi: %d",
7090 data->request_id, data->curr_rssi);
7091 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
7092 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
7093
7094 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
7095 data->request_id) ||
7096 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
7097 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
7098 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
7099 data->curr_rssi)) {
7100 hddLog(LOGE, FL("nla put fail"));
7101 goto fail;
7102 }
7103
7104 cfg80211_vendor_event(skb, GFP_KERNEL);
7105 return;
7106
7107fail:
7108 kfree_skb(skb);
7109 return;
7110}
7111
7112
7113
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307114/**
7115 * __wlan_hdd_cfg80211_setband() - set band
7116 * @wiphy: Pointer to wireless phy
7117 * @wdev: Pointer to wireless device
7118 * @data: Pointer to data
7119 * @data_len: Data length
7120 *
7121 * Return: 0 on success, negative errno on failure
7122 */
7123static int
7124__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7125 struct wireless_dev *wdev,
7126 const void *data,
7127 int data_len)
7128{
7129 struct net_device *dev = wdev->netdev;
7130 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7131 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7132 int ret;
7133 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7134 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7135
7136 ENTER();
7137
7138 ret = wlan_hdd_validate_context(hdd_ctx);
7139 if (0 != ret) {
7140 hddLog(LOGE, FL("HDD context is not valid"));
7141 return ret;
7142 }
7143
7144 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7145 policy)) {
7146 hddLog(LOGE, FL("Invalid ATTR"));
7147 return -EINVAL;
7148 }
7149
7150 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7151 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7152 return -EINVAL;
7153 }
7154
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307155 hdd_ctx->isSetBandByNL = TRUE;
7156 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307157 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307158 hdd_ctx->isSetBandByNL = FALSE;
7159
7160 EXIT();
7161 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307162}
7163
7164/**
7165 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7166 * @wiphy: wiphy structure pointer
7167 * @wdev: Wireless device structure pointer
7168 * @data: Pointer to the data received
7169 * @data_len: Length of @data
7170 *
7171 * Return: 0 on success; errno on failure
7172 */
7173static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7174 struct wireless_dev *wdev,
7175 const void *data,
7176 int data_len)
7177{
7178 int ret = 0;
7179
7180 vos_ssr_protect(__func__);
7181 ret = __wlan_hdd_cfg80211_setband(wiphy,
7182 wdev, data, data_len);
7183 vos_ssr_unprotect(__func__);
7184
7185 return ret;
7186}
7187
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307188#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7189/**
7190 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7191 * @hdd_ctx: HDD context
7192 * @request_id: [input] request id
7193 * @pattern_id: [output] pattern id
7194 *
7195 * This function loops through request id to pattern id array
7196 * if the slot is available, store the request id and return pattern id
7197 * if entry exists, return the pattern id
7198 *
7199 * Return: 0 on success and errno on failure
7200 */
7201static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7202 uint32_t request_id,
7203 uint8_t *pattern_id)
7204{
7205 uint32_t i;
7206
7207 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7208 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7209 {
7210 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7211 {
7212 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7213 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7214 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7215 return 0;
7216 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7217 request_id) {
7218 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7219 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7220 return 0;
7221 }
7222 }
7223 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7224 return -EINVAL;
7225}
7226
7227/**
7228 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7229 * @hdd_ctx: HDD context
7230 * @request_id: [input] request id
7231 * @pattern_id: [output] pattern id
7232 *
7233 * This function loops through request id to pattern id array
7234 * reset request id to 0 (slot available again) and
7235 * return pattern id
7236 *
7237 * Return: 0 on success and errno on failure
7238 */
7239static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7240 uint32_t request_id,
7241 uint8_t *pattern_id)
7242{
7243 uint32_t i;
7244
7245 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7246 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7247 {
7248 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7249 {
7250 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7251 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7252 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7253 return 0;
7254 }
7255 }
7256 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7257 return -EINVAL;
7258}
7259
7260
7261/*
7262 * define short names for the global vendor params
7263 * used by __wlan_hdd_cfg80211_offloaded_packets()
7264 */
7265#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7266#define PARAM_REQUEST_ID \
7267 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7268#define PARAM_CONTROL \
7269 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7270#define PARAM_IP_PACKET \
7271 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7272#define PARAM_SRC_MAC_ADDR \
7273 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7274#define PARAM_DST_MAC_ADDR \
7275 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7276#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7277
7278/**
7279 * wlan_hdd_add_tx_ptrn() - add tx pattern
7280 * @adapter: adapter pointer
7281 * @hdd_ctx: hdd context
7282 * @tb: nl attributes
7283 *
7284 * This function reads the NL attributes and forms a AddTxPtrn message
7285 * posts it to SME.
7286 *
7287 */
7288static int
7289wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7290 struct nlattr **tb)
7291{
7292 struct sSirAddPeriodicTxPtrn *add_req;
7293 eHalStatus status;
7294 uint32_t request_id, ret, len;
7295 uint8_t pattern_id = 0;
7296 v_MACADDR_t dst_addr;
7297 uint16_t eth_type = htons(ETH_P_IP);
7298
7299 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7300 {
7301 hddLog(LOGE, FL("Not in Connected state!"));
7302 return -ENOTSUPP;
7303 }
7304
7305 add_req = vos_mem_malloc(sizeof(*add_req));
7306 if (!add_req)
7307 {
7308 hddLog(LOGE, FL("memory allocation failed"));
7309 return -ENOMEM;
7310 }
7311
7312 /* Parse and fetch request Id */
7313 if (!tb[PARAM_REQUEST_ID])
7314 {
7315 hddLog(LOGE, FL("attr request id failed"));
7316 goto fail;
7317 }
7318
7319 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7320 hddLog(LOG1, FL("Request Id: %u"), request_id);
7321 if (request_id == 0)
7322 {
7323 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307324 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307325 }
7326
7327 if (!tb[PARAM_PERIOD])
7328 {
7329 hddLog(LOGE, FL("attr period failed"));
7330 goto fail;
7331 }
7332 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7333 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7334 if (add_req->usPtrnIntervalMs == 0)
7335 {
7336 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7337 goto fail;
7338 }
7339
7340 if (!tb[PARAM_SRC_MAC_ADDR])
7341 {
7342 hddLog(LOGE, FL("attr source mac address failed"));
7343 goto fail;
7344 }
7345 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7346 VOS_MAC_ADDR_SIZE);
7347 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7348 MAC_ADDR_ARRAY(add_req->macAddress));
7349
7350 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7351 VOS_MAC_ADDR_SIZE))
7352 {
7353 hddLog(LOGE,
7354 FL("input src mac address and connected ap bssid are different"));
7355 goto fail;
7356 }
7357
7358 if (!tb[PARAM_DST_MAC_ADDR])
7359 {
7360 hddLog(LOGE, FL("attr dst mac address failed"));
7361 goto fail;
7362 }
7363 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7364 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7365 MAC_ADDR_ARRAY(dst_addr.bytes));
7366
7367 if (!tb[PARAM_IP_PACKET])
7368 {
7369 hddLog(LOGE, FL("attr ip packet failed"));
7370 goto fail;
7371 }
7372 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7373 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7374
7375 if (add_req->ucPtrnSize < 0 ||
7376 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7377 HDD_ETH_HEADER_LEN))
7378 {
7379 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7380 add_req->ucPtrnSize);
7381 goto fail;
7382 }
7383
7384 len = 0;
7385 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7386 len += VOS_MAC_ADDR_SIZE;
7387 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7388 VOS_MAC_ADDR_SIZE);
7389 len += VOS_MAC_ADDR_SIZE;
7390 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7391 len += 2;
7392
7393 /*
7394 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7395 * ------------------------------------------------------------
7396 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7397 * ------------------------------------------------------------
7398 */
7399 vos_mem_copy(&add_req->ucPattern[len],
7400 nla_data(tb[PARAM_IP_PACKET]),
7401 add_req->ucPtrnSize);
7402 add_req->ucPtrnSize += len;
7403
7404 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7405 add_req->ucPattern, add_req->ucPtrnSize);
7406
7407 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7408 if (ret)
7409 {
7410 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7411 goto fail;
7412 }
7413 add_req->ucPtrnId = pattern_id;
7414 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7415
7416 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7417 if (!HAL_STATUS_SUCCESS(status))
7418 {
7419 hddLog(LOGE,
7420 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7421 goto fail;
7422 }
7423
7424 EXIT();
7425 vos_mem_free(add_req);
7426 return 0;
7427
7428fail:
7429 vos_mem_free(add_req);
7430 return -EINVAL;
7431}
7432
7433/**
7434 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7435 * @adapter: adapter pointer
7436 * @hdd_ctx: hdd context
7437 * @tb: nl attributes
7438 *
7439 * This function reads the NL attributes and forms a DelTxPtrn message
7440 * posts it to SME.
7441 *
7442 */
7443static int
7444wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7445 struct nlattr **tb)
7446{
7447 struct sSirDelPeriodicTxPtrn *del_req;
7448 eHalStatus status;
7449 uint32_t request_id, ret;
7450 uint8_t pattern_id = 0;
7451
7452 /* Parse and fetch request Id */
7453 if (!tb[PARAM_REQUEST_ID])
7454 {
7455 hddLog(LOGE, FL("attr request id failed"));
7456 return -EINVAL;
7457 }
7458 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7459 if (request_id == 0)
7460 {
7461 hddLog(LOGE, FL("request_id cannot be zero"));
7462 return -EINVAL;
7463 }
7464
7465 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7466 if (ret)
7467 {
7468 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7469 return -EINVAL;
7470 }
7471
7472 del_req = vos_mem_malloc(sizeof(*del_req));
7473 if (!del_req)
7474 {
7475 hddLog(LOGE, FL("memory allocation failed"));
7476 return -ENOMEM;
7477 }
7478
7479 vos_mem_set(del_req, sizeof(*del_req), 0);
7480 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7481 VOS_MAC_ADDR_SIZE);
7482 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7483 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7484 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7485 request_id, pattern_id, del_req->ucPatternIdBitmap);
7486
7487 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7488 if (!HAL_STATUS_SUCCESS(status))
7489 {
7490 hddLog(LOGE,
7491 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7492 goto fail;
7493 }
7494
7495 EXIT();
7496 vos_mem_free(del_req);
7497 return 0;
7498
7499fail:
7500 vos_mem_free(del_req);
7501 return -EINVAL;
7502}
7503
7504
7505/**
7506 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7507 * @wiphy: Pointer to wireless phy
7508 * @wdev: Pointer to wireless device
7509 * @data: Pointer to data
7510 * @data_len: Data length
7511 *
7512 * Return: 0 on success, negative errno on failure
7513 */
7514static int
7515__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7516 struct wireless_dev *wdev,
7517 const void *data,
7518 int data_len)
7519{
7520 struct net_device *dev = wdev->netdev;
7521 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7522 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7523 struct nlattr *tb[PARAM_MAX + 1];
7524 uint8_t control;
7525 int ret;
7526 static const struct nla_policy policy[PARAM_MAX + 1] =
7527 {
7528 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7529 [PARAM_CONTROL] = { .type = NLA_U32 },
7530 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7531 .len = VOS_MAC_ADDR_SIZE },
7532 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7533 .len = VOS_MAC_ADDR_SIZE },
7534 [PARAM_PERIOD] = { .type = NLA_U32 },
7535 };
7536
7537 ENTER();
7538
7539 ret = wlan_hdd_validate_context(hdd_ctx);
7540 if (0 != ret)
7541 {
7542 hddLog(LOGE, FL("HDD context is not valid"));
7543 return ret;
7544 }
7545
7546 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7547 {
7548 hddLog(LOGE,
7549 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7550 return -ENOTSUPP;
7551 }
7552
7553 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7554 {
7555 hddLog(LOGE, FL("Invalid ATTR"));
7556 return -EINVAL;
7557 }
7558
7559 if (!tb[PARAM_CONTROL])
7560 {
7561 hddLog(LOGE, FL("attr control failed"));
7562 return -EINVAL;
7563 }
7564 control = nla_get_u32(tb[PARAM_CONTROL]);
7565 hddLog(LOG1, FL("Control: %d"), control);
7566
7567 if (control == WLAN_START_OFFLOADED_PACKETS)
7568 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7569 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7570 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7571 else
7572 {
7573 hddLog(LOGE, FL("Invalid control: %d"), control);
7574 return -EINVAL;
7575 }
7576}
7577
7578/*
7579 * done with short names for the global vendor params
7580 * used by __wlan_hdd_cfg80211_offloaded_packets()
7581 */
7582#undef PARAM_MAX
7583#undef PARAM_REQUEST_ID
7584#undef PARAM_CONTROL
7585#undef PARAM_IP_PACKET
7586#undef PARAM_SRC_MAC_ADDR
7587#undef PARAM_DST_MAC_ADDR
7588#undef PARAM_PERIOD
7589
7590/**
7591 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7592 * @wiphy: wiphy structure pointer
7593 * @wdev: Wireless device structure pointer
7594 * @data: Pointer to the data received
7595 * @data_len: Length of @data
7596 *
7597 * Return: 0 on success; errno on failure
7598 */
7599static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7600 struct wireless_dev *wdev,
7601 const void *data,
7602 int data_len)
7603{
7604 int ret = 0;
7605
7606 vos_ssr_protect(__func__);
7607 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7608 wdev, data, data_len);
7609 vos_ssr_unprotect(__func__);
7610
7611 return ret;
7612}
7613#endif
7614
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307615static const struct
7616nla_policy
7617qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307618 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7619 .type = NLA_BINARY,
7620 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307621};
7622
7623/**
7624 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7625 * get link properties like nss, rate flags and operating frequency for
7626 * the connection with the given peer.
7627 * @wiphy: WIPHY structure pointer
7628 * @wdev: Wireless device structure pointer
7629 * @data: Pointer to the data received
7630 * @data_len: Length of the data received
7631 *
7632 * This function return the above link properties on success.
7633 *
7634 * Return: 0 on success and errno on failure
7635 */
7636static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7637 struct wireless_dev *wdev,
7638 const void *data,
7639 int data_len)
7640{
7641 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7642 struct net_device *dev = wdev->netdev;
7643 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7644 hdd_station_ctx_t *hdd_sta_ctx;
7645 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7646 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7647 uint32_t sta_id;
7648 struct sk_buff *reply_skb;
7649 uint32_t rate_flags = 0;
7650 uint8_t nss;
7651 uint8_t final_rate_flags = 0;
7652 uint32_t freq;
7653 v_CONTEXT_t pVosContext = NULL;
7654 ptSapContext pSapCtx = NULL;
7655
7656 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7657 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7658 return -EINVAL;
7659 }
7660
7661 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7662 qca_wlan_vendor_attr_policy)) {
7663 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7664 return -EINVAL;
7665 }
7666
7667 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7668 hddLog(VOS_TRACE_LEVEL_ERROR,
7669 FL("Attribute peerMac not provided for mode=%d"),
7670 adapter->device_mode);
7671 return -EINVAL;
7672 }
7673
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307674 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7675 hddLog(VOS_TRACE_LEVEL_ERROR,
7676 FL("Attribute peerMac is invalid=%d"),
7677 adapter->device_mode);
7678 return -EINVAL;
7679 }
7680
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307681 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7682 sizeof(peer_mac));
7683 hddLog(VOS_TRACE_LEVEL_INFO,
7684 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7685 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7686
7687 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7688 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7689 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7690 if ((hdd_sta_ctx->conn_info.connState !=
7691 eConnectionState_Associated) ||
7692 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7693 VOS_MAC_ADDRESS_LEN)) {
7694 hddLog(VOS_TRACE_LEVEL_ERROR,
7695 FL("Not Associated to mac "MAC_ADDRESS_STR),
7696 MAC_ADDR_ARRAY(peer_mac));
7697 return -EINVAL;
7698 }
7699
7700 nss = 1; //pronto supports only one spatial stream
7701 freq = vos_chan_to_freq(
7702 hdd_sta_ctx->conn_info.operationChannel);
7703 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7704
7705 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7706 adapter->device_mode == WLAN_HDD_SOFTAP) {
7707
7708 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7709 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7710 if(pSapCtx == NULL){
7711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7712 FL("psapCtx is NULL"));
7713 return -ENOENT;
7714 }
7715
7716
7717 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7718 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7719 !vos_is_macaddr_broadcast(
7720 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7721 vos_mem_compare(
7722 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7723 peer_mac, VOS_MAC_ADDRESS_LEN))
7724 break;
7725 }
7726
7727 if (WLAN_MAX_STA_COUNT == sta_id) {
7728 hddLog(VOS_TRACE_LEVEL_ERROR,
7729 FL("No active peer with mac="MAC_ADDRESS_STR),
7730 MAC_ADDR_ARRAY(peer_mac));
7731 return -EINVAL;
7732 }
7733
7734 nss = 1; //pronto supports only one spatial stream
7735 freq = vos_chan_to_freq(
7736 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7737 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7738 } else {
7739 hddLog(VOS_TRACE_LEVEL_ERROR,
7740 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7741 MAC_ADDR_ARRAY(peer_mac));
7742 return -EINVAL;
7743 }
7744
7745 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7746 if (rate_flags & eHAL_TX_RATE_VHT80) {
7747 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307748#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7749 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307750 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307751#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307752 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7753 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307754#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7755 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307756 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307757#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307758 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7759 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7760 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7761 final_rate_flags |= RATE_INFO_FLAGS_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307762#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7763 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307764 if (rate_flags & eHAL_TX_RATE_HT40)
7765 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307766#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307767 }
7768
7769 if (rate_flags & eHAL_TX_RATE_SGI) {
7770 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7771 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7772 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7773 }
7774 }
7775
7776 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7777 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7778
7779 if (NULL == reply_skb) {
7780 hddLog(VOS_TRACE_LEVEL_ERROR,
7781 FL("getLinkProperties: skb alloc failed"));
7782 return -EINVAL;
7783 }
7784
7785 if (nla_put_u8(reply_skb,
7786 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7787 nss) ||
7788 nla_put_u8(reply_skb,
7789 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7790 final_rate_flags) ||
7791 nla_put_u32(reply_skb,
7792 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7793 freq)) {
7794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7795 kfree_skb(reply_skb);
7796 return -EINVAL;
7797 }
7798
7799 return cfg80211_vendor_cmd_reply(reply_skb);
7800}
7801
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307802#define BEACON_MISS_THRESH_2_4 \
7803 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7804#define BEACON_MISS_THRESH_5_0 \
7805 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307806#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7807#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7808#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7809#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307810#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7811 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307812
7813/**
7814 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7815 * vendor command
7816 *
7817 * @wiphy: wiphy device pointer
7818 * @wdev: wireless device pointer
7819 * @data: Vendor command data buffer
7820 * @data_len: Buffer length
7821 *
7822 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7823 *
7824 * Return: EOK or other error codes.
7825 */
7826
7827static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7828 struct wireless_dev *wdev,
7829 const void *data,
7830 int data_len)
7831{
7832 struct net_device *dev = wdev->netdev;
7833 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7834 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7835 hdd_station_ctx_t *pHddStaCtx;
7836 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7837 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307838 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307839 eHalStatus status;
7840 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307841 uint8_t hb_thresh_val;
7842
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307843 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7844 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7845 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307846 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7847 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7848 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307849 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7850 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307851 };
7852
7853 ENTER();
7854
7855 if (VOS_FTM_MODE == hdd_get_conparam()) {
7856 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7857 return -EINVAL;
7858 }
7859
7860 ret_val = wlan_hdd_validate_context(pHddCtx);
7861 if (ret_val) {
7862 return ret_val;
7863 }
7864
7865 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7866
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307867 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7868 hddLog(LOGE, FL("Invalid ATTR"));
7869 return -EINVAL;
7870 }
7871
7872 /* check the Wifi Capability */
7873 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7874 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7875 {
7876 hddLog(VOS_TRACE_LEVEL_ERROR,
7877 FL("WIFICONFIG not supported by Firmware"));
7878 return -EINVAL;
7879 }
7880
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307881 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7882 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7883 modifyRoamParamsReq.value =
7884 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7885
7886 if (eHAL_STATUS_SUCCESS !=
7887 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7888 {
7889 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7890 ret_val = -EINVAL;
7891 }
7892 return ret_val;
7893 }
7894
7895 /* Moved this down in order to provide provision to set beacon
7896 * miss penalty count irrespective of connection state.
7897 */
7898 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7899 hddLog(LOGE, FL("Not in Connected state!"));
7900 return -ENOTSUPP;
7901 }
7902
7903 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307904
7905 if (!pReq) {
7906 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7907 "%s: Not able to allocate memory for tSetWifiConfigParams",
7908 __func__);
7909 return eHAL_STATUS_E_MALLOC_FAILED;
7910 }
7911
7912 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7913
7914 pReq->sessionId = pAdapter->sessionId;
7915 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7916
7917 if (tb[PARAM_MODULATED_DTIM]) {
7918 pReq->paramValue = nla_get_u32(
7919 tb[PARAM_MODULATED_DTIM]);
7920 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7921 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307922 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307923 hdd_set_pwrparams(pHddCtx);
7924 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7925 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7926
7927 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7928 iw_full_power_cbfn, pAdapter,
7929 eSME_FULL_PWR_NEEDED_BY_HDD);
7930 }
7931 else
7932 {
7933 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7934 }
7935 }
7936
7937 if (tb[PARAM_STATS_AVG_FACTOR]) {
7938 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7939 pReq->paramValue = nla_get_u16(
7940 tb[PARAM_STATS_AVG_FACTOR]);
7941 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7942 pReq->paramType, pReq->paramValue);
7943 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7944
7945 if (eHAL_STATUS_SUCCESS != status)
7946 {
7947 vos_mem_free(pReq);
7948 pReq = NULL;
7949 ret_val = -EPERM;
7950 return ret_val;
7951 }
7952 }
7953
7954
7955 if (tb[PARAM_GUARD_TIME]) {
7956 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7957 pReq->paramValue = nla_get_u32(
7958 tb[PARAM_GUARD_TIME]);
7959 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7960 pReq->paramType, pReq->paramValue);
7961 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7962
7963 if (eHAL_STATUS_SUCCESS != status)
7964 {
7965 vos_mem_free(pReq);
7966 pReq = NULL;
7967 ret_val = -EPERM;
7968 return ret_val;
7969 }
7970
7971 }
7972
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307973 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7974 hb_thresh_val = nla_get_u8(
7975 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7976
7977 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7978 hb_thresh_val);
7979 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7980 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7981 NULL, eANI_BOOLEAN_FALSE);
7982
7983 status = sme_update_hb_threshold(
7984 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7985 WNI_CFG_HEART_BEAT_THRESHOLD,
7986 hb_thresh_val, eCSR_BAND_24);
7987 if (eHAL_STATUS_SUCCESS != status) {
7988 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7989 vos_mem_free(pReq);
7990 pReq = NULL;
7991 return -EPERM;
7992 }
7993 }
7994
7995 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7996 hb_thresh_val = nla_get_u8(
7997 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7998
7999 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
8000 hb_thresh_val);
8001 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
8002 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
8003 NULL, eANI_BOOLEAN_FALSE);
8004
8005 status = sme_update_hb_threshold(
8006 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
8007 WNI_CFG_HEART_BEAT_THRESHOLD,
8008 hb_thresh_val, eCSR_BAND_5G);
8009 if (eHAL_STATUS_SUCCESS != status) {
8010 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
8011 vos_mem_free(pReq);
8012 pReq = NULL;
8013 return -EPERM;
8014 }
8015 }
8016
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308017 EXIT();
8018 return ret_val;
8019}
8020
8021/**
8022 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
8023 * vendor command
8024 *
8025 * @wiphy: wiphy device pointer
8026 * @wdev: wireless device pointer
8027 * @data: Vendor command data buffer
8028 * @data_len: Buffer length
8029 *
8030 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
8031 *
8032 * Return: EOK or other error codes.
8033 */
8034static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
8035 struct wireless_dev *wdev,
8036 const void *data,
8037 int data_len)
8038{
8039 int ret;
8040
8041 vos_ssr_protect(__func__);
8042 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
8043 data, data_len);
8044 vos_ssr_unprotect(__func__);
8045
8046 return ret;
8047}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308048
8049/*
8050 * define short names for the global vendor params
8051 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8052 */
8053#define STATS_SET_INVALID \
8054 QCA_ATTR_NUD_STATS_SET_INVALID
8055#define STATS_SET_START \
8056 QCA_ATTR_NUD_STATS_SET_START
8057#define STATS_GW_IPV4 \
8058 QCA_ATTR_NUD_STATS_GW_IPV4
8059#define STATS_SET_MAX \
8060 QCA_ATTR_NUD_STATS_SET_MAX
8061
8062const struct nla_policy
8063qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
8064{
8065 [STATS_SET_START] = {.type = NLA_FLAG },
8066 [STATS_GW_IPV4] = {.type = NLA_U32 },
8067};
8068
8069/**
8070 * hdd_set_nud_stats_cb() - hdd callback api to get status
8071 * @data: pointer to adapter
8072 * @rsp: status
8073 *
8074 * Return: None
8075 */
8076static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
8077{
8078
8079 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8080
8081 if (NULL == adapter)
8082 return;
8083
8084 if (VOS_STATUS_SUCCESS == rsp) {
8085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8086 "%s success received STATS_SET_START", __func__);
8087 } else {
8088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8089 "%s STATS_SET_START Failed!!", __func__);
8090 }
8091 return;
8092}
8093
8094/**
8095 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8096 * @wiphy: pointer to wireless wiphy structure.
8097 * @wdev: pointer to wireless_dev structure.
8098 * @data: pointer to apfind configuration data.
8099 * @data_len: the length in byte of apfind data.
8100 *
8101 * This is called when wlan driver needs to send arp stats to
8102 * firmware.
8103 *
8104 * Return: An error code or 0 on success.
8105 */
8106static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8107 struct wireless_dev *wdev,
8108 const void *data, int data_len)
8109{
8110 struct nlattr *tb[STATS_SET_MAX + 1];
8111 struct net_device *dev = wdev->netdev;
8112 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8113 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308114 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308115 setArpStatsParams arp_stats_params;
8116 int err = 0;
8117
8118 ENTER();
8119
8120 err = wlan_hdd_validate_context(hdd_ctx);
8121 if (0 != err)
8122 return err;
8123
8124 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8125 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8126 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8127 return -EINVAL;
8128 }
8129
8130 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8131 qca_wlan_vendor_set_nud_stats);
8132 if (err)
8133 {
8134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8135 "%s STATS_SET_START ATTR", __func__);
8136 return err;
8137 }
8138
8139 if (tb[STATS_SET_START])
8140 {
8141 if (!tb[STATS_GW_IPV4]) {
8142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8143 "%s STATS_SET_START CMD", __func__);
8144 return -EINVAL;
8145 }
8146 arp_stats_params.flag = true;
8147 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8148 } else {
8149 arp_stats_params.flag = false;
8150 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308151 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8153 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308154 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8155 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308156
8157 arp_stats_params.pkt_type = 1; // ARP packet type
8158
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308159 if (arp_stats_params.flag) {
8160 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8161 WLANTL_SetARPFWDatapath(pVosContext, true);
8162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8163 "%s Set FW in data path for ARP with tgt IP :%d",
8164 __func__, hdd_ctx->track_arp_ip);
8165 }
8166 else {
8167 WLANTL_SetARPFWDatapath(pVosContext, false);
8168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8169 "%s Remove FW from data path", __func__);
8170 }
8171
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308172 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8173 arp_stats_params.data_ctx = adapter;
8174
8175 if (eHAL_STATUS_SUCCESS !=
8176 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8178 "%s STATS_SET_START CMD Failed!!", __func__);
8179 return -EINVAL;
8180 }
8181
8182 EXIT();
8183
8184 return err;
8185}
8186
8187/**
8188 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8189 * @wiphy: pointer to wireless wiphy structure.
8190 * @wdev: pointer to wireless_dev structure.
8191 * @data: pointer to apfind configuration data.
8192 * @data_len: the length in byte of apfind data.
8193 *
8194 * This is called when wlan driver needs to send arp stats to
8195 * firmware.
8196 *
8197 * Return: An error code or 0 on success.
8198 */
8199static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8200 struct wireless_dev *wdev,
8201 const void *data, int data_len)
8202{
8203 int ret;
8204
8205 vos_ssr_protect(__func__);
8206 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8207 vos_ssr_unprotect(__func__);
8208
8209 return ret;
8210}
8211#undef STATS_SET_INVALID
8212#undef STATS_SET_START
8213#undef STATS_GW_IPV4
8214#undef STATS_SET_MAX
8215
8216/*
8217 * define short names for the global vendor params
8218 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8219 */
8220#define STATS_GET_INVALID \
8221 QCA_ATTR_NUD_STATS_SET_INVALID
8222#define COUNT_FROM_NETDEV \
8223 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8224#define COUNT_TO_LOWER_MAC \
8225 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8226#define RX_COUNT_BY_LOWER_MAC \
8227 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8228#define COUNT_TX_SUCCESS \
8229 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8230#define RSP_RX_COUNT_BY_LOWER_MAC \
8231 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8232#define RSP_RX_COUNT_BY_UPPER_MAC \
8233 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8234#define RSP_COUNT_TO_NETDEV \
8235 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8236#define RSP_COUNT_OUT_OF_ORDER_DROP \
8237 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8238#define AP_LINK_ACTIVE \
8239 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8240#define AP_LINK_DAD \
8241 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8242#define STATS_GET_MAX \
8243 QCA_ATTR_NUD_STATS_GET_MAX
8244
8245const struct nla_policy
8246qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8247{
8248 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8249 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8250 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8251 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8252 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8253 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8254 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8255 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8256 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8257 [AP_LINK_DAD] = {.type = NLA_FLAG },
8258};
8259
8260static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8261{
8262
8263 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308264 hdd_context_t *hdd_ctx;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308265 struct hdd_nud_stats_context *context;
8266 int status;
8267
8268 ENTER();
8269
8270 if (NULL == adapter)
8271 return;
8272
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308273 if (!rsp) {
8274 hddLog(LOGE, FL("data is null"));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308275 return;
8276 }
8277
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308278 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8279 status = wlan_hdd_validate_context(hdd_ctx);
8280 if (0 != status) {
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308281 return;
8282 }
8283
8284 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8285 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8286 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8287 adapter->dad |= rsp->dad;
8288
8289 spin_lock(&hdd_context_lock);
8290 context = &hdd_ctx->nud_stats_context;
8291 complete(&context->response_event);
8292 spin_unlock(&hdd_context_lock);
8293
8294 return;
8295}
8296static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8297 struct wireless_dev *wdev,
8298 const void *data, int data_len)
8299{
8300 int err = 0;
8301 unsigned long rc;
8302 struct hdd_nud_stats_context *context;
8303 struct net_device *dev = wdev->netdev;
8304 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8305 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8306 getArpStatsParams arp_stats_params;
8307 struct sk_buff *skb;
8308
8309 ENTER();
8310
8311 err = wlan_hdd_validate_context(hdd_ctx);
8312 if (0 != err)
8313 return err;
8314
8315 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8316 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8317 arp_stats_params.data_ctx = adapter;
8318
8319 spin_lock(&hdd_context_lock);
8320 context = &hdd_ctx->nud_stats_context;
8321 INIT_COMPLETION(context->response_event);
8322 spin_unlock(&hdd_context_lock);
8323
8324 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8326 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8327 return -EINVAL;
8328 }
8329
8330 if (eHAL_STATUS_SUCCESS !=
8331 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8333 "%s STATS_SET_START CMD Failed!!", __func__);
8334 return -EINVAL;
8335 }
8336
8337 rc = wait_for_completion_timeout(&context->response_event,
8338 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8339 if (!rc)
8340 {
8341 hddLog(LOGE,
8342 FL("Target response timed out request "));
8343 return -ETIMEDOUT;
8344 }
8345
8346 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8347 WLAN_NUD_STATS_LEN);
8348 if (!skb)
8349 {
8350 hddLog(VOS_TRACE_LEVEL_ERROR,
8351 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8352 __func__);
8353 return -ENOMEM;
8354 }
8355
8356 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8357 adapter->hdd_stats.hddArpStats.txCount) ||
8358 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8359 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8360 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8361 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8362 nla_put_u16(skb, COUNT_TX_SUCCESS,
8363 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8364 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8365 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8366 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8367 adapter->hdd_stats.hddArpStats.rxCount) ||
8368 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8369 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8370 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8371 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8372 hddLog(LOGE, FL("nla put fail"));
8373 kfree_skb(skb);
8374 return -EINVAL;
8375 }
8376 if (adapter->con_status)
8377 nla_put_flag(skb, AP_LINK_ACTIVE);
8378 if (adapter->dad)
8379 nla_put_flag(skb, AP_LINK_DAD);
8380
8381 cfg80211_vendor_cmd_reply(skb);
8382 return err;
8383}
8384
8385static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8386 struct wireless_dev *wdev,
8387 const void *data, int data_len)
8388{
8389 int ret;
8390
8391 vos_ssr_protect(__func__);
8392 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8393 vos_ssr_unprotect(__func__);
8394
8395 return ret;
8396}
8397
8398#undef QCA_ATTR_NUD_STATS_SET_INVALID
8399#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8400#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8401#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8402#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8403#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8404#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8405#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8406#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8407#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8408#undef QCA_ATTR_NUD_STATS_GET_MAX
8409
8410
8411
Kapil Guptaee33bf12016-12-20 18:27:37 +05308412#ifdef WLAN_FEATURE_APFIND
8413/**
8414 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8415 * @wiphy: pointer to wireless wiphy structure.
8416 * @wdev: pointer to wireless_dev structure.
8417 * @data: pointer to apfind configuration data.
8418 * @data_len: the length in byte of apfind data.
8419 *
8420 * This is called when wlan driver needs to send APFIND configurations to
8421 * firmware.
8422 *
8423 * Return: An error code or 0 on success.
8424 */
8425static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8426 struct wireless_dev *wdev,
8427 const void *data, int data_len)
8428{
8429 struct sme_ap_find_request_req apfind_req;
8430 VOS_STATUS status;
8431 int ret_val;
8432 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8433
8434 ENTER();
8435
8436 ret_val = wlan_hdd_validate_context(hdd_ctx);
8437 if (ret_val)
8438 return ret_val;
8439
8440 if (VOS_FTM_MODE == hdd_get_conparam()) {
8441 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8442 return -EPERM;
8443 }
8444
8445 apfind_req.request_data_len = data_len;
8446 apfind_req.request_data = data;
8447
8448 status = sme_apfind_set_cmd(&apfind_req);
8449 if (VOS_STATUS_SUCCESS != status) {
8450 ret_val = -EIO;
8451 }
8452 return ret_val;
8453}
8454
8455/**
8456 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8457 * @wiphy: pointer to wireless wiphy structure.
8458 * @wdev: pointer to wireless_dev structure.
8459 * @data: pointer to apfind configuration data.
8460 * @data_len: the length in byte of apfind data.
8461 *
8462 * This is called when wlan driver needs to send APFIND configurations to
8463 * firmware.
8464 *
8465 * Return: An error code or 0 on success.
8466 */
8467static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8468 struct wireless_dev *wdev,
8469 const void *data, int data_len)
8470{
8471 int ret;
8472
8473 vos_ssr_protect(__func__);
8474 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8475 vos_ssr_unprotect(__func__);
8476
8477 return ret;
8478}
8479#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308480const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8481{
Mukul Sharma2a271632014-10-13 14:59:01 +05308482 {
8483 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8484 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8485 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8486 WIPHY_VENDOR_CMD_NEED_NETDEV |
8487 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308488 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308489 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308490
8491 {
8492 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8493 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8494 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8495 WIPHY_VENDOR_CMD_NEED_NETDEV |
8496 WIPHY_VENDOR_CMD_NEED_RUNNING,
8497 .doit = wlan_hdd_cfg80211_nan_request
8498 },
8499
Sunil Duttc69bccb2014-05-26 21:30:20 +05308500#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8501 {
8502 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8503 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8504 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8505 WIPHY_VENDOR_CMD_NEED_NETDEV |
8506 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308507 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308508 },
8509
8510 {
8511 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8512 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8513 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8514 WIPHY_VENDOR_CMD_NEED_NETDEV |
8515 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308516 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308517 },
8518
8519 {
8520 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8521 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8522 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8523 WIPHY_VENDOR_CMD_NEED_NETDEV |
8524 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308525 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308526 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308527#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308528#ifdef WLAN_FEATURE_EXTSCAN
8529 {
8530 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8531 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8532 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8533 WIPHY_VENDOR_CMD_NEED_NETDEV |
8534 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308535 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308536 },
8537 {
8538 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8539 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8540 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8541 WIPHY_VENDOR_CMD_NEED_NETDEV |
8542 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308543 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308544 },
8545 {
8546 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8547 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8548 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8549 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308550 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308551 },
8552 {
8553 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8554 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8555 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8556 WIPHY_VENDOR_CMD_NEED_NETDEV |
8557 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308558 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308559 },
8560 {
8561 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8562 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8563 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8564 WIPHY_VENDOR_CMD_NEED_NETDEV |
8565 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308566 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308567 },
8568 {
8569 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8570 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8571 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8572 WIPHY_VENDOR_CMD_NEED_NETDEV |
8573 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308574 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308575 },
8576 {
8577 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8578 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8579 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8580 WIPHY_VENDOR_CMD_NEED_NETDEV |
8581 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308582 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308583 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308584#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308585/*EXT TDLS*/
8586 {
8587 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8588 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8589 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8590 WIPHY_VENDOR_CMD_NEED_NETDEV |
8591 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308592 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308593 },
8594 {
8595 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8596 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8597 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8598 WIPHY_VENDOR_CMD_NEED_NETDEV |
8599 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308600 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308601 },
8602 {
8603 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8604 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8605 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8606 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308607 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308608 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308609 {
8610 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8611 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8612 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8613 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308614 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308615 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308616 {
8617 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8618 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8619 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8620 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308621 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308622 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308623 {
8624 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8625 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8626 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8627 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308628 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308629 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308630 {
8631 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8632 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8633 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8634 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308635 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308636 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308637 {
8638 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308639 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8640 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8641 WIPHY_VENDOR_CMD_NEED_NETDEV |
8642 WIPHY_VENDOR_CMD_NEED_RUNNING,
8643 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8644 },
8645 {
8646 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308647 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8648 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8649 WIPHY_VENDOR_CMD_NEED_NETDEV |
8650 WIPHY_VENDOR_CMD_NEED_RUNNING,
8651 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308652 },
8653 {
8654 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8655 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8656 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8657 WIPHY_VENDOR_CMD_NEED_NETDEV,
8658 .doit = wlan_hdd_cfg80211_wifi_logger_start
8659 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308660 {
8661 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8662 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8663 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8664 WIPHY_VENDOR_CMD_NEED_NETDEV|
8665 WIPHY_VENDOR_CMD_NEED_RUNNING,
8666 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308667 },
8668 {
8669 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8670 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8671 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8672 WIPHY_VENDOR_CMD_NEED_NETDEV |
8673 WIPHY_VENDOR_CMD_NEED_RUNNING,
8674 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308675 },
8676 {
8677 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8678 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8679 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8680 WIPHY_VENDOR_CMD_NEED_NETDEV |
8681 WIPHY_VENDOR_CMD_NEED_RUNNING,
8682 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308683 },
8684#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8685 {
8686 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8687 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8688 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8689 WIPHY_VENDOR_CMD_NEED_NETDEV |
8690 WIPHY_VENDOR_CMD_NEED_RUNNING,
8691 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308692 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308693#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308694 {
8695 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8696 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8697 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8698 WIPHY_VENDOR_CMD_NEED_NETDEV |
8699 WIPHY_VENDOR_CMD_NEED_RUNNING,
8700 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308701 },
8702 {
8703 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8704 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8705 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8706 WIPHY_VENDOR_CMD_NEED_NETDEV |
8707 WIPHY_VENDOR_CMD_NEED_RUNNING,
8708 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308709 },
8710#ifdef WLAN_FEATURE_APFIND
8711 {
8712 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8713 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8714 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8715 WIPHY_VENDOR_CMD_NEED_NETDEV,
8716 .doit = wlan_hdd_cfg80211_apfind_cmd
8717 },
8718#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308719 {
8720 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8721 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8722 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8723 WIPHY_VENDOR_CMD_NEED_NETDEV |
8724 WIPHY_VENDOR_CMD_NEED_RUNNING,
8725 .doit = wlan_hdd_cfg80211_set_nud_stats
8726 },
8727 {
8728 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8729 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8730 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8731 WIPHY_VENDOR_CMD_NEED_NETDEV |
8732 WIPHY_VENDOR_CMD_NEED_RUNNING,
8733 .doit = wlan_hdd_cfg80211_get_nud_stats
8734 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308735 {
8736 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8737 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8738 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8739 WIPHY_VENDOR_CMD_NEED_NETDEV |
8740 WIPHY_VENDOR_CMD_NEED_RUNNING,
8741 .doit = hdd_cfg80211_get_station_cmd
8742 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308743};
8744
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008745/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308746static const
8747struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008748{
8749#ifdef FEATURE_WLAN_CH_AVOID
8750 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308751 .vendor_id = QCA_NL80211_VENDOR_ID,
8752 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008753 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308754#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8755#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8756 {
8757 /* Index = 1*/
8758 .vendor_id = QCA_NL80211_VENDOR_ID,
8759 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8760 },
8761 {
8762 /* Index = 2*/
8763 .vendor_id = QCA_NL80211_VENDOR_ID,
8764 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8765 },
8766 {
8767 /* Index = 3*/
8768 .vendor_id = QCA_NL80211_VENDOR_ID,
8769 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8770 },
8771 {
8772 /* Index = 4*/
8773 .vendor_id = QCA_NL80211_VENDOR_ID,
8774 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8775 },
8776 {
8777 /* Index = 5*/
8778 .vendor_id = QCA_NL80211_VENDOR_ID,
8779 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8780 },
8781 {
8782 /* Index = 6*/
8783 .vendor_id = QCA_NL80211_VENDOR_ID,
8784 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8785 },
8786#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308787#ifdef WLAN_FEATURE_EXTSCAN
8788 {
8789 .vendor_id = QCA_NL80211_VENDOR_ID,
8790 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8791 },
8792 {
8793 .vendor_id = QCA_NL80211_VENDOR_ID,
8794 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8795 },
8796 {
8797 .vendor_id = QCA_NL80211_VENDOR_ID,
8798 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8799 },
8800 {
8801 .vendor_id = QCA_NL80211_VENDOR_ID,
8802 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8803 },
8804 {
8805 .vendor_id = QCA_NL80211_VENDOR_ID,
8806 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8807 },
8808 {
8809 .vendor_id = QCA_NL80211_VENDOR_ID,
8810 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8811 },
8812 {
8813 .vendor_id = QCA_NL80211_VENDOR_ID,
8814 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8815 },
8816 {
8817 .vendor_id = QCA_NL80211_VENDOR_ID,
8818 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8819 },
8820 {
8821 .vendor_id = QCA_NL80211_VENDOR_ID,
8822 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8823 },
8824 {
8825 .vendor_id = QCA_NL80211_VENDOR_ID,
8826 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8827 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308828#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308829/*EXT TDLS*/
8830 {
8831 .vendor_id = QCA_NL80211_VENDOR_ID,
8832 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8833 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308834 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8835 .vendor_id = QCA_NL80211_VENDOR_ID,
8836 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8837 },
8838
Srinivas Dasari030bad32015-02-18 23:23:54 +05308839
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308840 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308841 .vendor_id = QCA_NL80211_VENDOR_ID,
8842 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8843 },
8844
Sushant Kaushik084f6592015-09-10 13:11:56 +05308845 {
8846 .vendor_id = QCA_NL80211_VENDOR_ID,
8847 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308848 },
8849 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8850 .vendor_id = QCA_NL80211_VENDOR_ID,
8851 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8852 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308853 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8854 .vendor_id = QCA_NL80211_VENDOR_ID,
8855 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8856 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308857 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8858 .vendor_id = QCA_NL80211_VENDOR_ID,
8859 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8860 },
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05308861 [QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
8862 .vendor_id = QCA_NL80211_VENDOR_ID,
8863 .subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
8864 },
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +05308865 [QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX] = {
8866 .vendor_id = QCA_NL80211_VENDOR_ID,
8867 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8868 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008869};
8870
Jeff Johnson295189b2012-06-20 16:38:30 -07008871/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308872 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308873 * This function is called by hdd_wlan_startup()
8874 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308875 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008876 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308877struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008878{
8879 struct wiphy *wiphy;
8880 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308881 /*
8882 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008883 */
8884 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8885
8886 if (!wiphy)
8887 {
8888 /* Print error and jump into err label and free the memory */
8889 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8890 return NULL;
8891 }
8892
Sunil Duttc69bccb2014-05-26 21:30:20 +05308893
Jeff Johnson295189b2012-06-20 16:38:30 -07008894 return wiphy;
8895}
8896
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308897#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8898 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8899/**
8900 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8901 * @wiphy: pointer to wiphy
8902 * @config: pointer to config
8903 *
8904 * Return: None
8905 */
8906static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8907 hdd_config_t *config)
8908{
8909 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
8910 if (config->max_sched_scan_plan_interval)
8911 wiphy->max_sched_scan_plan_interval =
8912 config->max_sched_scan_plan_interval;
8913 if (config->max_sched_scan_plan_iterations)
8914 wiphy->max_sched_scan_plan_iterations =
8915 config->max_sched_scan_plan_iterations;
8916}
8917#else
8918static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8919 hdd_config_t *config)
8920{
8921}
8922#endif
8923
Jeff Johnson295189b2012-06-20 16:38:30 -07008924/*
8925 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308926 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07008927 * private ioctl to change the band value
8928 */
8929int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
8930{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308931 int i, j;
8932 eNVChannelEnabledType channelEnabledState;
8933
Jeff Johnsone7245742012-09-05 17:12:55 -07008934 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308935
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308936 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008937 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308938
8939 if (NULL == wiphy->bands[i])
8940 {
8941 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
8942 __func__, i);
8943 continue;
8944 }
8945
8946 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8947 {
8948 struct ieee80211_supported_band *band = wiphy->bands[i];
8949
8950 channelEnabledState = vos_nv_getChannelEnabledState(
8951 band->channels[j].hw_value);
8952
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308953 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308954 {
Abhishek Singh678227a2014-11-04 10:52:38 +05308955 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308956 continue;
8957 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308958 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308959 {
8960 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8961 continue;
8962 }
8963
8964 if (NV_CHANNEL_DISABLE == channelEnabledState ||
8965 NV_CHANNEL_INVALID == channelEnabledState)
8966 {
8967 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8968 }
8969 else if (NV_CHANNEL_DFS == channelEnabledState)
8970 {
8971 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8972 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
8973 }
8974 else
8975 {
8976 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
8977 |IEEE80211_CHAN_RADAR);
8978 }
8979 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008980 }
8981 return 0;
8982}
8983/*
8984 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308985 * This function is called by hdd_wlan_startup()
8986 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07008987 * This function is used to initialize and register wiphy structure.
8988 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308989int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008990 struct wiphy *wiphy,
8991 hdd_config_t *pCfg
8992 )
8993{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308994 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308995 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8996
Jeff Johnsone7245742012-09-05 17:12:55 -07008997 ENTER();
8998
Jeff Johnson295189b2012-06-20 16:38:30 -07008999 /* Now bind the underlying wlan device with wiphy */
9000 set_wiphy_dev(wiphy, dev);
9001
9002 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009003
Kiet Lam6c583332013-10-14 05:37:09 +05309004#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009005 /* the flag for the other case would be initialzed in
9006 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05309007#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9008 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
9009#else
Amar Singhal0a402232013-10-11 20:57:16 -07009010 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05309011#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05309012#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009013
Amar Singhalfddc28c2013-09-05 13:03:40 -07009014 /* This will disable updating of NL channels from passive to
9015 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309016#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9017 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
9018#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07009019 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309020#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07009021
Amar Singhala49cbc52013-10-08 18:37:44 -07009022
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009023#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009024 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
9025 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
9026 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07009027 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309028#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05309029 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309030#else
9031 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
9032#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009033#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009034
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009035#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009036 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08009037#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009038 || pCfg->isFastRoamIniFeatureEnabled
9039#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009040#ifdef FEATURE_WLAN_ESE
9041 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009042#endif
9043 )
9044 {
9045 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
9046 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08009047#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009048#ifdef FEATURE_WLAN_TDLS
9049 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
9050 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
9051#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309052#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05309053 if (pCfg->configPNOScanSupport)
9054 {
9055 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
9056 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
9057 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
9058 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
9059 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309060#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009061
Abhishek Singh10d85972015-04-17 10:27:23 +05309062#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9063 wiphy->features |= NL80211_FEATURE_HT_IBSS;
9064#endif
9065
Amar Singhalfddc28c2013-09-05 13:03:40 -07009066#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009067 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
9068 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07009069 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009070 driver need to determine what to do with both
9071 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07009072
9073 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07009074#else
9075 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009076#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009077
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309078 wiphy->max_scan_ssids = MAX_SCAN_SSID;
9079
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05309080 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07009081
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309082 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
9083
Jeff Johnson295189b2012-06-20 16:38:30 -07009084 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05309085 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
9086 | BIT(NL80211_IFTYPE_ADHOC)
9087 | BIT(NL80211_IFTYPE_P2P_CLIENT)
9088 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309089 | BIT(NL80211_IFTYPE_AP)
9090 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07009091
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309092 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009093 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309094#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9095 if( pCfg->enableMCC )
9096 {
9097 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309098 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009099
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309100 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309101 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009102
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309103 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309104 wiphy->iface_combinations = wlan_hdd_iface_combination;
9105 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009106#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309107 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009108
Jeff Johnson295189b2012-06-20 16:38:30 -07009109 /* Before registering we need to update the ht capabilitied based
9110 * on ini values*/
9111 if( !pCfg->ShortGI20MhzEnable )
9112 {
9113 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
9114 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07009115 }
9116
9117 if( !pCfg->ShortGI40MhzEnable )
9118 {
9119 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9120 }
9121
9122 if( !pCfg->nChannelBondingMode5GHz )
9123 {
9124 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9125 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309126 /*
9127 * In case of static linked driver at the time of driver unload,
9128 * module exit doesn't happens. Module cleanup helps in cleaning
9129 * of static memory.
9130 * If driver load happens statically, at the time of driver unload,
9131 * wiphy flags don't get reset because of static memory.
9132 * It's better not to store channel in static memory.
9133 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309134 wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9135 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309136 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309137 if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309138 {
9139 hddLog(VOS_TRACE_LEVEL_ERROR,
9140 FL("Not enough memory to allocate channels"));
9141 return -ENOMEM;
9142 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309143 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309144 &hdd_channels_2_4_GHZ[0],
9145 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009146
Agrawal Ashish97dec502015-11-26 20:20:58 +05309147 if (true == hdd_is_5g_supported(pHddCtx))
9148 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309149 wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9150 wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309151 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309152 if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309153 {
9154 hddLog(VOS_TRACE_LEVEL_ERROR,
9155 FL("Not enough memory to allocate channels"));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309156 vos_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
9157 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
Agrawal Ashish97dec502015-11-26 20:20:58 +05309158 return -ENOMEM;
9159 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309160 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309161 &hdd_channels_5_GHZ[0],
9162 sizeof(hdd_channels_5_GHZ));
9163 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309164
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309165 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309166 {
9167
9168 if (NULL == wiphy->bands[i])
9169 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309170 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309171 __func__, i);
9172 continue;
9173 }
9174
9175 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9176 {
9177 struct ieee80211_supported_band *band = wiphy->bands[i];
9178
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309179 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309180 {
9181 // Enable social channels for P2P
9182 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9183 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9184 else
9185 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9186 continue;
9187 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309188 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309189 {
9190 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9191 continue;
9192 }
9193 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009194 }
9195 /*Initialise the supported cipher suite details*/
9196 wiphy->cipher_suites = hdd_cipher_suites;
9197 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9198
9199 /*signal strength in mBm (100*dBm) */
9200 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9201
9202#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309203 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009204#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009205
Sunil Duttc69bccb2014-05-26 21:30:20 +05309206 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9207 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009208 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9209 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9210
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309211 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
9212
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309213 EXIT();
9214 return 0;
9215}
9216
9217/* In this function we are registering wiphy. */
9218int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9219{
9220 ENTER();
9221 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009222 if (0 > wiphy_register(wiphy))
9223 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309224 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009225 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9226 return -EIO;
9227 }
9228
9229 EXIT();
9230 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309231}
Jeff Johnson295189b2012-06-20 16:38:30 -07009232
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309233/* In this function we are updating channel list when,
9234 regulatory domain is FCC and country code is US.
9235 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9236 As per FCC smart phone is not a indoor device.
9237 GO should not opeate on indoor channels */
9238void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9239{
9240 int j;
9241 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9242 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9243 //Default counrtycode from NV at the time of wiphy initialization.
9244 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9245 &defaultCountryCode[0]))
9246 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009247 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309248 }
9249 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9250 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309251 if (NULL == wiphy->bands[HDD_NL80211_BAND_5GHZ])
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309252 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309253 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[HDD_NL80211_BAND_5GHZ] is NULL",__func__ );
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309254 return;
9255 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309256 for (j = 0; j < wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels; j++)
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309257 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309258 struct ieee80211_supported_band *band = wiphy->bands[HDD_NL80211_BAND_5GHZ];
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309259 // Mark UNII -1 band channel as passive
9260 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9261 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9262 }
9263 }
9264}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309265/* This function registers for all frame which supplicant is interested in */
9266void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009267{
Jeff Johnson295189b2012-06-20 16:38:30 -07009268 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9269 /* Register for all P2P action, public action etc frames */
9270 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009271 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309272 /* Register frame indication call back */
9273 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009274 /* Right now we are registering these frame when driver is getting
9275 initialized. Once we will move to 2.6.37 kernel, in which we have
9276 frame register ops, we will move this code as a part of that */
9277 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309278 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009279 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9280
9281 /* GAS Initial Response */
9282 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9283 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309284
Jeff Johnson295189b2012-06-20 16:38:30 -07009285 /* GAS Comeback Request */
9286 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9287 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9288
9289 /* GAS Comeback Response */
9290 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9291 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9292
9293 /* P2P Public Action */
9294 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309295 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009296 P2P_PUBLIC_ACTION_FRAME_SIZE );
9297
9298 /* P2P Action */
9299 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9300 (v_U8_t*)P2P_ACTION_FRAME,
9301 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009302
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309303 /* WNM BSS Transition Request frame */
9304 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9305 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9306 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009307
9308 /* WNM-Notification */
9309 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9310 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9311 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009312}
9313
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309314void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009315{
Jeff Johnson295189b2012-06-20 16:38:30 -07009316 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9317 /* Register for all P2P action, public action etc frames */
9318 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9319
Jeff Johnsone7245742012-09-05 17:12:55 -07009320 ENTER();
9321
Jeff Johnson295189b2012-06-20 16:38:30 -07009322 /* Right now we are registering these frame when driver is getting
9323 initialized. Once we will move to 2.6.37 kernel, in which we have
9324 frame register ops, we will move this code as a part of that */
9325 /* GAS Initial Request */
9326
9327 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9328 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9329
9330 /* GAS Initial Response */
9331 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9332 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309333
Jeff Johnson295189b2012-06-20 16:38:30 -07009334 /* GAS Comeback Request */
9335 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9336 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9337
9338 /* GAS Comeback Response */
9339 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9340 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9341
9342 /* P2P Public Action */
9343 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309344 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009345 P2P_PUBLIC_ACTION_FRAME_SIZE );
9346
9347 /* P2P Action */
9348 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9349 (v_U8_t*)P2P_ACTION_FRAME,
9350 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009351 /* WNM-Notification */
9352 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9353 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9354 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009355}
9356
9357#ifdef FEATURE_WLAN_WAPI
9358void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309359 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009360{
9361 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9362 tCsrRoamSetKey setKey;
9363 v_BOOL_t isConnected = TRUE;
9364 int status = 0;
9365 v_U32_t roamId= 0xFF;
9366 tANI_U8 *pKeyPtr = NULL;
9367 int n = 0;
9368
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309369 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9370 __func__, hdd_device_modetoString(pAdapter->device_mode),
9371 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009372
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309373 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009374 setKey.keyId = key_index; // Store Key ID
9375 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9376 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9377 setKey.paeRole = 0 ; // the PAE role
9378 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9379 {
9380 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9381 }
9382 else
9383 {
9384 isConnected = hdd_connIsConnected(pHddStaCtx);
9385 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9386 }
9387 setKey.keyLength = key_Len;
9388 pKeyPtr = setKey.Key;
9389 memcpy( pKeyPtr, key, key_Len);
9390
Arif Hussain6d2a3322013-11-17 19:50:10 -08009391 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009392 __func__, key_Len);
9393 for (n = 0 ; n < key_Len; n++)
9394 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9395 __func__,n,setKey.Key[n]);
9396
9397 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9398 if ( isConnected )
9399 {
9400 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9401 pAdapter->sessionId, &setKey, &roamId );
9402 }
9403 if ( status != 0 )
9404 {
9405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9406 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9407 __LINE__, status );
9408 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9409 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309410 /* Need to clear any trace of key value in the memory.
9411 * Thus zero out the memory even though it is local
9412 * variable.
9413 */
9414 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009415}
9416#endif /* FEATURE_WLAN_WAPI*/
9417
9418#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309419int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009420 beacon_data_t **ppBeacon,
9421 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009422#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309423int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009424 beacon_data_t **ppBeacon,
9425 struct cfg80211_beacon_data *params,
9426 int dtim_period)
9427#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309428{
Jeff Johnson295189b2012-06-20 16:38:30 -07009429 int size;
9430 beacon_data_t *beacon = NULL;
9431 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309432 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9433 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009434
Jeff Johnsone7245742012-09-05 17:12:55 -07009435 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009436 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309437 {
9438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9439 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009440 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309441 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009442
9443 old = pAdapter->sessionCtx.ap.beacon;
9444
9445 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309446 {
9447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9448 FL("session(%d) old and new heads points to NULL"),
9449 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009450 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309451 }
9452
9453 if (params->tail && !params->tail_len)
9454 {
9455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9456 FL("tail_len is zero but tail is not NULL"));
9457 return -EINVAL;
9458 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009459
Jeff Johnson295189b2012-06-20 16:38:30 -07009460#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9461 /* Kernel 3.0 is not updating dtim_period for set beacon */
9462 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309463 {
9464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9465 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009466 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309467 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009468#endif
9469
Kapil Gupta137ef892016-12-13 19:38:00 +05309470 if (params->head)
9471 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009472 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309473 head = params->head;
9474 } else
9475 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009476 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309477 head = old->head;
9478 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009479
Kapil Gupta137ef892016-12-13 19:38:00 +05309480 if (params->tail || !old)
9481 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009482 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309483 tail = params->tail;
9484 } else
9485 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009486 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309487 tail = old->tail;
9488 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009489
Kapil Gupta137ef892016-12-13 19:38:00 +05309490 if (params->proberesp_ies || !old)
9491 {
9492 proberesp_ies_len = params->proberesp_ies_len;
9493 proberesp_ies = params->proberesp_ies;
9494 } else
9495 {
9496 proberesp_ies_len = old->proberesp_ies_len;
9497 proberesp_ies = old->proberesp_ies;
9498 }
9499
9500 if (params->assocresp_ies || !old)
9501 {
9502 assocresp_ies_len = params->assocresp_ies_len;
9503 assocresp_ies = params->assocresp_ies;
9504 } else
9505 {
9506 assocresp_ies_len = old->assocresp_ies_len;
9507 assocresp_ies = old->assocresp_ies;
9508 }
9509
9510 size = sizeof(beacon_data_t) + head_len + tail_len +
9511 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009512
9513 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009514 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309515 {
9516 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9517 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009518 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309519 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009520
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009521#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309522 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009523 beacon->dtim_period = params->dtim_period;
9524 else
9525 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009526#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309527 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009528 beacon->dtim_period = dtim_period;
9529 else
9530 beacon->dtim_period = old->dtim_period;
9531#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309532
Jeff Johnson295189b2012-06-20 16:38:30 -07009533 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9534 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309535 beacon->proberesp_ies = beacon->tail + tail_len;
9536 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9537
Jeff Johnson295189b2012-06-20 16:38:30 -07009538 beacon->head_len = head_len;
9539 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309540 beacon->proberesp_ies_len = proberesp_ies_len;
9541 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009542
c_manjee527ecac2017-01-25 12:25:27 +05309543 if (head && head_len)
9544 memcpy(beacon->head, head, head_len);
9545 if (tail && tail_len)
9546 memcpy(beacon->tail, tail, tail_len);
9547 if (proberesp_ies && proberesp_ies_len)
9548 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9549 if (assocresp_ies && assocresp_ies_len)
9550 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009551
9552 *ppBeacon = beacon;
9553
9554 kfree(old);
9555
9556 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009557}
Jeff Johnson295189b2012-06-20 16:38:30 -07009558
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309559v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9560#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9561 const v_U8_t *pIes,
9562#else
9563 v_U8_t *pIes,
9564#endif
9565 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009566{
9567 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309568 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009569 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309570
Jeff Johnson295189b2012-06-20 16:38:30 -07009571 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309572 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009573 elem_id = ptr[0];
9574 elem_len = ptr[1];
9575 left -= 2;
9576 if(elem_len > left)
9577 {
9578 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009579 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009580 eid,elem_len,left);
9581 return NULL;
9582 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309583 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009584 {
9585 return ptr;
9586 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309587
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 left -= elem_len;
9589 ptr += (elem_len + 2);
9590 }
9591 return NULL;
9592}
9593
Jeff Johnson295189b2012-06-20 16:38:30 -07009594/* Check if rate is 11g rate or not */
9595static int wlan_hdd_rate_is_11g(u8 rate)
9596{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009597 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009598 u8 i;
9599 for (i = 0; i < 8; i++)
9600 {
9601 if(rate == gRateArray[i])
9602 return TRUE;
9603 }
9604 return FALSE;
9605}
9606
9607/* Check for 11g rate and set proper 11g only mode */
9608static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9609 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9610{
9611 u8 i, num_rates = pIe[0];
9612
9613 pIe += 1;
9614 for ( i = 0; i < num_rates; i++)
9615 {
9616 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9617 {
9618 /* If rate set have 11g rate than change the mode to 11G */
9619 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9620 if (pIe[i] & BASIC_RATE_MASK)
9621 {
9622 /* If we have 11g rate as basic rate, it means mode
9623 is 11g only mode.
9624 */
9625 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9626 *pCheckRatesfor11g = FALSE;
9627 }
9628 }
9629 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9630 {
9631 *require_ht = TRUE;
9632 }
9633 }
9634 return;
9635}
9636
9637static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9638{
9639 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9640 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9641 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9642 u8 checkRatesfor11g = TRUE;
9643 u8 require_ht = FALSE;
9644 u8 *pIe=NULL;
9645
9646 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9647
9648 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9649 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9650 if (pIe != NULL)
9651 {
9652 pIe += 1;
9653 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9654 &pConfig->SapHw_mode);
9655 }
9656
9657 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9658 WLAN_EID_EXT_SUPP_RATES);
9659 if (pIe != NULL)
9660 {
9661
9662 pIe += 1;
9663 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9664 &pConfig->SapHw_mode);
9665 }
9666
9667 if( pConfig->channel > 14 )
9668 {
9669 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9670 }
9671
9672 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9673 WLAN_EID_HT_CAPABILITY);
9674
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309675 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009676 {
9677 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9678 if(require_ht)
9679 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9680 }
9681}
9682
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309683static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9684 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9685{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009686 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309687 v_U8_t *pIe = NULL;
9688 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9689
9690 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9691 pBeacon->tail, pBeacon->tail_len);
9692
9693 if (pIe)
9694 {
9695 ielen = pIe[1] + 2;
9696 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9697 {
9698 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9699 }
9700 else
9701 {
9702 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9703 return -EINVAL;
9704 }
9705 *total_ielen += ielen;
9706 }
9707 return 0;
9708}
9709
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009710static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9711 v_U8_t *genie, v_U8_t *total_ielen)
9712{
9713 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9714 int left = pBeacon->tail_len;
9715 v_U8_t *ptr = pBeacon->tail;
9716 v_U8_t elem_id, elem_len;
9717 v_U16_t ielen = 0;
9718
9719 if ( NULL == ptr || 0 == left )
9720 return;
9721
9722 while (left >= 2)
9723 {
9724 elem_id = ptr[0];
9725 elem_len = ptr[1];
9726 left -= 2;
9727 if (elem_len > left)
9728 {
9729 hddLog( VOS_TRACE_LEVEL_ERROR,
9730 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9731 elem_id, elem_len, left);
9732 return;
9733 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309734 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009735 {
9736 /* skipping the VSIE's which we don't want to include or
9737 * it will be included by existing code
9738 */
9739 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9740#ifdef WLAN_FEATURE_WFD
9741 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9742#endif
9743 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9744 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9745 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9746 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9747 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9748 {
9749 ielen = ptr[1] + 2;
9750 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9751 {
9752 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9753 *total_ielen += ielen;
9754 }
9755 else
9756 {
9757 hddLog( VOS_TRACE_LEVEL_ERROR,
9758 "IE Length is too big "
9759 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9760 elem_id, elem_len, *total_ielen);
9761 }
9762 }
9763 }
9764
9765 left -= elem_len;
9766 ptr += (elem_len + 2);
9767 }
9768 return;
9769}
9770
Kapil Gupta137ef892016-12-13 19:38:00 +05309771int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009772{
9773 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309774 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009775 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009776 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309777 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009778
9779 genie = vos_mem_malloc(MAX_GENIE_LEN);
9780
9781 if(genie == NULL) {
9782
9783 return -ENOMEM;
9784 }
9785
Kapil Gupta137ef892016-12-13 19:38:00 +05309786 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309787 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9788 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009789 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309790 hddLog(LOGE,
9791 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309792 ret = -EINVAL;
9793 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009794 }
9795
9796#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309797 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9798 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9799 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309800 hddLog(LOGE,
9801 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309802 ret = -EINVAL;
9803 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009804 }
9805#endif
9806
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309807 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9808 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009809 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309810 hddLog(LOGE,
9811 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309812 ret = -EINVAL;
9813 goto done;
9814 }
9815
9816 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9817 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009818 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009819 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009820
9821 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9822 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9823 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9824 {
9825 hddLog(LOGE,
9826 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009827 ret = -EINVAL;
9828 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009829 }
9830
9831 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9832 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9833 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9834 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9835 ==eHAL_STATUS_FAILURE)
9836 {
9837 hddLog(LOGE,
9838 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009839 ret = -EINVAL;
9840 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009841 }
9842
9843 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309844 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009845 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309846 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009847 u8 probe_rsp_ie_len[3] = {0};
9848 u8 counter = 0;
9849 /* Check Probe Resp Length if it is greater then 255 then Store
9850 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9851 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9852 Store More then 255 bytes into One Variable.
9853 */
9854 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9855 {
9856 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9857 {
9858 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9859 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9860 }
9861 else
9862 {
9863 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9864 rem_probe_resp_ie_len = 0;
9865 }
9866 }
9867
9868 rem_probe_resp_ie_len = 0;
9869
9870 if (probe_rsp_ie_len[0] > 0)
9871 {
9872 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9873 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05309874 (tANI_U8*)&pBeacon->
9875 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009876 probe_rsp_ie_len[0], NULL,
9877 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9878 {
9879 hddLog(LOGE,
9880 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009881 ret = -EINVAL;
9882 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009883 }
9884 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9885 }
9886
9887 if (probe_rsp_ie_len[1] > 0)
9888 {
9889 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9890 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +05309891 (tANI_U8*)&pBeacon->
9892 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009893 probe_rsp_ie_len[1], NULL,
9894 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9895 {
9896 hddLog(LOGE,
9897 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009898 ret = -EINVAL;
9899 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009900 }
9901 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9902 }
9903
9904 if (probe_rsp_ie_len[2] > 0)
9905 {
9906 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9907 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +05309908 (tANI_U8*)&pBeacon->
9909 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009910 probe_rsp_ie_len[2], NULL,
9911 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9912 {
9913 hddLog(LOGE,
9914 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009915 ret = -EINVAL;
9916 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009917 }
9918 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9919 }
9920
9921 if (probe_rsp_ie_len[1] == 0 )
9922 {
9923 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9924 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9925 eANI_BOOLEAN_FALSE) )
9926 {
9927 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009928 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009929 }
9930 }
9931
9932 if (probe_rsp_ie_len[2] == 0 )
9933 {
9934 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9935 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9936 eANI_BOOLEAN_FALSE) )
9937 {
9938 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009939 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009940 }
9941 }
9942
9943 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9944 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9945 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9946 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9947 == eHAL_STATUS_FAILURE)
9948 {
9949 hddLog(LOGE,
9950 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009951 ret = -EINVAL;
9952 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009953 }
9954 }
9955 else
9956 {
9957 // Reset WNI_CFG_PROBE_RSP Flags
9958 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
9959
9960 hddLog(VOS_TRACE_LEVEL_INFO,
9961 "%s: No Probe Response IE received in set beacon",
9962 __func__);
9963 }
9964
9965 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309966 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009967 {
9968 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05309969 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
9970 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07009971 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9972 {
9973 hddLog(LOGE,
9974 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009975 ret = -EINVAL;
9976 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009977 }
9978
9979 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9980 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
9981 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9982 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9983 == eHAL_STATUS_FAILURE)
9984 {
9985 hddLog(LOGE,
9986 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009987 ret = -EINVAL;
9988 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009989 }
9990 }
9991 else
9992 {
9993 hddLog(VOS_TRACE_LEVEL_INFO,
9994 "%s: No Assoc Response IE received in set beacon",
9995 __func__);
9996
9997 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9998 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9999 eANI_BOOLEAN_FALSE) )
10000 {
10001 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010002 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010003 }
10004 }
10005
Jeff Johnsone7245742012-09-05 17:12:55 -070010006done:
Jeff Johnson295189b2012-06-20 16:38:30 -070010007 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010008 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010009}
Jeff Johnson295189b2012-06-20 16:38:30 -070010010
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010011/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010012 * FUNCTION: wlan_hdd_validate_operation_channel
10013 * called by wlan_hdd_cfg80211_start_bss() and
10014 * wlan_hdd_cfg80211_set_channel()
10015 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010016 * channel list.
10017 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -070010018VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010019{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010020
Jeff Johnson295189b2012-06-20 16:38:30 -070010021 v_U32_t num_ch = 0;
10022 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10023 u32 indx = 0;
10024 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010025 v_U8_t fValidChannel = FALSE, count = 0;
10026 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010027
Jeff Johnson295189b2012-06-20 16:38:30 -070010028 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10029
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010030 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010031 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010032 /* Validate the channel */
10033 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010034 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010035 if ( channel == rfChannels[count].channelNum )
10036 {
10037 fValidChannel = TRUE;
10038 break;
10039 }
10040 }
10041 if (fValidChannel != TRUE)
10042 {
10043 hddLog(VOS_TRACE_LEVEL_ERROR,
10044 "%s: Invalid Channel [%d]", __func__, channel);
10045 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010046 }
10047 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010048 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010049 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010050 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10051 valid_ch, &num_ch))
10052 {
10053 hddLog(VOS_TRACE_LEVEL_ERROR,
10054 "%s: failed to get valid channel list", __func__);
10055 return VOS_STATUS_E_FAILURE;
10056 }
10057 for (indx = 0; indx < num_ch; indx++)
10058 {
10059 if (channel == valid_ch[indx])
10060 {
10061 break;
10062 }
10063 }
10064
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010065 if (indx >= num_ch)
10066 {
10067 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10068 {
10069 eCsrBand band;
10070 unsigned int freq;
10071
10072 sme_GetFreqBand(hHal, &band);
10073
10074 if (eCSR_BAND_5G == band)
10075 {
10076#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10077 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10078 {
10079 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010080 HDD_NL80211_BAND_2GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010081 }
10082 else
10083 {
10084 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010085 HDD_NL80211_BAND_5GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010086 }
10087#else
10088 freq = ieee80211_channel_to_frequency(channel);
10089#endif
10090 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
10091 return VOS_STATUS_SUCCESS;
10092 }
10093 }
10094
10095 hddLog(VOS_TRACE_LEVEL_ERROR,
10096 "%s: Invalid Channel [%d]", __func__, channel);
10097 return VOS_STATUS_E_FAILURE;
10098 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010099 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010100
Jeff Johnson295189b2012-06-20 16:38:30 -070010101 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010102
Jeff Johnson295189b2012-06-20 16:38:30 -070010103}
10104
Viral Modi3a32cc52013-02-08 11:14:52 -080010105/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010106 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -080010107 * This function is used to set the channel number
10108 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010109static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -080010110 struct ieee80211_channel *chan,
10111 enum nl80211_channel_type channel_type
10112 )
10113{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010114 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -080010115 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -070010116 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -080010117 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010118 hdd_context_t *pHddCtx;
10119 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010120
10121 ENTER();
10122
10123 if( NULL == dev )
10124 {
10125 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010126 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010127 return -ENODEV;
10128 }
10129 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010130
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010131 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10132 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10133 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010134 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010135 "%s: device_mode = %s (%d) freq = %d", __func__,
10136 hdd_device_modetoString(pAdapter->device_mode),
10137 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010138
10139 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10140 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010141 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010142 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010143 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010144 }
10145
10146 /*
10147 * Do freq to chan conversion
10148 * TODO: for 11a
10149 */
10150
10151 channel = ieee80211_frequency_to_channel(freq);
10152
10153 /* Check freq range */
10154 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10155 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10156 {
10157 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010158 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010159 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10160 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10161 return -EINVAL;
10162 }
10163
10164 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10165
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010166 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10167 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010168 {
10169 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10170 {
10171 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010172 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010173 return -EINVAL;
10174 }
10175 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10176 "%s: set channel to [%d] for device mode =%d",
10177 __func__, channel,pAdapter->device_mode);
10178 }
10179 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010180 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010181 )
10182 {
10183 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10184 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10185 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10186
10187 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10188 {
10189 /* Link is up then return cant set channel*/
10190 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010191 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010192 return -EINVAL;
10193 }
10194
10195 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10196 pHddStaCtx->conn_info.operationChannel = channel;
10197 pRoamProfile->ChannelInfo.ChannelList =
10198 &pHddStaCtx->conn_info.operationChannel;
10199 }
10200 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010201 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010202 )
10203 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010204 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10205 {
10206 if(VOS_STATUS_SUCCESS !=
10207 wlan_hdd_validate_operation_channel(pAdapter,channel))
10208 {
10209 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010210 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010211 return -EINVAL;
10212 }
10213 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10214 }
10215 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010216 {
10217 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10218
10219 /* If auto channel selection is configured as enable/ 1 then ignore
10220 channel set by supplicant
10221 */
10222 if ( cfg_param->apAutoChannelSelection )
10223 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010224 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10225 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010226 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010227 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10228 __func__, hdd_device_modetoString(pAdapter->device_mode),
10229 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010230 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010231 else
10232 {
10233 if(VOS_STATUS_SUCCESS !=
10234 wlan_hdd_validate_operation_channel(pAdapter,channel))
10235 {
10236 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010237 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010238 return -EINVAL;
10239 }
10240 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10241 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010242 }
10243 }
10244 else
10245 {
10246 hddLog(VOS_TRACE_LEVEL_FATAL,
10247 "%s: Invalid device mode failed to set valid channel", __func__);
10248 return -EINVAL;
10249 }
10250 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010251 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010252}
10253
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010254static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10255 struct net_device *dev,
10256 struct ieee80211_channel *chan,
10257 enum nl80211_channel_type channel_type
10258 )
10259{
10260 int ret;
10261
10262 vos_ssr_protect(__func__);
10263 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10264 vos_ssr_unprotect(__func__);
10265
10266 return ret;
10267}
10268
Anurag Chouhan83026002016-12-13 22:46:21 +053010269#ifdef DHCP_SERVER_OFFLOAD
10270void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10271 VOS_STATUS status)
10272{
10273 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10274
10275 ENTER();
10276
10277 if (NULL == adapter)
10278 {
10279 hddLog(VOS_TRACE_LEVEL_ERROR,
10280 "%s: adapter is NULL",__func__);
10281 return;
10282 }
10283
10284 adapter->dhcp_status.dhcp_offload_status = status;
10285 vos_event_set(&adapter->dhcp_status.vos_event);
10286 return;
10287}
10288
10289/**
10290 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10291 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010292 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010293 *
10294 * Return: None
10295 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010296VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10297 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010298{
10299 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10300 sir_dhcp_srv_offload_info dhcp_srv_info;
10301 tANI_U8 num_entries = 0;
10302 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10303 tANI_U8 num;
10304 tANI_U32 temp;
10305 VOS_STATUS ret;
10306
10307 ENTER();
10308
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010309 if (!re_init) {
10310 ret = wlan_hdd_validate_context(hdd_ctx);
10311 if (0 != ret)
10312 return VOS_STATUS_E_INVAL;
10313 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010314
10315 /* Prepare the request to send to SME */
10316 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10317 if (NULL == dhcp_srv_info) {
10318 hddLog(VOS_TRACE_LEVEL_ERROR,
10319 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10320 return VOS_STATUS_E_NOMEM;
10321 }
10322
10323 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10324
10325 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10326 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10327 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10328 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10329 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10330 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10331
10332 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10333 srv_ip,
10334 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010335 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010336 if (num_entries != IPADDR_NUM_ENTRIES) {
10337 hddLog(VOS_TRACE_LEVEL_ERROR,
10338 "%s: incorrect IP address (%s) assigned for DHCP server!",
10339 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10340 vos_mem_free(dhcp_srv_info);
10341 return VOS_STATUS_E_FAILURE;
10342 }
10343
10344 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10345 hddLog(VOS_TRACE_LEVEL_ERROR,
10346 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10347 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10348 vos_mem_free(dhcp_srv_info);
10349 return VOS_STATUS_E_FAILURE;
10350 }
10351
10352 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10353 hddLog(VOS_TRACE_LEVEL_ERROR,
10354 "%s: invalid IP address (%s)! The last field must be less than 100!",
10355 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10356 vos_mem_free(dhcp_srv_info);
10357 return VOS_STATUS_E_FAILURE;
10358 }
10359
10360 for (num = 0; num < num_entries; num++) {
10361 temp = srv_ip[num];
10362 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10363 }
10364
10365 if (eHAL_STATUS_SUCCESS !=
10366 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10367 hddLog(VOS_TRACE_LEVEL_ERROR,
10368 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10369 vos_mem_free(dhcp_srv_info);
10370 return VOS_STATUS_E_FAILURE;
10371 }
10372
10373 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10374 "%s: enable DHCP Server offload successfully!", __func__);
10375
10376 vos_mem_free(dhcp_srv_info);
10377 return 0;
10378}
10379#endif /* DHCP_SERVER_OFFLOAD */
10380
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010381/*
10382 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10383 * @wiphy_chan: wiphy channel number
10384 * @rfChannel: channel hw value
10385 * @disable: Disable/enable the flags
10386 *
10387 * Modify wiphy flags and cds state if channel is indoor.
10388 *
10389 * Return: void
10390 */
10391void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
10392 v_U32_t rfChannel, bool disable)
10393{
10394 v_U32_t channelLoop;
10395 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10396
10397 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10398
10399 if (rfChannels[channelLoop].channelNum == rfChannel) {
10400 channelEnum = (eRfChannels)channelLoop;
10401 break;
10402 }
10403 }
10404
10405 if (INVALID_RF_CHANNEL == channelEnum)
10406 return;
10407
10408 if (disable) {
10409 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10410 wiphy_chan->flags |=
10411 IEEE80211_CHAN_DISABLED;
10412 regChannels[channelEnum].enabled =
10413 NV_CHANNEL_DISABLE;
10414 }
10415 } else {
10416 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10417 wiphy_chan->flags &=
10418 ~IEEE80211_CHAN_DISABLED;
10419 /*
10420 * Indoor channels are marked as DFS
10421 * during regulatory processing
10422 */
10423
10424 regChannels[channelEnum].enabled =
10425 NV_CHANNEL_DFS;
10426 }
10427 }
10428
10429}
10430
10431void hdd_update_indoor_channel(hdd_context_t *hdd_ctx,
10432 bool disable)
10433{
10434 int band_num;
10435 int chan_num;
10436 v_U32_t rfChannel;
10437 struct ieee80211_channel *wiphy_chan;
10438 struct wiphy *wiphy;
10439
10440 ENTER();
10441 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10442
10443 wiphy = hdd_ctx->wiphy;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010444 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010445
10446 if (wiphy->bands[band_num] == NULL)
10447 continue;
10448
10449 for (chan_num = 0;
10450 chan_num < wiphy->bands[band_num]->n_channels;
10451 chan_num++) {
10452
10453 wiphy_chan =
10454 &(wiphy->bands[band_num]->channels[chan_num]);
10455 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10456
10457 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
10458 disable);
10459 }
10460 }
10461 EXIT();
10462}
10463
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010464/*
10465 * FUNCTION: wlan_hdd_disconnect
10466 * This function is used to issue a disconnect request to SME
10467 */
10468int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10469{
10470 int status, result = 0;
10471 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10472 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10473 long ret;
10474 eConnectionState prev_conn_state;
10475 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
10476
10477 ENTER();
10478
10479 status = wlan_hdd_validate_context(pHddCtx);
10480 if (0 != status)
10481 {
10482 return status;
10483 }
10484 /* Indicate sme of disconnect so that in progress connection or preauth
10485 * can be aborted
10486 */
10487 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10488 pAdapter->sessionId);
10489 pHddCtx->isAmpAllowed = VOS_TRUE;
10490
10491 /* Need to apply spin lock before decreasing active sessions
10492 * as there can be chance for double decrement if context switch
10493 * Calls hdd_DisConnectHandler.
10494 */
10495
10496 prev_conn_state = pHddStaCtx->conn_info.connState;
10497
10498 spin_lock_bh(&pAdapter->lock_for_active_session);
10499 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10500 {
10501 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10502 }
10503 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10504 spin_unlock_bh(&pAdapter->lock_for_active_session);
10505 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
10506
10507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10508 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10509
10510 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10511
10512 /*
10513 * stop tx queues before deleting STA/BSS context from the firmware.
10514 * tx has to be disabled because the firmware can get busy dropping
10515 * the tx frames after BSS/STA has been deleted and will not send
10516 * back a response resulting in WDI timeout
10517 */
10518 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10519 netif_tx_disable(pAdapter->dev);
10520 netif_carrier_off(pAdapter->dev);
10521
10522 wlan_hdd_check_and_stop_mon(pAdapter, true);
10523
10524 /*issue disconnect*/
10525 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10526 pAdapter->sessionId, reason);
10527 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
10528 prev_conn_state != eConnectionState_Connecting)
10529 {
10530 hddLog(LOG1,
10531 FL("status = %d, already disconnected"), status);
10532 result = 0;
10533 /*
10534 * Wait here instead of returning directly. This will block the
10535 * next connect command and allow processing of the disconnect
10536 * in SME else we might hit some race conditions leading to SME
10537 * and HDD out of sync. As disconnect is already in progress,
10538 * wait here for 1 sec instead of 5 sec.
10539 */
10540 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
10541 goto wait_for_disconnect;
10542 }
10543 /*
10544 * Wait here instead of returning directly, this will block the next
10545 * connect command and allow processing of the scan for ssid and
10546 * the previous connect command in CSR. Else we might hit some
10547 * race conditions leading to SME and HDD out of sync.
10548 */
10549 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10550 {
10551 hddLog(LOG1,
10552 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
10553 }
10554 else if ( 0 != status )
10555 {
10556 hddLog(LOGE,
10557 FL("csrRoamDisconnect failure, returned %d"),
10558 (int)status);
10559 result = -EINVAL;
10560 goto disconnected;
10561 }
10562wait_for_disconnect:
10563 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
10564 msecs_to_jiffies(wait_time));
10565 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
10566 {
10567 hddLog(LOGE,
10568 "%s: Failed to disconnect, timed out", __func__);
10569 result = -ETIMEDOUT;
10570 }
10571disconnected:
10572 hddLog(LOG1,
10573 FL("Set HDD connState to eConnectionState_NotConnected"));
10574 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10575#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
10576 /* Sending disconnect event to userspace for kernel version < 3.11
10577 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
10578 */
10579 hddLog(LOG1, FL("Send disconnected event to userspace"));
10580
10581 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
10582 WLAN_REASON_UNSPECIFIED);
10583#endif
10584
10585 EXIT();
10586 return result;
10587}
10588
10589/*
10590 * hdd_check_and_disconnect_sta_on_invalid_channel() - Disconnect STA if it is
10591 * on indoor channel
10592 * @hdd_ctx: pointer to hdd context
10593 *
10594 * STA should be disconnected before starting the SAP if it is on indoor
10595 * channel.
10596 *
10597 * Return: void
10598 */
10599void hdd_check_and_disconnect_sta_on_invalid_channel(hdd_context_t *hdd_ctx)
10600{
10601
10602 hdd_adapter_t *sta_adapter;
10603 tANI_U8 sta_chan;
10604
10605 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
10606
10607 if (!sta_chan) {
10608 hddLog(LOG1, FL("STA not connected"));
10609 return;
10610 }
10611
10612 hddLog(LOG1, FL("STA connected on chan %hu"), sta_chan);
10613
10614 if (sme_IsChannelValid(hdd_ctx->hHal, sta_chan)) {
10615 hddLog(LOG1, FL("STA connected on chan %hu and it is valid"),
10616 sta_chan);
10617 return;
10618 }
10619
10620 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
10621
10622 if (!sta_adapter) {
10623 hddLog(LOG1, FL("STA adapter doesn't exist"));
10624 return;
10625 }
10626
10627 hddLog(LOG1, FL("chan %hu not valid, issue disconnect"), sta_chan);
10628 /* Issue Disconnect request */
10629 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10630}
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010631
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010632int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx)
10633{
10634 struct hdd_cache_channels *cache_chann;
10635 struct wiphy *wiphy;
10636 int freq, status, rfChannel;
10637 int i, band_num, channel_num;
10638 struct ieee80211_channel *wiphy_channel;
10639
10640 ENTER();
10641
10642 if (!hdd_ctx) {
10643 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10644 return -EINVAL;
10645 }
10646
10647 wiphy = hdd_ctx->wiphy;
10648
10649 mutex_lock(&hdd_ctx->cache_channel_lock);
10650
10651 cache_chann = hdd_ctx->orginal_channels;
10652
10653 if (!cache_chann || !cache_chann->num_channels) {
10654 hddLog(VOS_TRACE_LEVEL_INFO,
10655 "%s channel list is NULL or num channels are zero",
10656 __func__);
10657 mutex_unlock(&hdd_ctx->cache_channel_lock);
10658 return -EINVAL;
10659 }
10660
10661 for (i = 0; i < cache_chann->num_channels; i++) {
10662 status = hdd_wlan_get_freq(
10663 cache_chann->channel_info[i].channel_num,
10664 &freq);
10665
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010666 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
10667 band_num++) {
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010668 for (channel_num = 0; channel_num <
10669 wiphy->bands[band_num]->n_channels;
10670 channel_num++) {
10671 wiphy_channel = &(wiphy->bands[band_num]->
10672 channels[channel_num]);
10673 if (wiphy_channel->center_freq == freq) {
10674 rfChannel = wiphy_channel->hw_value;
10675 /*
10676 *Restore the orginal states
10677 *of the channels
10678 */
10679 vos_nv_set_channel_state(
10680 rfChannel,
10681 cache_chann->
10682 channel_info[i].reg_status);
10683 wiphy_channel->flags =
10684 cache_chann->
10685 channel_info[i].wiphy_status;
10686 break;
10687 }
10688 }
10689 if (channel_num < wiphy->bands[band_num]->n_channels)
10690 break;
10691 }
10692 }
10693
10694 mutex_unlock(&hdd_ctx->cache_channel_lock);
10695
10696 status = sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10697 if (status)
10698 hddLog(VOS_TRACE_LEVEL_ERROR, "Can't Restore channel list");
10699 EXIT();
10700
10701 return 0;
10702}
10703
10704/*
10705 * wlan_hdd_disable_channels() - Cache the the channels
10706 * and current state of the channels from the channel list
10707 * received in the command and disable the channels on the
10708 * wiphy and NV table.
10709 * @hdd_ctx: Pointer to hdd context
10710 *
10711 * @return: 0 on success, Error code on failure
10712 */
10713
10714static int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx)
10715{
10716 struct hdd_cache_channels *cache_chann;
10717 struct wiphy *wiphy;
10718 int freq, status, rfChannel;
10719 int i, band_num, band_ch_num;
10720 struct ieee80211_channel *wiphy_channel;
10721
10722 if (!hdd_ctx) {
10723 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10724 return -EINVAL;
10725 }
10726
10727 wiphy = hdd_ctx->wiphy;
10728
10729 mutex_lock(&hdd_ctx->cache_channel_lock);
10730 cache_chann = hdd_ctx->orginal_channels;
10731
10732 if (!cache_chann || !cache_chann->num_channels) {
10733 hddLog(VOS_TRACE_LEVEL_INFO,
10734 "%s channel list is NULL or num channels are zero",
10735 __func__);
10736 mutex_unlock(&hdd_ctx->cache_channel_lock);
10737 return -EINVAL;
10738 }
10739
10740 for (i = 0; i < cache_chann->num_channels; i++) {
10741 status = hdd_wlan_get_freq(
10742 cache_chann->channel_info[i].channel_num,
10743 &freq);
10744
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010745 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010746 band_num++) {
10747 for (band_ch_num = 0; band_ch_num <
10748 wiphy->bands[band_num]->n_channels;
10749 band_ch_num++) {
10750 wiphy_channel = &(wiphy->bands[band_num]->
10751 channels[band_ch_num]);
10752 if (wiphy_channel->center_freq == freq) {
10753 rfChannel = wiphy_channel->hw_value;
10754 /*
10755 * Cache the current states of
10756 * the channels
10757 */
10758 cache_chann->
10759 channel_info[i].reg_status =
10760 vos_nv_getChannelEnabledState(
10761 rfChannel);
10762
10763 cache_chann->
10764 channel_info[i].wiphy_status =
10765 wiphy_channel->flags;
10766 hddLog(VOS_TRACE_LEVEL_INFO,
10767 "Disable channel %d reg_stat %d wiphy_stat 0x%x",
10768 cache_chann->
10769 channel_info[i].channel_num,
10770 cache_chann->
10771 channel_info[i].reg_status,
10772 wiphy_channel->flags);
10773
10774 vos_nv_set_channel_state(
10775 rfChannel,
10776 NV_CHANNEL_DISABLE);
10777 wiphy_channel->flags |=
10778 IEEE80211_CHAN_DISABLED;
10779 break;
10780 }
10781 }
10782 if (band_ch_num < wiphy->bands[band_num]->n_channels)
10783 break;
10784 }
10785 }
10786
10787 mutex_unlock(&hdd_ctx->cache_channel_lock);
10788 sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10789 return 0;
10790}
10791
Jeff Johnson295189b2012-06-20 16:38:30 -070010792#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10793static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10794 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010795#else
10796static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10797 struct cfg80211_beacon_data *params,
10798 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010799 enum nl80211_hidden_ssid hidden_ssid,
10800 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010801#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010802{
10803 tsap_Config_t *pConfig;
10804 beacon_data_t *pBeacon = NULL;
10805 struct ieee80211_mgmt *pMgmt_frame;
10806 v_U8_t *pIe=NULL;
10807 v_U16_t capab_info;
10808 eCsrAuthType RSNAuthType;
10809 eCsrEncryptionType RSNEncryptType;
10810 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010811 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010812 tpWLAN_SAPEventCB pSapEventCallback;
10813 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070010814 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010815 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010816 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010817 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070010818 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080010819 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +053010820 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070010821 v_BOOL_t MFPCapable = VOS_FALSE;
10822 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010823 v_BOOL_t sapEnable11AC =
10824 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053010825 u_int16_t prev_rsn_length = 0;
10826
Jeff Johnson295189b2012-06-20 16:38:30 -070010827 ENTER();
10828
Nitesh Shah9b066282017-06-06 18:05:52 +053010829 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010830 iniConfig = pHddCtx->cfg_ini;
10831
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010832 /* Mark the indoor channel (passive) to disable */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053010833 if (iniConfig->disable_indoor_channel &&
10834 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010835 hdd_update_indoor_channel(pHddCtx, true);
10836
10837 if (!VOS_IS_STATUS_SUCCESS(
10838 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
10839 hdd_update_indoor_channel(pHddCtx, false);
10840 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
10841 FL("Can't start BSS: update channel list failed"));
10842 return eHAL_STATUS_FAILURE;
10843 }
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010844
10845 /* check if STA is on indoor channel */
10846 if (hdd_is_sta_sap_scc_allowed_on_dfs_chan(pHddCtx))
10847 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010848 }
10849
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010850 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
10851 /* Disable the channels received in command SET_DISABLE_CHANNEL_LIST*/
10852 wlan_hdd_disable_channels(pHddCtx);
10853 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
10854 }
10855
Jeff Johnson295189b2012-06-20 16:38:30 -070010856 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
10857
10858 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
10859
10860 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
10861
10862 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
10863
10864 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
10865
10866 //channel is already set in the set_channel Call back
10867 //pConfig->channel = pCommitConfig->channel;
10868
10869 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010870 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070010871 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
10872
10873 pConfig->dtim_period = pBeacon->dtim_period;
10874
Arif Hussain6d2a3322013-11-17 19:50:10 -080010875 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070010876 pConfig->dtim_period);
10877
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080010878 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070010879 {
10880 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010881 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053010882 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
10883 {
10884 tANI_BOOLEAN restartNeeded;
10885 pConfig->ieee80211d = 1;
10886 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
10887 sme_setRegInfo(hHal, pConfig->countryCode);
10888 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
10889 }
10890 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070010891 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070010892 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070010893 pConfig->ieee80211d = 1;
10894 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
10895 sme_setRegInfo(hHal, pConfig->countryCode);
10896 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070010897 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010898 else
10899 {
10900 pConfig->ieee80211d = 0;
10901 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010902 /*
10903 * If auto channel is configured i.e. channel is 0,
10904 * so skip channel validation.
10905 */
10906 if( AUTO_CHANNEL_SELECT != pConfig->channel )
10907 {
10908 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
10909 {
10910 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010911 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010912 ret = -EINVAL;
10913 goto error;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010914 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010915 pConfig->user_config_channel = pConfig->channel;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010916 }
10917 else
10918 {
10919 if(1 != pHddCtx->is_dynamic_channel_range_set)
10920 {
10921 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
10922 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
10923 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
10924 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010925 pHddCtx->is_dynamic_channel_range_set = 0;
10926 pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010927 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010928 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010929 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010930 {
10931 pConfig->ieee80211d = 0;
10932 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010933
10934#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10935 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10936 pConfig->authType = eSAP_OPEN_SYSTEM;
10937 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10938 pConfig->authType = eSAP_SHARED_KEY;
10939 else
10940 pConfig->authType = eSAP_AUTO_SWITCH;
10941#else
10942 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10943 pConfig->authType = eSAP_OPEN_SYSTEM;
10944 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10945 pConfig->authType = eSAP_SHARED_KEY;
10946 else
10947 pConfig->authType = eSAP_AUTO_SWITCH;
10948#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010949
10950 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010951
10952 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070010953 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053010954#ifdef SAP_AUTH_OFFLOAD
10955 /* In case of sap offload, hostapd.conf is configuted with open mode and
10956 * security is configured from ini file. Due to open mode in hostapd.conf
10957 * privacy bit is set to false which will result in not sending,
10958 * data packets as encrypted.
10959 * If enable_sap_auth_offload is enabled in ini and
10960 * sap_auth_offload_sec_type is type of WPA2-PSK,
10961 * driver will set privacy bit to 1.
10962 */
10963 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
10964 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
10965 pConfig->privacy = VOS_TRUE;
10966#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010967
10968 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
10969
10970 /*Set wps station to configured*/
10971 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
10972
10973 if(pIe)
10974 {
10975 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
10976 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010977 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010978 ret = -EINVAL;
10979 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070010980 }
10981 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
10982 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070010983 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070010984 /* Check 15 bit of WPS IE as it contain information for wps state
10985 * WPS state
10986 */
10987 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
10988 {
10989 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
10990 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
10991 {
10992 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
10993 }
10994 }
10995 }
10996 else
10997 {
10998 pConfig->wps_state = SAP_WPS_DISABLED;
10999 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011000 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070011001
c_hpothufe599e92014-06-16 11:38:55 +053011002 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11003 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11004 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
11005 eCSR_ENCRYPT_TYPE_NONE;
11006
Jeff Johnson295189b2012-06-20 16:38:30 -070011007 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053011008 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011009 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011010 WLAN_EID_RSN);
11011 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011012 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011013 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011014 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11015 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11016 pConfig->RSNWPAReqIELength);
11017 else
11018 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11019 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011020 /* The actual processing may eventually be more extensive than
11021 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070011022 * by the app.
11023 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011024 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011025 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11026 &RSNEncryptType,
11027 &mcRSNEncryptType,
11028 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011029 &MFPCapable,
11030 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011031 pConfig->RSNWPAReqIE[1]+2,
11032 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011033
11034 if( VOS_STATUS_SUCCESS == status )
11035 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011036 /* Now copy over all the security attributes you have
11037 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011038 * */
11039 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11040 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11041 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11042 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011043 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011044 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011045 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11046 }
11047 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011048
Jeff Johnson295189b2012-06-20 16:38:30 -070011049 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11050 pBeacon->tail, pBeacon->tail_len);
11051
11052 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
11053 {
Kapil Gupta137ef892016-12-13 19:38:00 +053011054 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011055 {
11056 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053011057 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070011058 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011059 if (pConfig->RSNWPAReqIELength <=
11060 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
11061 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
11062 pIe[1] + 2);
11063 else
11064 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11065 pConfig->RSNWPAReqIELength);
11066
Jeff Johnson295189b2012-06-20 16:38:30 -070011067 }
11068 else
11069 {
11070 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011071 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11072 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11073 pConfig->RSNWPAReqIELength);
11074 else
11075 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11076 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011077 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011078 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11079 &RSNEncryptType,
11080 &mcRSNEncryptType,
11081 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011082 &MFPCapable,
11083 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011084 pConfig->RSNWPAReqIE[1]+2,
11085 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011086
11087 if( VOS_STATUS_SUCCESS == status )
11088 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011089 /* Now copy over all the security attributes you have
11090 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011091 * */
11092 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11093 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11094 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11095 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011096 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011097 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011098 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11099 }
11100 }
11101 }
11102
Kapil Gupta137ef892016-12-13 19:38:00 +053011103 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070011104 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011105 ret = -EINVAL;
11106 goto error;
Jeff Johnson4416a782013-03-25 14:17:50 -070011107 }
11108
Jeff Johnson295189b2012-06-20 16:38:30 -070011109 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
11110
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011111#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011112 if (params->ssid != NULL)
11113 {
11114 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
11115 pConfig->SSIDinfo.ssid.length = params->ssid_len;
11116 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11117 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11118 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011119#else
11120 if (ssid != NULL)
11121 {
11122 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
11123 pConfig->SSIDinfo.ssid.length = ssid_len;
11124 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11125 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11126 }
11127#endif
11128
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011129 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070011130 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011131
Jeff Johnson295189b2012-06-20 16:38:30 -070011132 /* default value */
11133 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
11134 pConfig->num_accept_mac = 0;
11135 pConfig->num_deny_mac = 0;
11136
11137 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11138 pBeacon->tail, pBeacon->tail_len);
11139
11140 /* pIe for black list is following form:
11141 type : 1 byte
11142 length : 1 byte
11143 OUI : 4 bytes
11144 acl type : 1 byte
11145 no of mac addr in black list: 1 byte
11146 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011147 */
11148 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011149 {
11150 pConfig->SapMacaddr_acl = pIe[6];
11151 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011152 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011153 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011154 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
11155 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011156 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11157 for (i = 0; i < pConfig->num_deny_mac; i++)
11158 {
11159 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11160 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011161 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011162 }
11163 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11164 pBeacon->tail, pBeacon->tail_len);
11165
11166 /* pIe for white list is following form:
11167 type : 1 byte
11168 length : 1 byte
11169 OUI : 4 bytes
11170 acl type : 1 byte
11171 no of mac addr in white list: 1 byte
11172 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011173 */
11174 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011175 {
11176 pConfig->SapMacaddr_acl = pIe[6];
11177 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011178 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011179 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011180 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
11181 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011182 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11183 for (i = 0; i < pConfig->num_accept_mac; i++)
11184 {
11185 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11186 acl_entry++;
11187 }
11188 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011189
Jeff Johnson295189b2012-06-20 16:38:30 -070011190 wlan_hdd_set_sapHwmode(pHostapdAdapter);
11191
Jeff Johnsone7245742012-09-05 17:12:55 -070011192#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011193 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011194 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
11195 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053011196 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
11197 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011198 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
11199 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011200 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
11201 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070011202 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011203 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070011204 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011205 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011206
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011207 /* If ACS disable and selected channel <= 14
11208 * OR
11209 * ACS enabled and ACS operating band is choosen as 2.4
11210 * AND
11211 * VHT in 2.4G Disabled
11212 * THEN
11213 * Fallback to 11N mode
11214 */
11215 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
11216 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053011217 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011218 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011219 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011220 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
11221 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011222 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
11223 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011224 }
11225#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011226
Jeff Johnson295189b2012-06-20 16:38:30 -070011227 // ht_capab is not what the name conveys,this is used for protection bitmap
11228 pConfig->ht_capab =
11229 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
11230
Kapil Gupta137ef892016-12-13 19:38:00 +053011231 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070011232 {
11233 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011234 ret = -EINVAL;
11235 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011236 }
11237
11238 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011239 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070011240 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
11241 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011242 pConfig->obssProtEnabled =
11243 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070011244
Chet Lanctot8cecea22014-02-11 19:09:36 -080011245#ifdef WLAN_FEATURE_11W
11246 pConfig->mfpCapable = MFPCapable;
11247 pConfig->mfpRequired = MFPRequired;
11248 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
11249 pConfig->mfpCapable, pConfig->mfpRequired);
11250#endif
11251
Arif Hussain6d2a3322013-11-17 19:50:10 -080011252 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070011253 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011254 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
11255 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
11256 (int)pConfig->channel);
11257 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
11258 pConfig->SapHw_mode, pConfig->privacy,
11259 pConfig->authType);
11260 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
11261 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
11262 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
11263 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070011264
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011265 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070011266 {
11267 //Bss already started. just return.
11268 //TODO Probably it should update some beacon params.
11269 hddLog( LOGE, "Bss Already started...Ignore the request");
11270 EXIT();
11271 return 0;
11272 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011273
Agarwal Ashish51325b52014-06-16 16:50:49 +053011274 if (vos_max_concurrent_connections_reached()) {
11275 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011276 ret = -EINVAL;
11277 goto error;
Agarwal Ashish51325b52014-06-16 16:50:49 +053011278 }
11279
Jeff Johnson295189b2012-06-20 16:38:30 -070011280 pConfig->persona = pHostapdAdapter->device_mode;
11281
Peng Xu2446a892014-09-05 17:21:18 +053011282 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
11283 if ( NULL != psmeConfig)
11284 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011285 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053011286 sme_GetConfigParam(hHal, psmeConfig);
11287 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011288#ifdef WLAN_FEATURE_AP_HT40_24G
11289 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11290 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
11291 && pHddCtx->cfg_ini->apHT40_24GEnabled)
11292 {
11293 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
11294 sme_UpdateConfig (hHal, psmeConfig);
11295 }
11296#endif
Peng Xu2446a892014-09-05 17:21:18 +053011297 vos_mem_free(psmeConfig);
11298 }
Peng Xuafc34e32014-09-25 13:23:55 +053011299 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053011300
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011301 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
11302
Jeff Johnson295189b2012-06-20 16:38:30 -070011303 pSapEventCallback = hdd_hostapd_SAPEventCB;
11304 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
11305 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
11306 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011307 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011308 ret = -EINVAL;
11309 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011310 }
11311
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011312 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070011313 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
11314
11315 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011316
Jeff Johnson295189b2012-06-20 16:38:30 -070011317 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011318 {
11319 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011320 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070011321 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011322 VOS_ASSERT(0);
11323 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011324
Jeff Johnson295189b2012-06-20 16:38:30 -070011325 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053011326 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
11327 VOS_STATUS_SUCCESS)
11328 {
11329 hddLog(LOGE,FL("Fail to get Softap sessionID"));
11330 VOS_ASSERT(0);
11331 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053011332 /* Initialize WMM configuation */
11333 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011334 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011335
Anurag Chouhan83026002016-12-13 22:46:21 +053011336#ifdef DHCP_SERVER_OFFLOAD
11337 /* set dhcp server offload */
11338 if (iniConfig->enable_dhcp_srv_offload &&
11339 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011340 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053011341 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053011342 if (!VOS_IS_STATUS_SUCCESS(status))
11343 {
11344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11345 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011346 vos_event_reset(&pHostapdState->vosEvent);
11347 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11348 status = vos_wait_single_event(&pHostapdState->vosEvent,
11349 10000);
11350 if (!VOS_IS_STATUS_SUCCESS(status)) {
11351 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011352 ret = -EINVAL;
11353 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011354 }
11355 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011356 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011357 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
11358 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
11359 {
11360 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11361 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
11362 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011363 vos_event_reset(&pHostapdState->vosEvent);
11364 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11365 status = vos_wait_single_event(&pHostapdState->vosEvent,
11366 10000);
11367 if (!VOS_IS_STATUS_SUCCESS(status)) {
11368 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011369 ret = -EINVAL;
11370 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011371 }
11372 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011373 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011374#ifdef MDNS_OFFLOAD
11375 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011376 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011377 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
11378 if (VOS_IS_STATUS_SUCCESS(status))
11379 {
11380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11381 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011382 vos_event_reset(&pHostapdState->vosEvent);
11383 if (VOS_STATUS_SUCCESS ==
11384 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11385 status = vos_wait_single_event(&pHostapdState->vosEvent,
11386 10000);
11387 if (!VOS_IS_STATUS_SUCCESS(status)) {
11388 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011389 ret = -EINVAL;
11390 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011391 }
11392 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011393 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011394 status = vos_wait_single_event(&pHostapdAdapter->
11395 mdns_status.vos_event, 2000);
11396 if (!VOS_IS_STATUS_SUCCESS(status) ||
11397 pHostapdAdapter->mdns_status.mdns_enable_status ||
11398 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
11399 pHostapdAdapter->mdns_status.mdns_resp_status)
11400 {
11401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11402 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
11403 pHostapdAdapter->mdns_status.mdns_enable_status,
11404 pHostapdAdapter->mdns_status.mdns_fqdn_status,
11405 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011406 vos_event_reset(&pHostapdState->vosEvent);
11407 if (VOS_STATUS_SUCCESS ==
11408 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11409 status = vos_wait_single_event(&pHostapdState->vosEvent,
11410 10000);
11411 if (!VOS_IS_STATUS_SUCCESS(status)) {
11412 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011413 ret = -EINVAL;
11414 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011415 }
11416 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011417 }
11418 }
11419#endif /* MDNS_OFFLOAD */
11420 } else {
11421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11422 ("DHCP Disabled ini %d, FW %d"),
11423 iniConfig->enable_dhcp_srv_offload,
11424 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053011425 }
11426#endif /* DHCP_SERVER_OFFLOAD */
11427
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011428#ifdef WLAN_FEATURE_P2P_DEBUG
11429 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
11430 {
11431 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
11432 {
11433 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11434 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011435 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011436 }
11437 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
11438 {
11439 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11440 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011441 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011442 }
11443 }
11444#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053011445 /* Check and restart SAP if it is on Unsafe channel */
11446 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011447
Jeff Johnson295189b2012-06-20 16:38:30 -070011448 pHostapdState->bCommit = TRUE;
11449 EXIT();
11450
11451 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011452error:
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011453 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11454 wlan_hdd_restore_channels(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011455 /* Revert the indoor to passive marking if START BSS fails */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011456 if (iniConfig->disable_indoor_channel &&
11457 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011458 hdd_update_indoor_channel(pHddCtx, false);
11459 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
11460 }
11461
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011462 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
11463 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011464}
11465
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011466#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011467static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011468 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011469 struct beacon_parameters *params)
11470{
11471 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011472 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011473 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011474
11475 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011476
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011477 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11478 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11479 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011480 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11481 hdd_device_modetoString(pAdapter->device_mode),
11482 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011483
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011484 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11485 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011486 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011487 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011488 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011489 }
11490
Agarwal Ashish51325b52014-06-16 16:50:49 +053011491 if (vos_max_concurrent_connections_reached()) {
11492 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11493 return -EINVAL;
11494 }
11495
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011496 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011497 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011498 )
11499 {
11500 beacon_data_t *old,*new;
11501
11502 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011503
Jeff Johnson295189b2012-06-20 16:38:30 -070011504 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011505 {
11506 hddLog(VOS_TRACE_LEVEL_WARN,
11507 FL("already beacon info added to session(%d)"),
11508 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011509 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011510 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011511
11512 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11513
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011514 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011515 {
11516 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011517 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011518 return -EINVAL;
11519 }
11520
11521 pAdapter->sessionCtx.ap.beacon = new;
11522
11523 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11524 }
11525
11526 EXIT();
11527 return status;
11528}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011529
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011530static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11531 struct net_device *dev,
11532 struct beacon_parameters *params)
11533{
11534 int ret;
11535
11536 vos_ssr_protect(__func__);
11537 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11538 vos_ssr_unprotect(__func__);
11539
11540 return ret;
11541}
11542
11543static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011544 struct net_device *dev,
11545 struct beacon_parameters *params)
11546{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011547 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011548 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11549 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011550 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011551
11552 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011553
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011554 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11555 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11556 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11557 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11558 __func__, hdd_device_modetoString(pAdapter->device_mode),
11559 pAdapter->device_mode);
11560
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011561 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11562 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011563 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011564 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011565 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011566 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011567
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011568 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011569 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011570 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011571 {
11572 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011573
Jeff Johnson295189b2012-06-20 16:38:30 -070011574 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011575
Jeff Johnson295189b2012-06-20 16:38:30 -070011576 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011577 {
11578 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11579 FL("session(%d) old and new heads points to NULL"),
11580 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011581 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011582 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011583
11584 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11585
11586 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011587 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011588 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011589 return -EINVAL;
11590 }
11591
11592 pAdapter->sessionCtx.ap.beacon = new;
11593
11594 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11595 }
11596
11597 EXIT();
11598 return status;
11599}
11600
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011601static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11602 struct net_device *dev,
11603 struct beacon_parameters *params)
11604{
11605 int ret;
11606
11607 vos_ssr_protect(__func__);
11608 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11609 vos_ssr_unprotect(__func__);
11610
11611 return ret;
11612}
11613
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011614#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11615
11616#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011617static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011618 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011619#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011620static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011621 struct net_device *dev)
11622#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011623{
11624 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070011625 hdd_context_t *pHddCtx = NULL;
11626 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011627 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011628 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011629
11630 ENTER();
11631
11632 if (NULL == pAdapter)
11633 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011635 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011636 return -ENODEV;
11637 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011638
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011639 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11640 TRACE_CODE_HDD_CFG80211_STOP_AP,
11641 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011642 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11643 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011644 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011645 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011646 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011647 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011648
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011649 pScanInfo = &pHddCtx->scan_info;
11650
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011651 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11652 __func__, hdd_device_modetoString(pAdapter->device_mode),
11653 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011654
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011655 ret = wlan_hdd_scan_abort(pAdapter);
11656
Girish Gowli4bf7a632014-06-12 13:42:11 +053011657 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011658 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11660 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011661
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011662 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011663 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11665 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011666
Jeff Johnsone7245742012-09-05 17:12:55 -070011667 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011668 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011669 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011670 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011671 }
11672
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011673 /* Delete all associated STAs before stopping AP/P2P GO */
11674 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011675 hdd_hostapd_stop(dev);
11676
Jeff Johnson295189b2012-06-20 16:38:30 -070011677 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011678 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011679 )
11680 {
11681 beacon_data_t *old;
11682
11683 old = pAdapter->sessionCtx.ap.beacon;
11684
11685 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011686 {
11687 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11688 FL("session(%d) beacon data points to NULL"),
11689 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011690 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011691 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011692
Jeff Johnson295189b2012-06-20 16:38:30 -070011693 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011694
11695 mutex_lock(&pHddCtx->sap_lock);
11696 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11697 {
Abhishek Singh10e17cf2018-03-12 14:34:22 +053011698 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
11699 hdd_wait_for_ecsa_complete(pHddCtx);
Jeff Johnson4416a782013-03-25 14:17:50 -070011700 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011701 {
11702 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11703
11704 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11705
11706 if (!VOS_IS_STATUS_SUCCESS(status))
11707 {
11708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011709 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011710 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011711 }
11712 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011713 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011714 /* BSS stopped, clear the active sessions for this device mode */
11715 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011716 }
11717 mutex_unlock(&pHddCtx->sap_lock);
11718
11719 if(status != VOS_STATUS_SUCCESS)
11720 {
11721 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011722 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011723 return -EINVAL;
11724 }
11725
Jeff Johnson4416a782013-03-25 14:17:50 -070011726 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011727 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11728 ==eHAL_STATUS_FAILURE)
11729 {
11730 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011731 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011732 }
11733
Jeff Johnson4416a782013-03-25 14:17:50 -070011734 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011735 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11736 eANI_BOOLEAN_FALSE) )
11737 {
11738 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011739 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011740 }
11741
11742 // Reset WNI_CFG_PROBE_RSP Flags
11743 wlan_hdd_reset_prob_rspies(pAdapter);
11744
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011745 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11746
Jeff Johnson295189b2012-06-20 16:38:30 -070011747 pAdapter->sessionCtx.ap.beacon = NULL;
11748 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011749#ifdef WLAN_FEATURE_P2P_DEBUG
11750 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11751 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11752 {
11753 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11754 "GO got removed");
11755 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11756 }
11757#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011758 }
11759 EXIT();
11760 return status;
11761}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011762
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011763#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11764static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
11765 struct net_device *dev)
11766{
11767 int ret;
11768
11769 vos_ssr_protect(__func__);
11770 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
11771 vos_ssr_unprotect(__func__);
11772
11773 return ret;
11774}
11775#else
11776static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
11777 struct net_device *dev)
11778{
11779 int ret;
11780
11781 vos_ssr_protect(__func__);
11782 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
11783 vos_ssr_unprotect(__func__);
11784
11785 return ret;
11786}
11787#endif
11788
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011789#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
11790
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011791static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011792 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011793 struct cfg80211_ap_settings *params)
11794{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011795 hdd_adapter_t *pAdapter;
11796 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011797 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011798
11799 ENTER();
11800
Girish Gowlib143d7a2015-02-18 19:39:55 +053011801 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011802 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053011804 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011805 return -ENODEV;
11806 }
11807
11808 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11809 if (NULL == pAdapter)
11810 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011811 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011812 "%s: HDD adapter is Null", __func__);
11813 return -ENODEV;
11814 }
11815
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011816 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11817 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
11818 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011819 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
11820 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011822 "%s: HDD adapter magic is invalid", __func__);
11823 return -ENODEV;
11824 }
11825
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011826 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11827
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011828 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011829 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011830 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011831 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011832 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011833 }
11834
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011835 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
11836 __func__, hdd_device_modetoString(pAdapter->device_mode),
11837 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011838
11839 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011840 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011841 )
11842 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011843 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011844
11845 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011846
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011847 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011848 {
11849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
11850 FL("already beacon info added to session(%d)"),
11851 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011852 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011853 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011854
Girish Gowlib143d7a2015-02-18 19:39:55 +053011855#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11856 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11857 &new,
11858 &params->beacon);
11859#else
11860 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11861 &new,
11862 &params->beacon,
11863 params->dtim_period);
11864#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011865
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011866 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011867 {
11868 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011869 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011870 return -EINVAL;
11871 }
11872 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080011873#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070011874 wlan_hdd_cfg80211_set_channel(wiphy, dev,
11875#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
11876 params->channel, params->channel_type);
11877#else
11878 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
11879#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080011880#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011881 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011882 params->ssid_len, params->hidden_ssid,
11883 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011884 }
11885
11886 EXIT();
11887 return status;
11888}
11889
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011890static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
11891 struct net_device *dev,
11892 struct cfg80211_ap_settings *params)
11893{
11894 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011895
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011896 vos_ssr_protect(__func__);
11897 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
11898 vos_ssr_unprotect(__func__);
11899
11900 return ret;
11901}
11902
11903static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011904 struct net_device *dev,
11905 struct cfg80211_beacon_data *params)
11906{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011907 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011908 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011909 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011910
11911 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011912
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011913 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11914 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
11915 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011916 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011917 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011918
11919 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11920 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011921 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011922 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011923 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011924 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011925
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011926 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011927 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011928 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011929 {
11930 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011931
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011932 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011933
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011934 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011935 {
11936 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11937 FL("session(%d) beacon data points to NULL"),
11938 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011939 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011940 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011941
11942 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
11943
11944 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011945 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011946 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011947 return -EINVAL;
11948 }
11949
11950 pAdapter->sessionCtx.ap.beacon = new;
11951
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011952 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
11953 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011954 }
11955
11956 EXIT();
11957 return status;
11958}
11959
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011960static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
11961 struct net_device *dev,
11962 struct cfg80211_beacon_data *params)
11963{
11964 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011965
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011966 vos_ssr_protect(__func__);
11967 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
11968 vos_ssr_unprotect(__func__);
11969
11970 return ret;
11971}
11972
11973#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011974
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011975static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011976 struct net_device *dev,
11977 struct bss_parameters *params)
11978{
11979 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011980 hdd_context_t *pHddCtx;
11981 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011982
11983 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011984
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011985 if (NULL == pAdapter)
11986 {
11987 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11988 "%s: HDD adapter is Null", __func__);
11989 return -ENODEV;
11990 }
11991 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011992 ret = wlan_hdd_validate_context(pHddCtx);
11993 if (0 != ret)
11994 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011995 return ret;
11996 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011997 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11998 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
11999 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012000 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12001 __func__, hdd_device_modetoString(pAdapter->device_mode),
12002 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012003
12004 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012005 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012006 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012007 {
12008 /* ap_isolate == -1 means that in change bss, upper layer doesn't
12009 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012010 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070012011 {
12012 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012013 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012014 }
12015
12016 EXIT();
12017 return 0;
12018}
12019
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012020static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
12021 struct net_device *dev,
12022 struct bss_parameters *params)
12023{
12024 int ret;
12025
12026 vos_ssr_protect(__func__);
12027 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
12028 vos_ssr_unprotect(__func__);
12029
12030 return ret;
12031}
Kiet Lam10841362013-11-01 11:36:50 +053012032/* FUNCTION: wlan_hdd_change_country_code_cd
12033* to wait for contry code completion
12034*/
12035void* wlan_hdd_change_country_code_cb(void *pAdapter)
12036{
12037 hdd_adapter_t *call_back_pAdapter = pAdapter;
12038 complete(&call_back_pAdapter->change_country_code);
12039 return NULL;
12040}
12041
Jeff Johnson295189b2012-06-20 16:38:30 -070012042/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012043 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070012044 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
12045 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012046int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012047 struct net_device *ndev,
12048 enum nl80211_iftype type,
12049 u32 *flags,
12050 struct vif_params *params
12051 )
12052{
12053 struct wireless_dev *wdev;
12054 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012055 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070012056 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012057 tCsrRoamProfile *pRoamProfile = NULL;
12058 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012059 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012060 eMib_dot11DesiredBssType connectedBssType;
12061 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012062 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012063
12064 ENTER();
12065
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012066 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012067 {
12068 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12069 "%s: Adapter context is null", __func__);
12070 return VOS_STATUS_E_FAILURE;
12071 }
12072
12073 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12074 if (!pHddCtx)
12075 {
12076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12077 "%s: HDD context is null", __func__);
12078 return VOS_STATUS_E_FAILURE;
12079 }
12080
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012081 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12082 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
12083 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012084 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012085 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012086 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012087 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012088 }
12089
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012090 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12091 __func__, hdd_device_modetoString(pAdapter->device_mode),
12092 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012093
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012094 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
12095 hddLog(VOS_TRACE_LEVEL_FATAL,
12096 "%s: STA + MON is in progress, cannot change interface",
12097 __func__);
12098 }
12099
Agarwal Ashish51325b52014-06-16 16:50:49 +053012100 if (vos_max_concurrent_connections_reached()) {
12101 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12102 return -EINVAL;
12103 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012104 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012105 wdev = ndev->ieee80211_ptr;
12106
12107#ifdef WLAN_BTAMP_FEATURE
12108 if((NL80211_IFTYPE_P2P_CLIENT == type)||
12109 (NL80211_IFTYPE_ADHOC == type)||
12110 (NL80211_IFTYPE_AP == type)||
12111 (NL80211_IFTYPE_P2P_GO == type))
12112 {
12113 pHddCtx->isAmpAllowed = VOS_FALSE;
12114 // stop AMP traffic
12115 status = WLANBAP_StopAmp();
12116 if(VOS_STATUS_SUCCESS != status )
12117 {
12118 pHddCtx->isAmpAllowed = VOS_TRUE;
12119 hddLog(VOS_TRACE_LEVEL_FATAL,
12120 "%s: Failed to stop AMP", __func__);
12121 return -EINVAL;
12122 }
12123 }
12124#endif //WLAN_BTAMP_FEATURE
12125 /* Reset the current device mode bit mask*/
12126 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
12127
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053012128 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
12129 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
12130 (type == NL80211_IFTYPE_P2P_GO)))
12131 {
12132 /* Notify Mode change in case of concurrency.
12133 * Below function invokes TDLS teardown Functionality Since TDLS is
12134 * not Supported in case of concurrency i.e Once P2P session
12135 * is detected disable offchannel and teardown TDLS links
12136 */
12137 hddLog(LOG1,
12138 FL("Device mode = %d Interface type = %d"),
12139 pAdapter->device_mode, type);
12140 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
12141 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053012142
Jeff Johnson295189b2012-06-20 16:38:30 -070012143 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012144 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070012145 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012146 )
12147 {
12148 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012149 if (!pWextState)
12150 {
12151 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12152 "%s: pWextState is null", __func__);
12153 return VOS_STATUS_E_FAILURE;
12154 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012155 pRoamProfile = &pWextState->roamProfile;
12156 LastBSSType = pRoamProfile->BSSType;
12157
12158 switch (type)
12159 {
12160 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012161 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012162 hddLog(VOS_TRACE_LEVEL_INFO,
12163 "%s: setting interface Type to INFRASTRUCTURE", __func__);
12164 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012165#ifdef WLAN_FEATURE_11AC
12166 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
12167 {
12168 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
12169 }
12170#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012171 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070012172 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012173 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012174 //Check for sub-string p2p to confirm its a p2p interface
12175 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012176 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053012177#ifdef FEATURE_WLAN_TDLS
12178 mutex_lock(&pHddCtx->tdls_lock);
12179 wlan_hdd_tdls_exit(pAdapter, TRUE);
12180 mutex_unlock(&pHddCtx->tdls_lock);
12181#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012182 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12183 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12184 }
12185 else
12186 {
12187 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012188 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012189 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012190 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053012191
Jeff Johnson295189b2012-06-20 16:38:30 -070012192 case NL80211_IFTYPE_ADHOC:
12193 hddLog(VOS_TRACE_LEVEL_INFO,
12194 "%s: setting interface Type to ADHOC", __func__);
12195 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
12196 pRoamProfile->phyMode =
12197 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070012198 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012199 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053012200 hdd_set_ibss_ops( pAdapter );
12201 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053012202
12203 status = hdd_sta_id_hash_attach(pAdapter);
12204 if (VOS_STATUS_SUCCESS != status) {
12205 hddLog(VOS_TRACE_LEVEL_ERROR,
12206 FL("Failed to initialize hash for IBSS"));
12207 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012208 break;
12209
12210 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012211 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012212 {
12213 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12214 "%s: setting interface Type to %s", __func__,
12215 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
12216
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012217 //Cancel any remain on channel for GO mode
12218 if (NL80211_IFTYPE_P2P_GO == type)
12219 {
12220 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
12221 }
Mohit Khanna0f232092012-09-11 14:46:08 -070012222 if (NL80211_IFTYPE_AP == type)
12223 {
12224 /* As Loading WLAN Driver one interface being created for p2p device
12225 * address. This will take one HW STA and the max number of clients
12226 * that can connect to softAP will be reduced by one. so while changing
12227 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
12228 * interface as it is not required in SoftAP mode.
12229 */
12230
12231 // Get P2P Adapter
12232 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
12233
12234 if (pP2pAdapter)
12235 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053012236 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053012237 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070012238 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12239 }
12240 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053012241 //Disable IMPS & BMPS for SAP/GO
12242 if(VOS_STATUS_E_FAILURE ==
12243 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
12244 {
12245 //Fail to Exit BMPS
12246 VOS_ASSERT(0);
12247 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053012248
12249 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
12250
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012251#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070012252
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012253 /* A Mutex Lock is introduced while changing the mode to
12254 * protect the concurrent access for the Adapters by TDLS
12255 * module.
12256 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012257 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012258#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012259 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053012260 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012261 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070012262 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12263 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012264#ifdef FEATURE_WLAN_TDLS
12265 mutex_unlock(&pHddCtx->tdls_lock);
12266#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012267 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
12268 (pConfig->apRandomBssidEnabled))
12269 {
12270 /* To meet Android requirements create a randomized
12271 MAC address of the form 02:1A:11:Fx:xx:xx */
12272 get_random_bytes(&ndev->dev_addr[3], 3);
12273 ndev->dev_addr[0] = 0x02;
12274 ndev->dev_addr[1] = 0x1A;
12275 ndev->dev_addr[2] = 0x11;
12276 ndev->dev_addr[3] |= 0xF0;
12277 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
12278 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080012279 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
12280 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012281 }
12282
Jeff Johnson295189b2012-06-20 16:38:30 -070012283 hdd_set_ap_ops( pAdapter->dev );
12284
Kiet Lam10841362013-11-01 11:36:50 +053012285 /* This is for only SAP mode where users can
12286 * control country through ini.
12287 * P2P GO follows station country code
12288 * acquired during the STA scanning. */
12289 if((NL80211_IFTYPE_AP == type) &&
12290 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
12291 {
12292 int status = 0;
12293 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
12294 "%s: setting country code from INI ", __func__);
12295 init_completion(&pAdapter->change_country_code);
12296 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
12297 (void *)(tSmeChangeCountryCallback)
12298 wlan_hdd_change_country_code_cb,
12299 pConfig->apCntryCode, pAdapter,
12300 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012301 eSIR_FALSE,
12302 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053012303 if (eHAL_STATUS_SUCCESS == status)
12304 {
12305 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012306 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053012307 &pAdapter->change_country_code,
12308 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012309 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053012310 {
12311 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012312 FL("SME Timed out while setting country code %ld"),
12313 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080012314
12315 if (pHddCtx->isLogpInProgress)
12316 {
12317 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12318 "%s: LOGP in Progress. Ignore!!!", __func__);
12319 return -EAGAIN;
12320 }
Kiet Lam10841362013-11-01 11:36:50 +053012321 }
12322 }
12323 else
12324 {
12325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012326 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053012327 return -EINVAL;
12328 }
12329 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053012330 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070012331 if(status != VOS_STATUS_SUCCESS)
12332 {
12333 hddLog(VOS_TRACE_LEVEL_FATAL,
12334 "%s: Error initializing the ap mode", __func__);
12335 return -EINVAL;
12336 }
12337 hdd_set_conparam(1);
12338
Nirav Shah7e3c8132015-06-22 23:51:42 +053012339 status = hdd_sta_id_hash_attach(pAdapter);
12340 if (VOS_STATUS_SUCCESS != status)
12341 {
12342 hddLog(VOS_TRACE_LEVEL_ERROR,
12343 FL("Failed to initialize hash for AP"));
12344 return -EINVAL;
12345 }
12346
Jeff Johnson295189b2012-06-20 16:38:30 -070012347 /*interface type changed update in wiphy structure*/
12348 if(wdev)
12349 {
12350 wdev->iftype = type;
12351 pHddCtx->change_iface = type;
12352 }
12353 else
12354 {
12355 hddLog(VOS_TRACE_LEVEL_ERROR,
12356 "%s: ERROR !!!! Wireless dev is NULL", __func__);
12357 return -EINVAL;
12358 }
12359 goto done;
12360 }
12361
12362 default:
12363 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12364 __func__);
12365 return -EOPNOTSUPP;
12366 }
12367 }
12368 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012369 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070012370 )
12371 {
12372 switch(type)
12373 {
12374 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012375 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012376 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053012377
12378 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012379#ifdef FEATURE_WLAN_TDLS
12380
12381 /* A Mutex Lock is introduced while changing the mode to
12382 * protect the concurrent access for the Adapters by TDLS
12383 * module.
12384 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012385 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012386#endif
c_hpothu002231a2015-02-05 14:58:51 +053012387 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012388 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012389 //Check for sub-string p2p to confirm its a p2p interface
12390 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012391 {
12392 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12393 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12394 }
12395 else
12396 {
12397 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012398 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012399 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053012400
12401 /* set con_mode to STA only when no SAP concurrency mode */
12402 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
12403 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012404 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012405 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
12406 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012407#ifdef FEATURE_WLAN_TDLS
12408 mutex_unlock(&pHddCtx->tdls_lock);
12409#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053012410 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070012411 if( VOS_STATUS_SUCCESS != status )
12412 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070012413 /* In case of JB, for P2P-GO, only change interface will be called,
12414 * This is the right place to enable back bmps_imps()
12415 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012416 if (pHddCtx->hdd_wlan_suspended)
12417 {
12418 hdd_set_pwrparams(pHddCtx);
12419 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012420 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012421 goto done;
12422 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012423 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012424 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012425 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12426 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012427 goto done;
12428 default:
12429 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12430 __func__);
12431 return -EOPNOTSUPP;
12432
12433 }
12434
12435 }
12436 else
12437 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012438 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
12439 __func__, hdd_device_modetoString(pAdapter->device_mode),
12440 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012441 return -EOPNOTSUPP;
12442 }
12443
12444
12445 if(pRoamProfile)
12446 {
12447 if ( LastBSSType != pRoamProfile->BSSType )
12448 {
12449 /*interface type changed update in wiphy structure*/
12450 wdev->iftype = type;
12451
12452 /*the BSS mode changed, We need to issue disconnect
12453 if connected or in IBSS disconnect state*/
12454 if ( hdd_connGetConnectedBssType(
12455 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
12456 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
12457 {
12458 /*need to issue a disconnect to CSR.*/
12459 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12460 if( eHAL_STATUS_SUCCESS ==
12461 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12462 pAdapter->sessionId,
12463 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12464 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012465 ret = wait_for_completion_interruptible_timeout(
12466 &pAdapter->disconnect_comp_var,
12467 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12468 if (ret <= 0)
12469 {
12470 hddLog(VOS_TRACE_LEVEL_ERROR,
12471 FL("wait on disconnect_comp_var failed %ld"), ret);
12472 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012473 }
12474 }
12475 }
12476 }
12477
12478done:
12479 /*set bitmask based on updated value*/
12480 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012481
12482 /* Only STA mode support TM now
12483 * all other mode, TM feature should be disabled */
12484 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12485 (~VOS_STA & pHddCtx->concurrency_mode) )
12486 {
12487 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12488 }
12489
Jeff Johnson295189b2012-06-20 16:38:30 -070012490#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012491 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012492 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012493 {
12494 //we are ok to do AMP
12495 pHddCtx->isAmpAllowed = VOS_TRUE;
12496 }
12497#endif //WLAN_BTAMP_FEATURE
12498 EXIT();
12499 return 0;
12500}
12501
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012502/*
12503 * FUNCTION: wlan_hdd_cfg80211_change_iface
12504 * wrapper function to protect the actual implementation from SSR.
12505 */
12506int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12507 struct net_device *ndev,
12508 enum nl80211_iftype type,
12509 u32 *flags,
12510 struct vif_params *params
12511 )
12512{
12513 int ret;
12514
12515 vos_ssr_protect(__func__);
12516 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12517 vos_ssr_unprotect(__func__);
12518
12519 return ret;
12520}
12521
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012522#ifdef FEATURE_WLAN_TDLS
12523static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012524 struct net_device *dev,
12525#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12526 const u8 *mac,
12527#else
12528 u8 *mac,
12529#endif
12530 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012531{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012532 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012533 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012534 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012535 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012536 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012537 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012538
12539 ENTER();
12540
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012541 if (!dev) {
12542 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12543 return -EINVAL;
12544 }
12545
12546 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12547 if (!pAdapter) {
12548 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12549 return -EINVAL;
12550 }
12551
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012552 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012553 {
12554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12555 "Invalid arguments");
12556 return -EINVAL;
12557 }
Hoonki Lee27511902013-03-14 18:19:06 -070012558
12559 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12560 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12561 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012563 "%s: TDLS mode is disabled OR not enabled in FW."
12564 MAC_ADDRESS_STR " Request declined.",
12565 __func__, MAC_ADDR_ARRAY(mac));
12566 return -ENOTSUPP;
12567 }
12568
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012569 if (pHddCtx->isLogpInProgress)
12570 {
12571 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12572 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012573 wlan_hdd_tdls_set_link_status(pAdapter,
12574 mac,
12575 eTDLS_LINK_IDLE,
12576 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012577 return -EBUSY;
12578 }
12579
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012580 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012581 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012582
12583 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012584 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012585 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12586 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012587 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012588 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012589 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012590
12591 /* in add station, we accept existing valid staId if there is */
12592 if ((0 == update) &&
12593 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12594 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012595 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012596 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012597 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012598 " link_status %d. staId %d. add station ignored.",
12599 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012600 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012601 return 0;
12602 }
12603 /* in change station, we accept only when staId is valid */
12604 if ((1 == update) &&
12605 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12606 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12607 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012608 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012609 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012610 "%s: " MAC_ADDRESS_STR
12611 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012612 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12613 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12614 mutex_unlock(&pHddCtx->tdls_lock);
12615 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012616 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012617 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012618
12619 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012620 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012621 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12623 "%s: " MAC_ADDRESS_STR
12624 " TDLS setup is ongoing. Request declined.",
12625 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012626 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012627 }
12628
12629 /* first to check if we reached to maximum supported TDLS peer.
12630 TODO: for now, return -EPERM looks working fine,
12631 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012632 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12633 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012634 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12636 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012637 " TDLS Max peer already connected. Request declined."
12638 " Num of peers (%d), Max allowed (%d).",
12639 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12640 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012641 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012642 }
12643 else
12644 {
12645 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012646 mutex_lock(&pHddCtx->tdls_lock);
12647 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012648 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012649 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012650 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012651 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12652 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12653 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012654 return -EPERM;
12655 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012656 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012657 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012658 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012659 wlan_hdd_tdls_set_link_status(pAdapter,
12660 mac,
12661 eTDLS_LINK_CONNECTING,
12662 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012663
Jeff Johnsond75fe012013-04-06 10:53:06 -070012664 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012665 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012666 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012667 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012668 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012669 if(StaParams->htcap_present)
12670 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012672 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012673 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012674 "ht_capa->extended_capabilities: %0x",
12675 StaParams->HTCap.extendedHtCapInfo);
12676 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012677 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012678 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012680 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012681 if(StaParams->vhtcap_present)
12682 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012684 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12685 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12686 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12687 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012688 {
12689 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012691 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012692 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012693 "[%d]: %x ", i, StaParams->supported_rates[i]);
12694 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012695 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012696 else if ((1 == update) && (NULL == StaParams))
12697 {
12698 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12699 "%s : update is true, but staParams is NULL. Error!", __func__);
12700 return -EPERM;
12701 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012702
12703 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12704
12705 if (!update)
12706 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012707 /*Before adding sta make sure that device exited from BMPS*/
12708 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12709 {
12710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12711 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12712 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12713 if (status != VOS_STATUS_SUCCESS) {
12714 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12715 }
12716 }
12717
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012718 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012719 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012720 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012721 hddLog(VOS_TRACE_LEVEL_ERROR,
12722 FL("Failed to add TDLS peer STA. Enable Bmps"));
12723 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012724 return -EPERM;
12725 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012726 }
12727 else
12728 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012729 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012730 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012731 if (ret != eHAL_STATUS_SUCCESS) {
12732 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12733 return -EPERM;
12734 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012735 }
12736
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012737 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012738 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12739
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012740 mutex_lock(&pHddCtx->tdls_lock);
12741 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12742
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012743 if ((pTdlsPeer != NULL) &&
12744 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012745 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012746 hddLog(VOS_TRACE_LEVEL_ERROR,
12747 FL("peer link status %u"), pTdlsPeer->link_status);
12748 mutex_unlock(&pHddCtx->tdls_lock);
12749 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012750 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012751 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012752
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012753 if (ret <= 0)
12754 {
12755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12756 "%s: timeout waiting for tdls add station indication %ld",
12757 __func__, ret);
12758 goto error;
12759 }
12760
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012761 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12762 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012764 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012765 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012766 }
12767
12768 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012769
12770error:
Atul Mittal115287b2014-07-08 13:26:33 +053012771 wlan_hdd_tdls_set_link_status(pAdapter,
12772 mac,
12773 eTDLS_LINK_IDLE,
12774 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012775 return -EPERM;
12776
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012777}
12778#endif
12779
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053012780VOS_STATUS wlan_hdd_send_sta_authorized_event(
12781 hdd_adapter_t *adapter,
12782 hdd_context_t *hdd_ctx,
12783 const v_MACADDR_t *mac_addr)
12784{
12785 struct sk_buff *vendor_event;
12786 uint32_t sta_flags = 0;
12787 VOS_STATUS status;
12788
12789 ENTER();
12790
12791 if (!hdd_ctx) {
12792 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null"));
12793 return -EINVAL;
12794 }
12795
12796 vendor_event =
12797 cfg80211_vendor_event_alloc(
12798 hdd_ctx->wiphy, &adapter->wdev, sizeof(sta_flags) +
12799 VOS_MAC_ADDR_SIZE + NLMSG_HDRLEN,
12800 QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX,
12801 GFP_KERNEL);
12802 if (!vendor_event) {
12803 hddLog(VOS_TRACE_LEVEL_ERROR,
12804 FL("cfg80211_vendor_event_alloc failed"));
12805 return -EINVAL;
12806 }
12807
12808 sta_flags |= BIT(NL80211_STA_FLAG_AUTHORIZED);
12809
12810 status = nla_put_u32(vendor_event,
12811 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS,
12812 sta_flags);
12813 if (status) {
12814 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA flag put fails"));
12815 kfree_skb(vendor_event);
12816 return VOS_STATUS_E_FAILURE;
12817 }
12818 status = nla_put(vendor_event,
12819 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_MAC,
12820 VOS_MAC_ADDR_SIZE, mac_addr->bytes);
12821 if (status) {
12822 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA MAC put fails"));
12823 kfree_skb(vendor_event);
12824 return VOS_STATUS_E_FAILURE;
12825 }
12826
12827 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
12828
12829 EXIT();
12830 return 0;
12831}
12832
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012833static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012834 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012835#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12836 const u8 *mac,
12837#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012838 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012839#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012840 struct station_parameters *params)
12841{
12842 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012843 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012844 hdd_context_t *pHddCtx;
12845 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012846 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012847 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012848#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012849 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012850 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012851 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012852 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012853#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012854
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012855 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012856
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012857 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012858 if ((NULL == pAdapter))
12859 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012861 "invalid adapter ");
12862 return -EINVAL;
12863 }
12864
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012865 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12866 TRACE_CODE_HDD_CHANGE_STATION,
12867 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053012868 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012869
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012870 ret = wlan_hdd_validate_context(pHddCtx);
12871 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053012872 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012873 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012874 }
12875
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012876 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12877
12878 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012879 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012880 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12881 "invalid HDD station context");
12882 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012883 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012884 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
12885
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012886 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
12887 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070012888 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012889 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070012890 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012891 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070012892 WLANTL_STA_AUTHENTICATED);
12893
Gopichand Nakkala29149562013-05-10 21:43:41 +053012894 if (status != VOS_STATUS_SUCCESS)
12895 {
12896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12897 "%s: Not able to change TL state to AUTHENTICATED", __func__);
12898 return -EINVAL;
12899 }
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053012900 status = wlan_hdd_send_sta_authorized_event(pAdapter, pHddCtx,
12901 &STAMacAddress);
12902 if (status != VOS_STATUS_SUCCESS)
12903 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012904 }
12905 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070012906 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
12907 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012908#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012909 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12910 StaParams.capability = params->capability;
12911 StaParams.uapsd_queues = params->uapsd_queues;
12912 StaParams.max_sp = params->max_sp;
12913
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012914 /* Convert (first channel , number of channels) tuple to
12915 * the total list of channels. This goes with the assumption
12916 * that if the first channel is < 14, then the next channels
12917 * are an incremental of 1 else an incremental of 4 till the number
12918 * of channels.
12919 */
12920 if (0 != params->supported_channels_len) {
12921 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
12922 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
12923 {
12924 int wifi_chan_index;
12925 StaParams.supported_channels[j] = params->supported_channels[i];
12926 wifi_chan_index =
12927 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
12928 no_of_channels = params->supported_channels[i+1];
12929 for(k=1; k <= no_of_channels; k++)
12930 {
12931 StaParams.supported_channels[j+1] =
12932 StaParams.supported_channels[j] + wifi_chan_index;
12933 j+=1;
12934 }
12935 }
12936 StaParams.supported_channels_len = j;
12937 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053012938 if (params->supported_oper_classes_len >
12939 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
12940 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12941 "received oper classes:%d, resetting it to max supported %d",
12942 params->supported_oper_classes_len,
12943 SIR_MAC_MAX_SUPP_OPER_CLASSES);
12944 params->supported_oper_classes_len =
12945 SIR_MAC_MAX_SUPP_OPER_CLASSES;
12946 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012947 vos_mem_copy(StaParams.supported_oper_classes,
12948 params->supported_oper_classes,
12949 params->supported_oper_classes_len);
12950 StaParams.supported_oper_classes_len =
12951 params->supported_oper_classes_len;
12952
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012953 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
12954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12955 "received extn capabilities:%d, resetting it to max supported",
12956 params->ext_capab_len);
12957 params->ext_capab_len = sizeof(StaParams.extn_capability);
12958 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012959 if (0 != params->ext_capab_len)
12960 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012961 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012962
12963 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012964 {
12965 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012966 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012967 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012968
12969 StaParams.supported_rates_len = params->supported_rates_len;
12970
12971 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
12972 * The supported_rates array , for all the structures propogating till Add Sta
12973 * to the firmware has to be modified , if the supplicant (ieee80211) is
12974 * modified to send more rates.
12975 */
12976
12977 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
12978 */
12979 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
12980 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
12981
12982 if (0 != StaParams.supported_rates_len) {
12983 int i = 0;
12984 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
12985 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012986 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012987 "Supported Rates with Length %d", StaParams.supported_rates_len);
12988 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012990 "[%d]: %0x", i, StaParams.supported_rates[i]);
12991 }
12992
12993 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012994 {
12995 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012996 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012997 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012998
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012999 if (0 != params->ext_capab_len ) {
13000 /*Define A Macro : TODO Sunil*/
13001 if ((1<<4) & StaParams.extn_capability[3]) {
13002 isBufSta = 1;
13003 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013004 /* TDLS Channel Switching Support */
13005 if ((1<<6) & StaParams.extn_capability[3]) {
13006 isOffChannelSupported = 1;
13007 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013008 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013009
13010 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053013011 (params->ht_capa || params->vht_capa ||
13012 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013013 /* TDLS Peer is WME/QoS capable */
13014 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013015
13016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13017 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
13018 __func__, isQosWmmSta, StaParams.htcap_present);
13019
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013020 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
13021 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013022 isOffChannelSupported,
13023 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013024
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013025 if (VOS_STATUS_SUCCESS != status) {
13026 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13027 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
13028 return -EINVAL;
13029 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013030 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
13031
13032 if (VOS_STATUS_SUCCESS != status) {
13033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13034 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
13035 return -EINVAL;
13036 }
13037 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013038#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053013039 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013040 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013041 return status;
13042}
13043
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013044#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13045static int wlan_hdd_change_station(struct wiphy *wiphy,
13046 struct net_device *dev,
13047 const u8 *mac,
13048 struct station_parameters *params)
13049#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013050static int wlan_hdd_change_station(struct wiphy *wiphy,
13051 struct net_device *dev,
13052 u8 *mac,
13053 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013054#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013055{
13056 int ret;
13057
13058 vos_ssr_protect(__func__);
13059 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
13060 vos_ssr_unprotect(__func__);
13061
13062 return ret;
13063}
13064
Jeff Johnson295189b2012-06-20 16:38:30 -070013065/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013066 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013067 * This function is used to initialize the key information
13068 */
13069#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013070static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013071 struct net_device *ndev,
13072 u8 key_index, bool pairwise,
13073 const u8 *mac_addr,
13074 struct key_params *params
13075 )
13076#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013077static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013078 struct net_device *ndev,
13079 u8 key_index, const u8 *mac_addr,
13080 struct key_params *params
13081 )
13082#endif
13083{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013084 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013085 tCsrRoamSetKey setKey;
13086 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013087 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013088 v_U32_t roamId= 0xFF;
13089 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013090 hdd_hostapd_state_t *pHostapdState;
13091 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013092 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013093 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013094 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013095 v_MACADDR_t *peerMacAddr;
13096 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013097 uint8_t staid = HDD_MAX_STA_COUNT;
13098 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013099
13100 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013101
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013102 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13103 TRACE_CODE_HDD_CFG80211_ADD_KEY,
13104 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013105 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13106 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013107 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013108 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013109 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013110 }
13111
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013112 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13113 __func__, hdd_device_modetoString(pAdapter->device_mode),
13114 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013115
13116 if (CSR_MAX_NUM_KEY <= key_index)
13117 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013118 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013119 key_index);
13120
13121 return -EINVAL;
13122 }
13123
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013124 if (CSR_MAX_KEY_LEN < params->key_len)
13125 {
13126 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
13127 params->key_len);
13128
13129 return -EINVAL;
13130 }
13131
Jingxiang Gec438aea2017-10-26 16:44:00 +080013132 if (CSR_MAX_RSC_LEN < params->seq_len)
13133 {
13134 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
13135 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053013136
13137 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080013138 }
13139
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013140 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080013141 "%s: called with key index = %d & key length %d & seq length %d",
13142 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013143
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013144 peerMacAddr = (v_MACADDR_t *)mac_addr;
13145
Jeff Johnson295189b2012-06-20 16:38:30 -070013146 /*extract key idx, key len and key*/
13147 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13148 setKey.keyId = key_index;
13149 setKey.keyLength = params->key_len;
13150 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080013151 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013152
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013153 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013154 {
13155 case WLAN_CIPHER_SUITE_WEP40:
13156 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13157 break;
13158
13159 case WLAN_CIPHER_SUITE_WEP104:
13160 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
13161 break;
13162
13163 case WLAN_CIPHER_SUITE_TKIP:
13164 {
13165 u8 *pKey = &setKey.Key[0];
13166 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
13167
13168 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
13169
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013170 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070013171
13172 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013173 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013174 |--------------|----------|----------|
13175 <---16bytes---><--8bytes--><--8bytes-->
13176
13177 */
13178 /*Sme expects the 32 bytes key to be in the below order
13179
13180 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013181 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013182 |--------------|----------|----------|
13183 <---16bytes---><--8bytes--><--8bytes-->
13184 */
13185 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013186 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070013187
13188 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013189 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013190
13191 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013192 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013193
13194
13195 break;
13196 }
13197
13198 case WLAN_CIPHER_SUITE_CCMP:
13199 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
13200 break;
13201
13202#ifdef FEATURE_WLAN_WAPI
13203 case WLAN_CIPHER_SUITE_SMS4:
13204 {
13205 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13206 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
13207 params->key, params->key_len);
13208 return 0;
13209 }
13210#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013211
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013212#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013213 case WLAN_CIPHER_SUITE_KRK:
13214 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
13215 break;
13216#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013217
13218#ifdef WLAN_FEATURE_11W
13219 case WLAN_CIPHER_SUITE_AES_CMAC:
13220 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070013221 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070013222#endif
13223
Jeff Johnson295189b2012-06-20 16:38:30 -070013224 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013225 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070013226 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013227 status = -EOPNOTSUPP;
13228 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013229 }
13230
13231 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
13232 __func__, setKey.encType);
13233
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013234 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070013235#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13236 (!pairwise)
13237#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013238 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013239#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013240 )
13241 {
13242 /* set group key*/
13243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13244 "%s- %d: setting Broadcast key",
13245 __func__, __LINE__);
13246 setKey.keyDirection = eSIR_RX_ONLY;
13247 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13248 }
13249 else
13250 {
13251 /* set pairwise key*/
13252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13253 "%s- %d: setting pairwise key",
13254 __func__, __LINE__);
13255 setKey.keyDirection = eSIR_TX_RX;
13256 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013257 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013258 }
13259 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
13260 {
13261 setKey.keyDirection = eSIR_TX_RX;
13262 /*Set the group key*/
13263 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13264 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070013265
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013266 if ( 0 != status )
13267 {
13268 hddLog(VOS_TRACE_LEVEL_ERROR,
13269 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013270 status = -EINVAL;
13271 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013272 }
13273 /*Save the keys here and call sme_RoamSetKey for setting
13274 the PTK after peer joins the IBSS network*/
13275 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
13276 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013277 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013278 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053013279 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
13280 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
13281 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013282 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013283 if( pHostapdState->bssState == BSS_START )
13284 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013285 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13286 vos_status = wlan_hdd_check_ula_done(pAdapter);
13287
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013288 if (peerMacAddr && (pairwise_set_key == true))
13289 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013290
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013291 if ( vos_status != VOS_STATUS_SUCCESS )
13292 {
13293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13294 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13295 __LINE__, vos_status );
13296
13297 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13298
13299 status = -EINVAL;
13300 goto end;
13301 }
13302
Jeff Johnson295189b2012-06-20 16:38:30 -070013303 status = WLANSAP_SetKeySta( pVosContext, &setKey);
13304
13305 if ( status != eHAL_STATUS_SUCCESS )
13306 {
13307 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13308 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13309 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013310 status = -EINVAL;
13311 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013312 }
13313 }
13314
13315 /* Saving WEP keys */
13316 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
13317 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
13318 {
13319 //Save the wep key in ap context. Issue setkey after the BSS is started.
13320 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13321 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
13322 }
13323 else
13324 {
13325 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013326 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013327 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
13328 }
13329 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013330 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
13331 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013332 {
13333 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13334 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13335
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013336#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13337 if (!pairwise)
13338#else
13339 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
13340#endif
13341 {
13342 /* set group key*/
13343 if (pHddStaCtx->roam_info.deferKeyComplete)
13344 {
13345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13346 "%s- %d: Perform Set key Complete",
13347 __func__, __LINE__);
13348 hdd_PerformRoamSetKeyComplete(pAdapter);
13349 }
13350 }
13351
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013352 if (pairwise_set_key == true)
13353 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013354
Jeff Johnson295189b2012-06-20 16:38:30 -070013355 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
13356
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080013357 pWextState->roamProfile.Keys.defaultIndex = key_index;
13358
13359
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013360 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013361 params->key, params->key_len);
13362
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013363
Jeff Johnson295189b2012-06-20 16:38:30 -070013364 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13365
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013366 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013367 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013368 __func__, setKey.peerMac[0], setKey.peerMac[1],
13369 setKey.peerMac[2], setKey.peerMac[3],
13370 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013371 setKey.keyDirection);
13372
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013373 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053013374
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013375 if ( vos_status != VOS_STATUS_SUCCESS )
13376 {
13377 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013378 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13379 __LINE__, vos_status );
13380
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013381 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013382
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013383 status = -EINVAL;
13384 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013385
13386 }
13387
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013388#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013389 /* The supplicant may attempt to set the PTK once pre-authentication
13390 is done. Save the key in the UMAC and include it in the ADD BSS
13391 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013392 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013393 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013394 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013395 hddLog(VOS_TRACE_LEVEL_INFO_MED,
13396 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013397 status = 0;
13398 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013399 }
13400 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
13401 {
13402 hddLog(VOS_TRACE_LEVEL_ERROR,
13403 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013404 status = -EINVAL;
13405 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013406 }
13407#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070013408
13409 /* issue set key request to SME*/
13410 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13411 pAdapter->sessionId, &setKey, &roamId );
13412
13413 if ( 0 != status )
13414 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013415 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013416 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
13417 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013418 status = -EINVAL;
13419 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013420 }
13421
13422
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013423 /* in case of IBSS as there was no information available about WEP keys during
13424 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070013425 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013426 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
13427 !( ( IW_AUTH_KEY_MGMT_802_1X
13428 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070013429 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
13430 )
13431 &&
13432 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
13433 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
13434 )
13435 )
13436 {
13437 setKey.keyDirection = eSIR_RX_ONLY;
13438 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13439
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013440 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013441 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013442 __func__, setKey.peerMac[0], setKey.peerMac[1],
13443 setKey.peerMac[2], setKey.peerMac[3],
13444 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013445 setKey.keyDirection);
13446
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013447 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013448 pAdapter->sessionId, &setKey, &roamId );
13449
13450 if ( 0 != status )
13451 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013452 hddLog(VOS_TRACE_LEVEL_ERROR,
13453 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013454 __func__, status);
13455 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013456 status = -EINVAL;
13457 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013458 }
13459 }
13460 }
13461
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013462 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013463 for (i = 0; i < params->seq_len; i++) {
13464 rsc_counter |= (params->seq[i] << i*8);
13465 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013466 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
13467 }
13468
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013469end:
13470 /* Need to clear any trace of key value in the memory.
13471 * Thus zero out the memory even though it is local
13472 * variable.
13473 */
13474 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013475 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013476 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013477}
13478
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013479#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13480static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13481 struct net_device *ndev,
13482 u8 key_index, bool pairwise,
13483 const u8 *mac_addr,
13484 struct key_params *params
13485 )
13486#else
13487static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13488 struct net_device *ndev,
13489 u8 key_index, const u8 *mac_addr,
13490 struct key_params *params
13491 )
13492#endif
13493{
13494 int ret;
13495 vos_ssr_protect(__func__);
13496#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13497 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
13498 mac_addr, params);
13499#else
13500 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
13501 params);
13502#endif
13503 vos_ssr_unprotect(__func__);
13504
13505 return ret;
13506}
13507
Jeff Johnson295189b2012-06-20 16:38:30 -070013508/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013509 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013510 * This function is used to get the key information
13511 */
13512#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013513static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013514 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013515 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013516 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013517 const u8 *mac_addr, void *cookie,
13518 void (*callback)(void *cookie, struct key_params*)
13519 )
13520#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013521static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013522 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013523 struct net_device *ndev,
13524 u8 key_index, const u8 *mac_addr, void *cookie,
13525 void (*callback)(void *cookie, struct key_params*)
13526 )
13527#endif
13528{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013529 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013530 hdd_wext_state_t *pWextState = NULL;
13531 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013532 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013533 hdd_context_t *pHddCtx;
13534 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013535
13536 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013537
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013538 if (NULL == pAdapter)
13539 {
13540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13541 "%s: HDD adapter is Null", __func__);
13542 return -ENODEV;
13543 }
13544
13545 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13546 ret = wlan_hdd_validate_context(pHddCtx);
13547 if (0 != ret)
13548 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013549 return ret;
13550 }
13551
13552 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13553 pRoamProfile = &(pWextState->roamProfile);
13554
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013555 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13556 __func__, hdd_device_modetoString(pAdapter->device_mode),
13557 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013558
Jeff Johnson295189b2012-06-20 16:38:30 -070013559 memset(&params, 0, sizeof(params));
13560
13561 if (CSR_MAX_NUM_KEY <= key_index)
13562 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013563 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013564 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013565 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013566
13567 switch(pRoamProfile->EncryptionType.encryptionType[0])
13568 {
13569 case eCSR_ENCRYPT_TYPE_NONE:
13570 params.cipher = IW_AUTH_CIPHER_NONE;
13571 break;
13572
13573 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13574 case eCSR_ENCRYPT_TYPE_WEP40:
13575 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13576 break;
13577
13578 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13579 case eCSR_ENCRYPT_TYPE_WEP104:
13580 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13581 break;
13582
13583 case eCSR_ENCRYPT_TYPE_TKIP:
13584 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13585 break;
13586
13587 case eCSR_ENCRYPT_TYPE_AES:
13588 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13589 break;
13590
13591 default:
13592 params.cipher = IW_AUTH_CIPHER_NONE;
13593 break;
13594 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013595
c_hpothuaaf19692014-05-17 17:01:48 +053013596 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13597 TRACE_CODE_HDD_CFG80211_GET_KEY,
13598 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013599
Jeff Johnson295189b2012-06-20 16:38:30 -070013600 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13601 params.seq_len = 0;
13602 params.seq = NULL;
13603 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13604 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013605 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013606 return 0;
13607}
13608
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013609#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13610static int wlan_hdd_cfg80211_get_key(
13611 struct wiphy *wiphy,
13612 struct net_device *ndev,
13613 u8 key_index, bool pairwise,
13614 const u8 *mac_addr, void *cookie,
13615 void (*callback)(void *cookie, struct key_params*)
13616 )
13617#else
13618static int wlan_hdd_cfg80211_get_key(
13619 struct wiphy *wiphy,
13620 struct net_device *ndev,
13621 u8 key_index, const u8 *mac_addr, void *cookie,
13622 void (*callback)(void *cookie, struct key_params*)
13623 )
13624#endif
13625{
13626 int ret;
13627
13628 vos_ssr_protect(__func__);
13629#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13630 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13631 mac_addr, cookie, callback);
13632#else
13633 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13634 callback);
13635#endif
13636 vos_ssr_unprotect(__func__);
13637
13638 return ret;
13639}
13640
Jeff Johnson295189b2012-06-20 16:38:30 -070013641/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013642 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013643 * This function is used to delete the key information
13644 */
13645#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013646static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013647 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013648 u8 key_index,
13649 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013650 const u8 *mac_addr
13651 )
13652#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013653static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013654 struct net_device *ndev,
13655 u8 key_index,
13656 const u8 *mac_addr
13657 )
13658#endif
13659{
13660 int status = 0;
13661
13662 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013663 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013664 //it is observed that this is invalidating peer
13665 //key index whenever re-key is done. This is affecting data link.
13666 //It should be ok to ignore del_key.
13667#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013668 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13669 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013670 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13671 tCsrRoamSetKey setKey;
13672 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013673
Jeff Johnson295189b2012-06-20 16:38:30 -070013674 ENTER();
13675
13676 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13677 __func__,pAdapter->device_mode);
13678
13679 if (CSR_MAX_NUM_KEY <= key_index)
13680 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013681 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013682 key_index);
13683
13684 return -EINVAL;
13685 }
13686
13687 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13688 setKey.keyId = key_index;
13689
13690 if (mac_addr)
13691 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13692 else
13693 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13694
13695 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13696
13697 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013698 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013699 )
13700 {
13701
13702 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013703 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13704 if( pHostapdState->bssState == BSS_START)
13705 {
13706 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013707
Jeff Johnson295189b2012-06-20 16:38:30 -070013708 if ( status != eHAL_STATUS_SUCCESS )
13709 {
13710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13711 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13712 __LINE__, status );
13713 }
13714 }
13715 }
13716 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013717 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013718 )
13719 {
13720 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13721
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013722 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13723
13724 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013725 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013726 __func__, setKey.peerMac[0], setKey.peerMac[1],
13727 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013728 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013729 if(pAdapter->sessionCtx.station.conn_info.connState ==
13730 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013731 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013732 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013733 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013734
Jeff Johnson295189b2012-06-20 16:38:30 -070013735 if ( 0 != status )
13736 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013737 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013738 "%s: sme_RoamSetKey failure, returned %d",
13739 __func__, status);
13740 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13741 return -EINVAL;
13742 }
13743 }
13744 }
13745#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013746 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013747 return status;
13748}
13749
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013750#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13751static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13752 struct net_device *ndev,
13753 u8 key_index,
13754 bool pairwise,
13755 const u8 *mac_addr
13756 )
13757#else
13758static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13759 struct net_device *ndev,
13760 u8 key_index,
13761 const u8 *mac_addr
13762 )
13763#endif
13764{
13765 int ret;
13766
13767 vos_ssr_protect(__func__);
13768#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13769 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
13770 mac_addr);
13771#else
13772 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
13773#endif
13774 vos_ssr_unprotect(__func__);
13775
13776 return ret;
13777}
13778
Jeff Johnson295189b2012-06-20 16:38:30 -070013779/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013780 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013781 * This function is used to set the default tx key index
13782 */
13783#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013784static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013785 struct net_device *ndev,
13786 u8 key_index,
13787 bool unicast, bool multicast)
13788#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013789static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013790 struct net_device *ndev,
13791 u8 key_index)
13792#endif
13793{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013794 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013795 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013796 hdd_wext_state_t *pWextState;
13797 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013798 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013799
13800 ENTER();
13801
Gopichand Nakkala29149562013-05-10 21:43:41 +053013802 if ((NULL == pAdapter))
13803 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013804 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013805 "invalid adapter");
13806 return -EINVAL;
13807 }
13808
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013809 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13810 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
13811 pAdapter->sessionId, key_index));
13812
Gopichand Nakkala29149562013-05-10 21:43:41 +053013813 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13814 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13815
13816 if ((NULL == pWextState) || (NULL == pHddStaCtx))
13817 {
13818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13819 "invalid Wext state or HDD context");
13820 return -EINVAL;
13821 }
13822
Arif Hussain6d2a3322013-11-17 19:50:10 -080013823 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013824 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013825
Jeff Johnson295189b2012-06-20 16:38:30 -070013826 if (CSR_MAX_NUM_KEY <= key_index)
13827 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013828 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013829 key_index);
13830
13831 return -EINVAL;
13832 }
13833
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013834 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13835 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013836 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013837 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013838 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013839 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013840
Jeff Johnson295189b2012-06-20 16:38:30 -070013841 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070013842 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013843 )
Jeff Johnson295189b2012-06-20 16:38:30 -070013844 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013845 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080013846 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080013847#ifdef FEATURE_WLAN_WAPI
13848 (eCSR_ENCRYPT_TYPE_WPI !=
13849 pHddStaCtx->conn_info.ucEncryptionType) &&
13850#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013851 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080013852 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070013853 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013854 {
13855 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070013856 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013857
Jeff Johnson295189b2012-06-20 16:38:30 -070013858 tCsrRoamSetKey setKey;
13859 v_U32_t roamId= 0xFF;
13860 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013861
13862 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013863 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013864
Jeff Johnson295189b2012-06-20 16:38:30 -070013865 Keys->defaultIndex = (u8)key_index;
13866 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13867 setKey.keyId = key_index;
13868 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013869
13870 vos_mem_copy(&setKey.Key[0],
13871 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013872 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013873
Gopichand Nakkala29149562013-05-10 21:43:41 +053013874 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013875
13876 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070013877 &pHddStaCtx->conn_info.bssId[0],
13878 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013879
Gopichand Nakkala29149562013-05-10 21:43:41 +053013880 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
13881 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
13882 eCSR_ENCRYPT_TYPE_WEP104)
13883 {
13884 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
13885 even though ap is configured for WEP-40 encryption. In this canse the key length
13886 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
13887 type(104) and switching encryption type to 40*/
13888 pWextState->roamProfile.EncryptionType.encryptionType[0] =
13889 eCSR_ENCRYPT_TYPE_WEP40;
13890 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
13891 eCSR_ENCRYPT_TYPE_WEP40;
13892 }
13893
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013894 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013895 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013896
Jeff Johnson295189b2012-06-20 16:38:30 -070013897 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013898 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013899 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013900
Jeff Johnson295189b2012-06-20 16:38:30 -070013901 if ( 0 != status )
13902 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013903 hddLog(VOS_TRACE_LEVEL_ERROR,
13904 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013905 status);
13906 return -EINVAL;
13907 }
13908 }
13909 }
13910
13911 /* In SoftAp mode setting key direction for default mode */
13912 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
13913 {
13914 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
13915 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
13916 (eCSR_ENCRYPT_TYPE_AES !=
13917 pWextState->roamProfile.EncryptionType.encryptionType[0])
13918 )
13919 {
13920 /* Saving key direction for default key index to TX default */
13921 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13922 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
13923 }
13924 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013925 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013926 return status;
13927}
13928
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013929#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13930static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13931 struct net_device *ndev,
13932 u8 key_index,
13933 bool unicast, bool multicast)
13934#else
13935static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13936 struct net_device *ndev,
13937 u8 key_index)
13938#endif
13939{
13940 int ret;
13941 vos_ssr_protect(__func__);
13942#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13943 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
13944 multicast);
13945#else
13946 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
13947#endif
13948 vos_ssr_unprotect(__func__);
13949
13950 return ret;
13951}
13952
Jeff Johnson295189b2012-06-20 16:38:30 -070013953/*
13954 * FUNCTION: wlan_hdd_cfg80211_inform_bss
13955 * This function is used to inform the BSS details to nl80211 interface.
13956 */
13957static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
13958 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
13959{
13960 struct net_device *dev = pAdapter->dev;
13961 struct wireless_dev *wdev = dev->ieee80211_ptr;
13962 struct wiphy *wiphy = wdev->wiphy;
13963 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
13964 int chan_no;
13965 int ie_length;
13966 const char *ie;
13967 unsigned int freq;
13968 struct ieee80211_channel *chan;
13969 int rssi = 0;
13970 struct cfg80211_bss *bss = NULL;
13971
Jeff Johnson295189b2012-06-20 16:38:30 -070013972 if( NULL == pBssDesc )
13973 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013974 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013975 return bss;
13976 }
13977
13978 chan_no = pBssDesc->channelId;
13979 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
13980 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
13981
13982 if( NULL == ie )
13983 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013984 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013985 return bss;
13986 }
13987
13988#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
13989 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
13990 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013991 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070013992 }
13993 else
13994 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013995 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070013996 }
13997#else
13998 freq = ieee80211_channel_to_frequency(chan_no);
13999#endif
14000
14001 chan = __ieee80211_get_channel(wiphy, freq);
14002
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053014003 if (!chan) {
14004 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
14005 return NULL;
14006 }
14007
Abhishek Singhaee43942014-06-16 18:55:47 +053014008 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070014009
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014010 return cfg80211_inform_bss(wiphy, chan,
14011#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14012 CFG80211_BSS_FTYPE_UNKNOWN,
14013#endif
14014 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014015 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070014016 pBssDesc->capabilityInfo,
14017 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053014018 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070014019}
14020
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014021/*
14022 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
14023 * interface that BSS might have been lost.
14024 * @pAdapter: adaptor
14025 * @bssid: bssid which might have been lost
14026 *
14027 * Return: bss which is unlinked from kernel cache
14028 */
14029struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
14030 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
14031{
14032 struct net_device *dev = pAdapter->dev;
14033 struct wireless_dev *wdev = dev->ieee80211_ptr;
14034 struct wiphy *wiphy = wdev->wiphy;
14035 struct cfg80211_bss *bss = NULL;
14036
Abhishek Singh5a597e62016-12-05 15:16:30 +053014037 bss = hdd_get_bss_entry(wiphy,
14038 NULL, bssid,
14039 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014040 if (bss == NULL) {
14041 hddLog(LOGE, FL("BSS not present"));
14042 } else {
14043 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
14044 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
14045 cfg80211_unlink_bss(wiphy, bss);
14046 }
14047 return bss;
14048}
Jeff Johnson295189b2012-06-20 16:38:30 -070014049
14050
14051/*
14052 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
14053 * This function is used to inform the BSS details to nl80211 interface.
14054 */
14055struct cfg80211_bss*
14056wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
14057 tSirBssDescription *bss_desc
14058 )
14059{
14060 /*
14061 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
14062 already exists in bss data base of cfg80211 for that particular BSS ID.
14063 Using cfg80211_inform_bss_frame to update the bss entry instead of
14064 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
14065 now there is no possibility to get the mgmt(probe response) frame from PE,
14066 converting bss_desc to ieee80211_mgmt(probe response) and passing to
14067 cfg80211_inform_bss_frame.
14068 */
14069 struct net_device *dev = pAdapter->dev;
14070 struct wireless_dev *wdev = dev->ieee80211_ptr;
14071 struct wiphy *wiphy = wdev->wiphy;
14072 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014073#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14074 qcom_ie_age *qie_age = NULL;
14075 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
14076#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014077 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014078#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014079 const char *ie =
14080 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
14081 unsigned int freq;
14082 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014083 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014084 struct cfg80211_bss *bss_status = NULL;
14085 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
14086 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070014087 hdd_context_t *pHddCtx;
14088 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070014089#ifdef WLAN_OPEN_SOURCE
14090 struct timespec ts;
14091#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014092
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014093
Wilson Yangf80a0542013-10-07 13:02:37 -070014094 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14095 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070014096 if (0 != status)
14097 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014098 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014099 }
14100
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014101 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070014102 if (!mgmt)
14103 {
14104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14105 "%s: memory allocation failed ", __func__);
14106 return NULL;
14107 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014108
Jeff Johnson295189b2012-06-20 16:38:30 -070014109 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014110
14111#ifdef WLAN_OPEN_SOURCE
14112 /* Android does not want the timestamp from the frame.
14113 Instead it wants a monotonic increasing value */
14114 get_monotonic_boottime(&ts);
14115 mgmt->u.probe_resp.timestamp =
14116 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
14117#else
14118 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014119 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
14120 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070014121
14122#endif
14123
Jeff Johnson295189b2012-06-20 16:38:30 -070014124 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
14125 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014126
14127#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14128 /* GPS Requirement: need age ie per entry. Using vendor specific. */
14129 /* Assuming this is the last IE, copy at the end */
14130 ie_length -=sizeof(qcom_ie_age);
14131 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
14132 qie_age->element_id = QCOM_VENDOR_IE_ID;
14133 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
14134 qie_age->oui_1 = QCOM_OUI1;
14135 qie_age->oui_2 = QCOM_OUI2;
14136 qie_age->oui_3 = QCOM_OUI3;
14137 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053014138 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
14139 * bss related timestamp is in units of ms. Due to this when scan results
14140 * are sent to lowi the scan age is high.To address this, send age in units
14141 * of 1/10 ms.
14142 */
14143 qie_age->age = (vos_timer_get_system_time() -
14144 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014145#endif
14146
Jeff Johnson295189b2012-06-20 16:38:30 -070014147 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053014148 if (bss_desc->fProbeRsp)
14149 {
14150 mgmt->frame_control |=
14151 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
14152 }
14153 else
14154 {
14155 mgmt->frame_control |=
14156 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
14157 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014158
14159#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014160 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014161 (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014162 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014163 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014164 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014165 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014166 (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014167
14168 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014169 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014170 }
14171 else
14172 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014173 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
14174 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070014175 kfree(mgmt);
14176 return NULL;
14177 }
14178#else
14179 freq = ieee80211_channel_to_frequency(chan_no);
14180#endif
14181 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014182 /*when the band is changed on the fly using the GUI, three things are done
14183 * 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)
14184 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
14185 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
14186 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
14187 * and discards the channels correponding to previous band and calls back with zero bss results.
14188 * 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
14189 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
14190 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
14191 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
14192 * So drop the bss and continue to next bss.
14193 */
14194 if(chan == NULL)
14195 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053014196 hddLog(VOS_TRACE_LEVEL_ERROR,
14197 FL("chan pointer is NULL, chan_no: %d freq: %d"),
14198 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070014199 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014200 return NULL;
14201 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053014202 /*To keep the rssi icon of the connected AP in the scan window
14203 *and the rssi icon of the wireless networks in sync
14204 * */
14205 if (( eConnectionState_Associated ==
14206 pAdapter->sessionCtx.station.conn_info.connState ) &&
14207 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
14208 pAdapter->sessionCtx.station.conn_info.bssId,
14209 WNI_CFG_BSSID_LEN)) &&
14210 (pHddCtx->hdd_wlan_suspended == FALSE))
14211 {
14212 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
14213 rssi = (pAdapter->rssi * 100);
14214 }
14215 else
14216 {
14217 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
14218 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014219
Nirav Shah20ac06f2013-12-12 18:14:06 +053014220 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053014221 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
14222 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053014223
Jeff Johnson295189b2012-06-20 16:38:30 -070014224 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
14225 frame_len, rssi, GFP_KERNEL);
14226 kfree(mgmt);
14227 return bss_status;
14228}
14229
14230/*
14231 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
14232 * This function is used to update the BSS data base of CFG8011
14233 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014234struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014235 tCsrRoamInfo *pRoamInfo
14236 )
14237{
14238 tCsrRoamConnectedProfile roamProfile;
14239 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14240 struct cfg80211_bss *bss = NULL;
14241
14242 ENTER();
14243
14244 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
14245 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
14246
14247 if (NULL != roamProfile.pBssDesc)
14248 {
Girish Gowlif4b68022014-08-28 23:18:57 +053014249 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14250 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070014251
14252 if (NULL == bss)
14253 {
14254 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
14255 __func__);
14256 }
14257
14258 sme_RoamFreeConnectProfile(hHal, &roamProfile);
14259 }
14260 else
14261 {
14262 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
14263 __func__);
14264 }
14265 return bss;
14266}
14267
14268/*
14269 * FUNCTION: wlan_hdd_cfg80211_update_bss
14270 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014271static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
14272 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070014273 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014274{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014275 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014276 tCsrScanResultInfo *pScanResult;
14277 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014278 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014279 tScanResultHandle pResult;
14280 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014281 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014282 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070014283 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014284
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014285 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14286 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
14287 NO_SESSION, pAdapter->sessionId));
14288
Wilson Yangf80a0542013-10-07 13:02:37 -070014289 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014290 ret = wlan_hdd_validate_context(pHddCtx);
14291 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070014292 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014293 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070014294 }
14295
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014296 if (pAdapter->request != NULL)
14297 {
14298 if ((pAdapter->request->n_ssids == 1)
14299 && (pAdapter->request->ssids != NULL)
14300 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
14301 is_p2p_scan = true;
14302 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014303 /*
14304 * start getting scan results and populate cgf80211 BSS database
14305 */
14306 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
14307
14308 /* no scan results */
14309 if (NULL == pResult)
14310 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014311 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
14312 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014313 wlan_hdd_get_frame_logs(pAdapter,
14314 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070014315 return status;
14316 }
14317
14318 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
14319
14320 while (pScanResult)
14321 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014322 /*
14323 * cfg80211_inform_bss() is not updating ie field of bss entry, if
14324 * entry already exists in bss data base of cfg80211 for that
14325 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
14326 * bss entry instead of cfg80211_inform_bss, But this call expects
14327 * mgmt packet as input. As of now there is no possibility to get
14328 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070014329 * ieee80211_mgmt(probe response) and passing to c
14330 * fg80211_inform_bss_frame.
14331 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014332 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
14333 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
14334 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014335 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14336 continue; //Skip the non p2p bss entries
14337 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014338 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14339 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014340
Jeff Johnson295189b2012-06-20 16:38:30 -070014341
14342 if (NULL == bss_status)
14343 {
14344 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014345 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014346 }
14347 else
14348 {
Yue Maf49ba872013-08-19 12:04:25 -070014349 cfg80211_put_bss(
14350#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
14351 wiphy,
14352#endif
14353 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070014354 }
14355
14356 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14357 }
14358
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014359 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014360 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014361 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014362}
14363
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014364void
14365hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
14366{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014367 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080014368 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014369} /****** end hddPrintMacAddr() ******/
14370
14371void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014372hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014373{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014374 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014375 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014376 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
14377 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
14378 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014379} /****** end hddPrintPmkId() ******/
14380
14381//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
14382//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
14383
14384//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
14385//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
14386
14387#define dump_bssid(bssid) \
14388 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014389 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
14390 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014391 }
14392
14393#define dump_pmkid(pMac, pmkid) \
14394 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014395 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
14396 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014397 }
14398
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070014399#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014400/*
14401 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
14402 * This function is used to notify the supplicant of a new PMKSA candidate.
14403 */
14404int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014405 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014406 int index, bool preauth )
14407{
Jeff Johnsone7245742012-09-05 17:12:55 -070014408#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014409 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014410 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014411
14412 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070014413 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014414
14415 if( NULL == pRoamInfo )
14416 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014417 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014418 return -EINVAL;
14419 }
14420
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014421 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
14422 {
14423 dump_bssid(pRoamInfo->bssid);
14424 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014425 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014426 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014427#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014428 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014429}
14430#endif //FEATURE_WLAN_LFR
14431
Yue Maef608272013-04-08 23:09:17 -070014432#ifdef FEATURE_WLAN_LFR_METRICS
14433/*
14434 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
14435 * 802.11r/LFR metrics reporting function to report preauth initiation
14436 *
14437 */
14438#define MAX_LFR_METRICS_EVENT_LENGTH 100
14439VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
14440 tCsrRoamInfo *pRoamInfo)
14441{
14442 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14443 union iwreq_data wrqu;
14444
14445 ENTER();
14446
14447 if (NULL == pAdapter)
14448 {
14449 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14450 return VOS_STATUS_E_FAILURE;
14451 }
14452
14453 /* create the event */
14454 memset(&wrqu, 0, sizeof(wrqu));
14455 memset(metrics_notification, 0, sizeof(metrics_notification));
14456
14457 wrqu.data.pointer = metrics_notification;
14458 wrqu.data.length = scnprintf(metrics_notification,
14459 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
14460 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14461
14462 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14463
14464 EXIT();
14465
14466 return VOS_STATUS_SUCCESS;
14467}
14468
14469/*
14470 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
14471 * 802.11r/LFR metrics reporting function to report preauth completion
14472 * or failure
14473 */
14474VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
14475 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
14476{
14477 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14478 union iwreq_data wrqu;
14479
14480 ENTER();
14481
14482 if (NULL == pAdapter)
14483 {
14484 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14485 return VOS_STATUS_E_FAILURE;
14486 }
14487
14488 /* create the event */
14489 memset(&wrqu, 0, sizeof(wrqu));
14490 memset(metrics_notification, 0, sizeof(metrics_notification));
14491
14492 scnprintf(metrics_notification, sizeof(metrics_notification),
14493 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
14494 MAC_ADDR_ARRAY(pRoamInfo->bssid));
14495
14496 if (1 == preauth_status)
14497 strncat(metrics_notification, " TRUE", 5);
14498 else
14499 strncat(metrics_notification, " FALSE", 6);
14500
14501 wrqu.data.pointer = metrics_notification;
14502 wrqu.data.length = strlen(metrics_notification);
14503
14504 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14505
14506 EXIT();
14507
14508 return VOS_STATUS_SUCCESS;
14509}
14510
14511/*
14512 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
14513 * 802.11r/LFR metrics reporting function to report handover initiation
14514 *
14515 */
14516VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
14517 tCsrRoamInfo *pRoamInfo)
14518{
14519 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14520 union iwreq_data wrqu;
14521
14522 ENTER();
14523
14524 if (NULL == pAdapter)
14525 {
14526 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14527 return VOS_STATUS_E_FAILURE;
14528 }
14529
14530 /* create the event */
14531 memset(&wrqu, 0, sizeof(wrqu));
14532 memset(metrics_notification, 0, sizeof(metrics_notification));
14533
14534 wrqu.data.pointer = metrics_notification;
14535 wrqu.data.length = scnprintf(metrics_notification,
14536 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14537 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14538
14539 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14540
14541 EXIT();
14542
14543 return VOS_STATUS_SUCCESS;
14544}
14545#endif
14546
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014547
14548/**
14549 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14550 * @scan_req: scan request to be checked
14551 *
14552 * Return: true or false
14553 */
14554#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14555static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14556 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014557 *scan_req, hdd_context_t
14558 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014559{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014560 if (!scan_req || !scan_req->wiphy ||
14561 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014562 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14563 return false;
14564 }
14565 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14566 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14567 return false;
14568 }
14569 return true;
14570}
14571#else
14572static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14573 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014574 *scan_req, hdd_context_t
14575 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014576{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014577 if (!scan_req || !scan_req->wiphy ||
14578 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014579 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14580 return false;
14581 }
14582 return true;
14583}
14584#endif
14585
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014586#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
14587/**
14588 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14589 * @adapter: Pointer to the adapter
14590 * @req : Scan request
14591 * @aborted : true scan aborted false scan success
14592 *
14593 * This function notifies scan done to cfg80211
14594 *
14595 * Return: none
14596 */
14597static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14598 struct cfg80211_scan_request *req,
14599 bool aborted)
14600{
14601 struct cfg80211_scan_info info = {
14602 .aborted = aborted
14603 };
14604
14605 if (adapter->dev->flags & IFF_UP)
14606 cfg80211_scan_done(req, &info);
14607 else
14608 hddLog(LOGW,
14609 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14610}
14611#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14612/**
14613 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14614 * @adapter: Pointer to the adapter
14615 * @req : Scan request
14616 * @aborted : true scan aborted false scan success
14617 *
14618 * This function notifies scan done to cfg80211
14619 *
14620 * Return: none
14621 */
14622static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14623 struct cfg80211_scan_request *req,
14624 bool aborted)
14625{
14626 if (adapter->dev->flags & IFF_UP)
14627 cfg80211_scan_done(req, aborted);
14628 else
14629 hddLog(LOGW,
14630 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14631}
14632#else
14633/**
14634 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14635 * @adapter: Pointer to the adapter
14636 * @req : Scan request
14637 * @aborted : true scan aborted false scan success
14638 *
14639 * This function notifies scan done to cfg80211
14640 *
14641 * Return: none
14642 */
14643static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14644 struct cfg80211_scan_request *req,
14645 bool aborted)
14646{
14647 cfg80211_scan_done(req, aborted);
14648}
14649#endif
14650
Mukul Sharmab392b642017-08-17 17:45:29 +053014651#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014652/*
14653 * FUNCTION: hdd_cfg80211_scan_done_callback
14654 * scanning callback function, called after finishing scan
14655 *
14656 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014657static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014658 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14659{
14660 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014661 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014662 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014663 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014664 struct cfg80211_scan_request *req = NULL;
14665 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014666 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014667 long waitRet = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014668 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014669
14670 ENTER();
14671
c_manjee1b4ab9a2016-10-26 11:36:55 +053014672 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14673 !pAdapter->dev) {
14674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14675 return 0;
14676 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014677 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014678 if (NULL == pHddCtx) {
14679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014680 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014681 }
14682
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014683#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014684 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014685 {
14686 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014687 }
14688#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014689 pScanInfo = &pHddCtx->scan_info;
14690
Jeff Johnson295189b2012-06-20 16:38:30 -070014691 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014692 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014693 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014694 __func__, halHandle, pContext, (int) scanId, (int) status);
14695
Kiet Lamac06e2c2013-10-23 16:25:07 +053014696 pScanInfo->mScanPendingCounter = 0;
14697
Jeff Johnson295189b2012-06-20 16:38:30 -070014698 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014699 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014700 &pScanInfo->scan_req_completion_event,
14701 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014702 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014703 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014704 hddLog(VOS_TRACE_LEVEL_ERROR,
14705 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014706 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014707 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014708 }
14709
Yue Maef608272013-04-08 23:09:17 -070014710 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014711 {
14712 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014713 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014714 }
14715
14716 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014717 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014718 {
14719 hddLog(VOS_TRACE_LEVEL_INFO,
14720 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014721 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014722 (int) scanId);
14723 }
14724
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014725#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014726 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014727#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014728 {
14729 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14730 pAdapter);
14731 if (0 > ret)
14732 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014733 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014734
Jeff Johnson295189b2012-06-20 16:38:30 -070014735 /* If any client wait scan result through WEXT
14736 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014737 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014738 {
14739 /* The other scan request waiting for current scan finish
14740 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014741 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014742 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014743 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014744 }
14745 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014746 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014747 {
14748 struct net_device *dev = pAdapter->dev;
14749 union iwreq_data wrqu;
14750 int we_event;
14751 char *msg;
14752
14753 memset(&wrqu, '\0', sizeof(wrqu));
14754 we_event = SIOCGIWSCAN;
14755 msg = NULL;
14756 wireless_send_event(dev, we_event, &wrqu, msg);
14757 }
14758 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014759 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014760
14761 /* Get the Scan Req */
14762 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014763 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014764
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014765 /* Scan is no longer pending */
14766 pScanInfo->mScanPending = VOS_FALSE;
14767
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014768 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070014769 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014770#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
14771 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053014772 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014773#endif
14774
14775 if (pAdapter->dev) {
14776 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
14777 pAdapter->dev->name);
14778 }
mukul sharmae7041822015-12-03 15:09:21 +053014779 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070014780 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014781 }
14782
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014783 /* last_scan_timestamp is used to decide if new scan
14784 * is needed or not on station interface. If last station
14785 * scan time and new station scan time is less then
14786 * last_scan_timestamp ; driver will return cached scan.
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014787 * Also only last_scan_timestamp is updated here last_scan_channellist
14788 * is updated on receiving scan request itself to make sure kernel
14789 * allocated scan request(scan_req) object is not dereferenced here,
14790 * because interface down, where kernel frees scan_req, may happen any
14791 * time while driver is processing scan_done_callback. So it's better
14792 * not to access scan_req in this routine.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014793 */
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014794 if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
14795 if (status == eCSR_SCAN_SUCCESS)
14796 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
14797 else {
14798 vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
14799 sizeof(pHddCtx->scan_info.last_scan_channelList));
14800 pHddCtx->scan_info.last_scan_numChannels = 0;
14801 pScanInfo->last_scan_timestamp = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014802 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014803 }
14804
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070014805 /*
14806 * cfg80211_scan_done informing NL80211 about completion
14807 * of scanning
14808 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014809 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
14810 {
14811 aborted = true;
14812 }
mukul sharmae7041822015-12-03 15:09:21 +053014813
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014814#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014815 if (NET_DEV_IS_IFF_UP(pAdapter) &&
14816 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014817#endif
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014818 hdd_cfg80211_scan_done(pAdapter, req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053014819
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080014820 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070014821
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014822allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014823 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
14824 ) && (pHddCtx->spoofMacAddr.isEnabled
14825 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053014826 /* Generate new random mac addr for next scan */
14827 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053014828
14829 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
14830 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053014831 }
14832
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014833 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014834 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014835
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014836 /* Acquire wakelock to handle the case where APP's tries to suspend
14837 * immediatly after the driver gets connect request(i.e after scan)
14838 * from supplicant, this result in app's is suspending and not able
14839 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014840 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014841
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014842#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014843 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014844#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014845#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014846 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014847#endif
14848
Jeff Johnson295189b2012-06-20 16:38:30 -070014849 EXIT();
14850 return 0;
14851}
14852
14853/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053014854 * FUNCTION: hdd_isConnectionInProgress
14855 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014856 *
14857 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014858v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
14859 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014860{
14861 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14862 hdd_station_ctx_t *pHddStaCtx = NULL;
14863 hdd_adapter_t *pAdapter = NULL;
14864 VOS_STATUS status = 0;
14865 v_U8_t staId = 0;
14866 v_U8_t *staMac = NULL;
14867
14868 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14869
14870 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14871 {
14872 pAdapter = pAdapterNode->pAdapter;
14873
14874 if( pAdapter )
14875 {
14876 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014877 "%s: Adapter with device mode %s (%d) exists",
14878 __func__, hdd_device_modetoString(pAdapter->device_mode),
14879 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014880 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053014881 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14882 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
14883 (eConnectionState_Connecting ==
14884 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14885 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014886 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014887 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053014888 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014889 if (session_id && reason)
14890 {
14891 *session_id = pAdapter->sessionId;
14892 *reason = eHDD_CONNECTION_IN_PROGRESS;
14893 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014894 return VOS_TRUE;
14895 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014896 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053014897 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014898 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014899 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014900 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014901 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014902 if (session_id && reason)
14903 {
14904 *session_id = pAdapter->sessionId;
14905 *reason = eHDD_REASSOC_IN_PROGRESS;
14906 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014907 return VOS_TRUE;
14908 }
14909 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014910 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14911 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014912 {
14913 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14914 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014915 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014916 {
14917 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014918 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014919 "%s: client " MAC_ADDRESS_STR
14920 " is in the middle of WPS/EAPOL exchange.", __func__,
14921 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014922 if (session_id && reason)
14923 {
14924 *session_id = pAdapter->sessionId;
14925 *reason = eHDD_EAPOL_IN_PROGRESS;
14926 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014927 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014928 }
14929 }
14930 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
14931 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
14932 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014933 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14934 ptSapContext pSapCtx = NULL;
14935 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14936 if(pSapCtx == NULL){
14937 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14938 FL("psapCtx is NULL"));
14939 return VOS_FALSE;
14940 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014941 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
14942 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014943 if ((pSapCtx->aStaInfo[staId].isUsed) &&
14944 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014945 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014946 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014947
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014948 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014949 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
14950 "middle of WPS/EAPOL exchange.", __func__,
14951 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014952 if (session_id && reason)
14953 {
14954 *session_id = pAdapter->sessionId;
14955 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
14956 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014957 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014958 }
14959 }
14960 }
14961 }
14962 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14963 pAdapterNode = pNext;
14964 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014965 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014966}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014967
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014968/**
14969 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
14970 * to the Scan request
14971 * @scanRequest: Pointer to the csr scan request
14972 * @request: Pointer to the scan request from supplicant
14973 *
14974 * Return: None
14975 */
14976#ifdef CFG80211_SCAN_BSSID
14977static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14978 struct cfg80211_scan_request *request)
14979{
14980 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
14981}
14982#else
14983static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14984 struct cfg80211_scan_request *request)
14985{
14986}
14987#endif
14988
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014989/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014990 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070014991 * this scan respond to scan trigger and update cfg80211 scan database
14992 * later, scan dump command can be used to recieve scan results
14993 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014994int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014995#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14996 struct net_device *dev,
14997#endif
14998 struct cfg80211_scan_request *request)
14999{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015000 hdd_adapter_t *pAdapter = NULL;
15001 hdd_context_t *pHddCtx = NULL;
15002 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015003 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015004 tCsrScanRequest scanRequest;
15005 tANI_U8 *channelList = NULL, i;
15006 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015007 int status;
15008 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015009 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015010 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053015011 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015012 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015013 v_U8_t curr_session_id;
15014 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070015015
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015016#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
15017 struct net_device *dev = NULL;
15018 if (NULL == request)
15019 {
15020 hddLog(VOS_TRACE_LEVEL_ERROR,
15021 "%s: scan req param null", __func__);
15022 return -EINVAL;
15023 }
15024 dev = request->wdev->netdev;
15025#endif
15026
15027 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15028 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
15029 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15030
Jeff Johnson295189b2012-06-20 16:38:30 -070015031 ENTER();
15032
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015033 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
15034 __func__, hdd_device_modetoString(pAdapter->device_mode),
15035 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015036
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015037 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015038 if (0 != status)
15039 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015040 return status;
15041 }
15042
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015043 if (NULL == pwextBuf)
15044 {
15045 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
15046 __func__);
15047 return -EIO;
15048 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015049 cfg_param = pHddCtx->cfg_ini;
15050 pScanInfo = &pHddCtx->scan_info;
15051
Jeff Johnson295189b2012-06-20 16:38:30 -070015052#ifdef WLAN_BTAMP_FEATURE
15053 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015054 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070015055 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015056 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015057 "%s: No scanning when AMP is on", __func__);
15058 return -EOPNOTSUPP;
15059 }
15060#endif
15061 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015062 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070015063 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015064 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015065 "%s: Not scanning on device_mode = %s (%d)",
15066 __func__, hdd_device_modetoString(pAdapter->device_mode),
15067 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015068 return -EOPNOTSUPP;
15069 }
15070
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015071 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
15072 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
15073 return -EOPNOTSUPP;
15074 }
15075
Jeff Johnson295189b2012-06-20 16:38:30 -070015076 if (TRUE == pScanInfo->mScanPending)
15077 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015078 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
15079 {
15080 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
15081 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015082 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015083 }
15084
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053015085 // Don't allow scan if PNO scan is going on.
15086 if (pHddCtx->isPnoEnable)
15087 {
15088 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15089 FL("pno scan in progress"));
15090 return -EBUSY;
15091 }
15092
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015093 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070015094 //Channel and action frame is pending
15095 //Otherwise Cancel Remain On Channel and allow Scan
15096 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015097 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070015098 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015099 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070015100 return -EBUSY;
15101 }
15102
Jeff Johnson295189b2012-06-20 16:38:30 -070015103 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
15104 {
15105 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080015106 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015107 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015108 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015109 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
15110 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015111 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015112 "%s: MAX TM Level Scan not allowed", __func__);
15113 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015114 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015115 }
15116 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
15117
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015118 /* Check if scan is allowed at this point of time.
15119 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053015120 if (TRUE == pHddCtx->btCoexModeSet)
15121 {
15122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15123 FL("BTCoex Mode operation in progress"));
15124 return -EBUSY;
15125 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015126 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015127 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015128
15129 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
15130 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
15131 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015132 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
15133 pHddCtx->last_scan_reject_reason != curr_reason ||
15134 !pHddCtx->last_scan_reject_timestamp)
15135 {
15136 pHddCtx->last_scan_reject_session_id = curr_session_id;
15137 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053015138 pHddCtx->last_scan_reject_timestamp =
15139 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015140 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053015141 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053015142 else
15143 {
15144 pHddCtx->scan_reject_cnt++;
15145
Abhishek Singhe4b12562017-06-20 16:53:39 +053015146 if ((pHddCtx->scan_reject_cnt >=
15147 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053015148 vos_system_time_after(jiffies_to_msecs(jiffies),
15149 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015150 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015151 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
15152 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
15153 vos_system_time_after(jiffies_to_msecs(jiffies),
15154 pHddCtx->last_scan_reject_timestamp));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015155 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015156 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015157 if (pHddCtx->cfg_ini->enableFatalEvent)
15158 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
15159 WLAN_LOG_INDICATOR_HOST_DRIVER,
15160 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
15161 FALSE, FALSE);
15162 else
15163 {
15164 hddLog(LOGE, FL("Triggering SSR"));
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +053015165 vos_wlanRestart(VOS_SCAN_REQ_EXPIRED);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015166 }
15167 }
15168 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015169 return -EBUSY;
15170 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015171 pHddCtx->last_scan_reject_timestamp = 0;
15172 pHddCtx->last_scan_reject_session_id = 0xFF;
15173 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015174 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015175
Jeff Johnson295189b2012-06-20 16:38:30 -070015176 vos_mem_zero( &scanRequest, sizeof(scanRequest));
15177
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015178 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
15179 * Becasue of this, driver is assuming that this is not wildcard scan and so
15180 * is not aging out the scan results.
15181 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053015182 if ((request->ssids) && (request->n_ssids == 1) &&
15183 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015184 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015185 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015186
15187 if ((request->ssids) && (0 < request->n_ssids))
15188 {
15189 tCsrSSIDInfo *SsidInfo;
15190 int j;
15191 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
15192 /* Allocate num_ssid tCsrSSIDInfo structure */
15193 SsidInfo = scanRequest.SSIDs.SSIDList =
15194 ( tCsrSSIDInfo *)vos_mem_malloc(
15195 request->n_ssids*sizeof(tCsrSSIDInfo));
15196
15197 if(NULL == scanRequest.SSIDs.SSIDList)
15198 {
15199 hddLog(VOS_TRACE_LEVEL_ERROR,
15200 "%s: memory alloc failed SSIDInfo buffer", __func__);
15201 return -ENOMEM;
15202 }
15203
15204 /* copy all the ssid's and their length */
15205 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
15206 {
15207 /* get the ssid length */
15208 SsidInfo->SSID.length = request->ssids[j].ssid_len;
15209 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
15210 SsidInfo->SSID.length);
15211 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
15212 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
15213 j, SsidInfo->SSID.ssId);
15214 }
15215 /* set the scan type to active */
15216 scanRequest.scanType = eSIR_ACTIVE_SCAN;
15217 }
15218 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015219 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015220 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15221 TRACE_CODE_HDD_CFG80211_SCAN,
15222 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070015223 /* set the scan type to active */
15224 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070015225 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015226 else
15227 {
15228 /*Set the scan type to default type, in this case it is ACTIVE*/
15229 scanRequest.scanType = pScanInfo->scan_mode;
15230 }
15231 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
15232 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070015233
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015234 csr_scan_request_assign_bssid(&scanRequest, request);
15235
Jeff Johnson295189b2012-06-20 16:38:30 -070015236 /* set BSSType to default type */
15237 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
15238
15239 /*TODO: scan the requested channels only*/
15240
15241 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015242 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070015243 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015244 hddLog(VOS_TRACE_LEVEL_WARN,
15245 "No of Scan Channels exceeded limit: %d", request->n_channels);
15246 request->n_channels = MAX_CHANNEL;
15247 }
15248
15249 hddLog(VOS_TRACE_LEVEL_INFO,
15250 "No of Scan Channels: %d", request->n_channels);
15251
15252
15253 if( request->n_channels )
15254 {
15255 char chList [(request->n_channels*5)+1];
15256 int len;
15257 channelList = vos_mem_malloc( request->n_channels );
15258 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053015259 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015260 hddLog(VOS_TRACE_LEVEL_ERROR,
15261 "%s: memory alloc failed channelList", __func__);
15262 status = -ENOMEM;
15263 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053015264 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015265
15266 for( i = 0, len = 0; i < request->n_channels ; i++ )
15267 {
15268 channelList[i] = request->channels[i]->hw_value;
15269 len += snprintf(chList+len, 5, "%d ", channelList[i]);
15270 }
15271
Nirav Shah20ac06f2013-12-12 18:14:06 +053015272 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015273 "Channel-List: %s ", chList);
15274 }
c_hpothu53512302014-04-15 18:49:53 +053015275
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015276 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
15277 scanRequest.ChannelInfo.ChannelList = channelList;
15278
15279 /* set requestType to full scan */
15280 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
15281
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015282 /* if there is back to back scan happening in driver with in
15283 * nDeferScanTimeInterval interval driver should defer new scan request
15284 * and should provide last cached scan results instead of new channel list.
15285 * This rule is not applicable if scan is p2p scan.
15286 * This condition will work only in case when last request no of channels
15287 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053015288 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053015289 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015290 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015291
Sushant Kaushik86592172015-04-27 16:35:03 +053015292 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
15293 /* if wps ie is NULL , then only defer scan */
15294 if ( pWpsIe == NULL &&
15295 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053015296 {
15297 if ( pScanInfo->last_scan_timestamp !=0 &&
15298 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
15299 {
15300 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
15301 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
15302 vos_mem_compare(pScanInfo->last_scan_channelList,
15303 channelList, pScanInfo->last_scan_numChannels))
15304 {
15305 hddLog(VOS_TRACE_LEVEL_WARN,
15306 " New and old station scan time differ is less then %u",
15307 pHddCtx->cfg_ini->nDeferScanTimeInterval);
15308
15309 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015310 pAdapter);
15311
Agarwal Ashish57e84372014-12-05 18:26:53 +053015312 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015313 "Return old cached scan as all channels and no of channels are same");
15314
Agarwal Ashish57e84372014-12-05 18:26:53 +053015315 if (0 > ret)
15316 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015317
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015318 hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015319
15320 status = eHAL_STATUS_SUCCESS;
15321 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053015322 }
15323 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015324 }
15325
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015326 /* Flush the scan results(only p2p beacons) for STA scan and P2P
15327 * search (Flush on both full scan and social scan but not on single
15328 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
15329 */
15330
15331 /* Supplicant does single channel scan after 8-way handshake
15332 * and in that case driver shoudnt flush scan results. If
15333 * driver flushes the scan results here and unfortunately if
15334 * the AP doesnt respond to our probe req then association
15335 * fails which is not desired
15336 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015337 if ((request->n_ssids == 1)
15338 && (request->ssids != NULL)
15339 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
15340 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015341
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015342 if( is_p2p_scan ||
15343 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015344 {
15345 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
15346 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
15347 pAdapter->sessionId );
15348 }
15349
15350 if( request->ie_len )
15351 {
15352 /* save this for future association (join requires this) */
15353 /*TODO: Array needs to be converted to dynamic allocation,
15354 * as multiple ie.s can be sent in cfg80211_scan_request structure
15355 * CR 597966
15356 */
15357 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
15358 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
15359 pScanInfo->scanAddIE.length = request->ie_len;
15360
15361 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15362 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15363 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015364 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015365 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070015366 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015367 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
15368 memcpy( pwextBuf->roamProfile.addIEScan,
15369 request->ie, request->ie_len);
15370 }
15371 else
15372 {
15373 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
15374 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070015375 }
15376
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015377 }
15378 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
15379 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
15380
15381 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
15382 request->ie_len);
15383 if (pP2pIe != NULL)
15384 {
15385#ifdef WLAN_FEATURE_P2P_DEBUG
15386 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
15387 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
15388 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053015389 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015390 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
15391 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15392 "Go nego completed to Connection is started");
15393 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15394 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053015395 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015396 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
15397 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015398 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015399 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
15400 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15401 "Disconnected state to Connection is started");
15402 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15403 "for 4way Handshake");
15404 }
15405#endif
15406
15407 /* no_cck will be set during p2p find to disable 11b rates */
15408 if(TRUE == request->no_cck)
15409 {
15410 hddLog(VOS_TRACE_LEVEL_INFO,
15411 "%s: This is a P2P Search", __func__);
15412 scanRequest.p2pSearch = 1;
15413
15414 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053015415 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015416 /* set requestType to P2P Discovery */
15417 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
15418 }
15419
15420 /*
15421 Skip Dfs Channel in case of P2P Search
15422 if it is set in ini file
15423 */
15424 if(cfg_param->skipDfsChnlInP2pSearch)
15425 {
15426 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015427 }
15428 else
15429 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015430 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015431 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015432
Agarwal Ashish4f616132013-12-30 23:32:50 +053015433 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015434 }
15435 }
15436
15437 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
15438
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015439#ifdef FEATURE_WLAN_TDLS
15440 /* if tdls disagree scan right now, return immediately.
15441 tdls will schedule the scan when scan is allowed. (return SUCCESS)
15442 or will reject the scan if any TDLS is in progress. (return -EBUSY)
15443 */
15444 status = wlan_hdd_tdls_scan_callback (pAdapter,
15445 wiphy,
15446#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15447 dev,
15448#endif
15449 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015450 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015451 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053015452 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015453 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
15454 "scan rejected %d", __func__, status);
15455 else
15456 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
15457 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015458 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053015459 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015460 }
15461#endif
15462
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015463 /* acquire the wakelock to avoid the apps suspend during the scan. To
15464 * address the following issues.
15465 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
15466 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
15467 * for long time, this result in apps running at full power for long time.
15468 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
15469 * be stuck in full power because of resume BMPS
15470 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015471 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015472
Nirav Shah20ac06f2013-12-12 18:14:06 +053015473 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
15474 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015475 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
15476 scanRequest.requestType, scanRequest.scanType,
15477 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053015478 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
15479
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015480 if (pHddCtx->spoofMacAddr.isEnabled &&
15481 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053015482 {
15483 hddLog(VOS_TRACE_LEVEL_INFO,
15484 "%s: MAC Spoofing enabled for current scan", __func__);
15485 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15486 * to fill TxBds for probe request during current scan
15487 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015488 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053015489 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015490
15491 if(status != VOS_STATUS_SUCCESS)
15492 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015493 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015494 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053015495#ifdef FEATURE_WLAN_TDLS
15496 wlan_hdd_tdls_scan_done_callback(pAdapter);
15497#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015498 goto free_mem;
15499 }
Siddharth Bhal76972212014-10-15 16:22:51 +053015500 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053015501 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070015502 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015503 pAdapter->sessionId, &scanRequest, &scanId,
15504 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070015505
Jeff Johnson295189b2012-06-20 16:38:30 -070015506 if (eHAL_STATUS_SUCCESS != status)
15507 {
15508 hddLog(VOS_TRACE_LEVEL_ERROR,
15509 "%s: sme_ScanRequest returned error %d", __func__, status);
15510 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015511 if(eHAL_STATUS_RESOURCES == status)
15512 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015513 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
15514 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015515 status = -EBUSY;
15516 } else {
15517 status = -EIO;
15518 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015519 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015520
15521#ifdef FEATURE_WLAN_TDLS
15522 wlan_hdd_tdls_scan_done_callback(pAdapter);
15523#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015524 goto free_mem;
15525 }
15526
15527 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015528 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070015529 pAdapter->request = request;
15530 pScanInfo->scanId = scanId;
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015531 pScanInfo->no_cck = request->no_cck;
15532 pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
15533 for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
15534 pHddCtx->scan_info.last_scan_channelList[i] =
15535 request->channels[i]->hw_value;
15536 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015537
15538 complete(&pScanInfo->scan_req_completion_event);
15539
15540free_mem:
15541 if( scanRequest.SSIDs.SSIDList )
15542 {
15543 vos_mem_free(scanRequest.SSIDs.SSIDList);
15544 }
15545
15546 if( channelList )
15547 vos_mem_free( channelList );
15548
15549 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015550 return status;
15551}
15552
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015553int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
15554#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15555 struct net_device *dev,
15556#endif
15557 struct cfg80211_scan_request *request)
15558{
15559 int ret;
15560
15561 vos_ssr_protect(__func__);
15562 ret = __wlan_hdd_cfg80211_scan(wiphy,
15563#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15564 dev,
15565#endif
15566 request);
15567 vos_ssr_unprotect(__func__);
15568
15569 return ret;
15570}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015571
15572void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
15573{
15574 v_U8_t iniDot11Mode =
15575 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
15576 eHddDot11Mode hddDot11Mode = iniDot11Mode;
15577
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015578 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
15579 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015580 switch ( iniDot11Mode )
15581 {
15582 case eHDD_DOT11_MODE_AUTO:
15583 case eHDD_DOT11_MODE_11ac:
15584 case eHDD_DOT11_MODE_11ac_ONLY:
15585#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053015586 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
15587 sme_IsFeatureSupportedByFW(DOT11AC) )
15588 hddDot11Mode = eHDD_DOT11_MODE_11ac;
15589 else
15590 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015591#else
15592 hddDot11Mode = eHDD_DOT11_MODE_11n;
15593#endif
15594 break;
15595 case eHDD_DOT11_MODE_11n:
15596 case eHDD_DOT11_MODE_11n_ONLY:
15597 hddDot11Mode = eHDD_DOT11_MODE_11n;
15598 break;
15599 default:
15600 hddDot11Mode = iniDot11Mode;
15601 break;
15602 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015603#ifdef WLAN_FEATURE_AP_HT40_24G
15604 if (operationChannel > SIR_11B_CHANNEL_END)
15605#endif
15606 {
15607 /* This call decides required channel bonding mode */
15608 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015609 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053015610 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015611 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015612}
15613
Jeff Johnson295189b2012-06-20 16:38:30 -070015614/*
15615 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015616 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015617 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015618int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053015619 const u8 *ssid, size_t ssid_len, const u8 *bssid,
15620 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070015621{
15622 int status = 0;
15623 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080015624 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015625 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015626 v_U32_t roamId;
15627 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070015628 eCsrAuthType RSNAuthType;
15629
15630 ENTER();
15631
15632 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015633 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015634 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015635
15636 status = wlan_hdd_validate_context(pHddCtx);
15637 if (status)
15638 {
Yue Mae36e3552014-03-05 17:06:20 -080015639 return status;
15640 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015641
Jeff Johnson295189b2012-06-20 16:38:30 -070015642 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
15643 {
15644 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
15645 return -EINVAL;
15646 }
15647
Nitesh Shah9b066282017-06-06 18:05:52 +053015648 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
15649
Jeff Johnson295189b2012-06-20 16:38:30 -070015650 pRoamProfile = &pWextState->roamProfile;
15651
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015652 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070015653 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015654 hdd_station_ctx_t *pHddStaCtx;
15655 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053015656 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015657
Siddharth Bhalda0d1622015-04-24 15:47:49 +053015658 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
15659
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015660 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070015661 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
15662 {
15663 /*QoS not enabled in cfg file*/
15664 pRoamProfile->uapsd_mask = 0;
15665 }
15666 else
15667 {
15668 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015669 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070015670 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
15671 }
15672
15673 pRoamProfile->SSIDs.numOfSSIDs = 1;
15674 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
15675 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015676 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070015677 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
15678 ssid, ssid_len);
15679
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015680 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
15681 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
15682
Jeff Johnson295189b2012-06-20 16:38:30 -070015683 if (bssid)
15684 {
15685 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015686 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015687 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015688 /* Save BSSID in seperate variable as well, as RoamProfile
15689 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070015690 case of join failure we should send valid BSSID to supplicant
15691 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015692 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015693 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015694
Jeff Johnson295189b2012-06-20 16:38:30 -070015695 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015696 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070015697 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015698 /* Store bssid_hint to use in the scan filter. */
15699 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15700 WNI_CFG_BSSID_LEN);
15701 /*
15702 * Save BSSID in seperate variable as well, as RoamProfile
15703 * BSSID is getting zeroed out in the association process. And in
15704 * case of join failure we should send valid BSSID to supplicant
15705 */
15706 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15707 WNI_CFG_BSSID_LEN);
15708 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15709 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015710 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015711
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015712
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015713 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15714 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015715 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15716 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015717 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015718 /*set gen ie*/
15719 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15720 /*set auth*/
15721 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15722 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015723#ifdef FEATURE_WLAN_WAPI
15724 if (pAdapter->wapi_info.nWapiMode)
15725 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015726 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015727 switch (pAdapter->wapi_info.wapiAuthMode)
15728 {
15729 case WAPI_AUTH_MODE_PSK:
15730 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015731 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015732 pAdapter->wapi_info.wapiAuthMode);
15733 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15734 break;
15735 }
15736 case WAPI_AUTH_MODE_CERT:
15737 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015738 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015739 pAdapter->wapi_info.wapiAuthMode);
15740 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15741 break;
15742 }
15743 } // End of switch
15744 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15745 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15746 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015747 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015748 pRoamProfile->AuthType.numEntries = 1;
15749 pRoamProfile->EncryptionType.numEntries = 1;
15750 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15751 pRoamProfile->mcEncryptionType.numEntries = 1;
15752 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15753 }
15754 }
15755#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015756#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015757 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015758 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15759 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
15760 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015761 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
15762 sizeof (tSirGtkOffloadParams));
15763 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015764 }
15765#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015766 pRoamProfile->csrPersona = pAdapter->device_mode;
15767
Jeff Johnson32d95a32012-09-10 13:15:23 -070015768 if( operatingChannel )
15769 {
15770 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
15771 pRoamProfile->ChannelInfo.numOfChannels = 1;
15772 }
Chet Lanctot186b5732013-03-18 10:26:30 -070015773 else
15774 {
15775 pRoamProfile->ChannelInfo.ChannelList = NULL;
15776 pRoamProfile->ChannelInfo.numOfChannels = 0;
15777 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015778 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
15779 {
15780 hdd_select_cbmode(pAdapter,operatingChannel);
15781 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015782
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015783 /*
15784 * Change conn_state to connecting before sme_RoamConnect(),
15785 * because sme_RoamConnect() has a direct path to call
15786 * hdd_smeRoamCallback(), which will change the conn_state
15787 * If direct path, conn_state will be accordingly changed
15788 * to NotConnected or Associated by either
15789 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
15790 * in sme_RoamCallback()
15791 * if sme_RomConnect is to be queued,
15792 * Connecting state will remain until it is completed.
15793 * If connection state is not changed,
15794 * connection state will remain in eConnectionState_NotConnected state.
15795 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
15796 * if conn state is eConnectionState_NotConnected.
15797 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
15798 * informed of connect result indication which is an issue.
15799 */
15800
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015801 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15802 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053015803 {
15804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015805 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015806 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
15807 eConnectionState_Connecting);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053015808 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
15809 hdd_wait_for_ecsa_complete(pHddCtx);
Abhishek Singhf4669da2014-05-26 15:07:49 +053015810 }
Abhishek Singh10e17cf2018-03-12 14:34:22 +053015811
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015812 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015813 pAdapter->sessionId, pRoamProfile, &roamId);
15814
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015815 if ((eHAL_STATUS_SUCCESS != status) &&
15816 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15817 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015818
15819 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015820 hddLog(VOS_TRACE_LEVEL_ERROR,
15821 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
15822 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015823 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015824 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015825 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015826 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015827
15828 pRoamProfile->ChannelInfo.ChannelList = NULL;
15829 pRoamProfile->ChannelInfo.numOfChannels = 0;
15830
Jeff Johnson295189b2012-06-20 16:38:30 -070015831 }
15832 else
15833 {
15834 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
15835 return -EINVAL;
15836 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015837 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015838 return status;
15839}
15840
15841/*
15842 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
15843 * This function is used to set the authentication type (OPEN/SHARED).
15844 *
15845 */
15846static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
15847 enum nl80211_auth_type auth_type)
15848{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015849 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015850 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15851
15852 ENTER();
15853
15854 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015855 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070015856 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015857 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015858 hddLog(VOS_TRACE_LEVEL_INFO,
15859 "%s: set authentication type to AUTOSWITCH", __func__);
15860 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
15861 break;
15862
15863 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015864#ifdef WLAN_FEATURE_VOWIFI_11R
15865 case NL80211_AUTHTYPE_FT:
15866#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015867 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015868 "%s: set authentication type to OPEN", __func__);
15869 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
15870 break;
15871
15872 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015873 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015874 "%s: set authentication type to SHARED", __func__);
15875 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
15876 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015877#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015878 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015879 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015880 "%s: set authentication type to CCKM WPA", __func__);
15881 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
15882 break;
15883#endif
15884
15885
15886 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015887 hddLog(VOS_TRACE_LEVEL_ERROR,
15888 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015889 auth_type);
15890 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
15891 return -EINVAL;
15892 }
15893
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015894 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015895 pHddStaCtx->conn_info.authType;
15896 return 0;
15897}
15898
15899/*
15900 * FUNCTION: wlan_hdd_set_akm_suite
15901 * This function is used to set the key mgmt type(PSK/8021x).
15902 *
15903 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015904static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015905 u32 key_mgmt
15906 )
15907{
15908 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15909 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053015910 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015911#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015912#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015913#endif
15914#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015915#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015916#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015917 /*set key mgmt type*/
15918 switch(key_mgmt)
15919 {
15920 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053015921 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015922#ifdef WLAN_FEATURE_VOWIFI_11R
15923 case WLAN_AKM_SUITE_FT_PSK:
15924#endif
15925 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070015926 __func__);
15927 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
15928 break;
15929
15930 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053015931 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015932#ifdef WLAN_FEATURE_VOWIFI_11R
15933 case WLAN_AKM_SUITE_FT_8021X:
15934#endif
15935 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070015936 __func__);
15937 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15938 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015939#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015940#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
15941#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
15942 case WLAN_AKM_SUITE_CCKM:
15943 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
15944 __func__);
15945 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
15946 break;
15947#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070015948#ifndef WLAN_AKM_SUITE_OSEN
15949#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
15950 case WLAN_AKM_SUITE_OSEN:
15951 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
15952 __func__);
15953 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15954 break;
15955#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015956
15957 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015958 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015959 __func__, key_mgmt);
15960 return -EINVAL;
15961
15962 }
15963 return 0;
15964}
15965
15966/*
15967 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015968 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070015969 * (NONE/WEP40/WEP104/TKIP/CCMP).
15970 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015971static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
15972 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070015973 bool ucast
15974 )
15975{
15976 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015977 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015978 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15979
15980 ENTER();
15981
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015982 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015983 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053015984 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070015985 __func__, cipher);
15986 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15987 }
15988 else
15989 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015990
Jeff Johnson295189b2012-06-20 16:38:30 -070015991 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015992 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015993 {
15994 case IW_AUTH_CIPHER_NONE:
15995 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15996 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015997
Jeff Johnson295189b2012-06-20 16:38:30 -070015998 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015999 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070016000 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016001
Jeff Johnson295189b2012-06-20 16:38:30 -070016002 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016003 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070016004 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016005
Jeff Johnson295189b2012-06-20 16:38:30 -070016006 case WLAN_CIPHER_SUITE_TKIP:
16007 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
16008 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016009
Jeff Johnson295189b2012-06-20 16:38:30 -070016010 case WLAN_CIPHER_SUITE_CCMP:
16011 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16012 break;
16013#ifdef FEATURE_WLAN_WAPI
16014 case WLAN_CIPHER_SUITE_SMS4:
16015 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
16016 break;
16017#endif
16018
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016019#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016020 case WLAN_CIPHER_SUITE_KRK:
16021 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
16022 break;
16023#endif
16024 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016025 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016026 __func__, cipher);
16027 return -EOPNOTSUPP;
16028 }
16029 }
16030
16031 if (ucast)
16032 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016033 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016034 __func__, encryptionType);
16035 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16036 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016037 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016038 encryptionType;
16039 }
16040 else
16041 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016042 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016043 __func__, encryptionType);
16044 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
16045 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
16046 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
16047 }
16048
16049 return 0;
16050}
16051
16052
16053/*
16054 * FUNCTION: wlan_hdd_cfg80211_set_ie
16055 * This function is used to parse WPA/RSN IE's.
16056 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016057int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016058#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16059 const u8 *ie,
16060#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016061 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016062#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016063 size_t ie_len
16064 )
16065{
16066 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016067#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16068 const u8 *genie = ie;
16069#else
Jeff Johnson295189b2012-06-20 16:38:30 -070016070 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016071#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016072 v_U16_t remLen = ie_len;
16073#ifdef FEATURE_WLAN_WAPI
16074 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
16075 u16 *tmp;
16076 v_U16_t akmsuiteCount;
16077 int *akmlist;
16078#endif
16079 ENTER();
16080
16081 /* clear previous assocAddIE */
16082 pWextState->assocAddIE.length = 0;
16083 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016084 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016085
16086 while (remLen >= 2)
16087 {
16088 v_U16_t eLen = 0;
16089 v_U8_t elementId;
16090 elementId = *genie++;
16091 eLen = *genie++;
16092 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016093
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053016094 /* Sanity check on eLen */
16095 if (eLen > remLen) {
16096 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
16097 __func__, eLen, elementId);
16098 VOS_ASSERT(0);
16099 return -EINVAL;
16100 }
16101
Arif Hussain6d2a3322013-11-17 19:50:10 -080016102 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070016103 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016104
16105 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070016106 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016107 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016108 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 -070016109 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016110 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016111 "%s: Invalid WPA IE", __func__);
16112 return -EINVAL;
16113 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016114 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070016115 {
16116 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016117 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016118 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016119
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016120 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016121 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016122 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
16123 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016124 VOS_ASSERT(0);
16125 return -ENOMEM;
16126 }
16127 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16128 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16129 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016130
Jeff Johnson295189b2012-06-20 16:38:30 -070016131 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
16132 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16133 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16134 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016135 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
16136 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053016137 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16138 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
16139 __func__, eLen);
16140 VOS_ASSERT(0);
16141 return -EINVAL;
16142 }
16143
Jeff Johnson295189b2012-06-20 16:38:30 -070016144 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
16145 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16146 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
16147 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
16148 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
16149 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016150 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053016151 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070016152 {
16153 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016154 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016155 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016156
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016157 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016158 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016159 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16160 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016161 VOS_ASSERT(0);
16162 return -ENOMEM;
16163 }
16164 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16165 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16166 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016167
Jeff Johnson295189b2012-06-20 16:38:30 -070016168 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16169 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16170 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016171#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016172 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
16173 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016174 /*Consider WFD IE, only for P2P Client */
16175 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
16176 {
16177 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016178 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016179 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016180
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016181 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016182 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016183 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16184 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016185 VOS_ASSERT(0);
16186 return -ENOMEM;
16187 }
16188 // WFD IE is saved to Additional IE ; it should be accumulated to handle
16189 // WPS IE + P2P IE + WFD IE
16190 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16191 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016192
Jeff Johnson295189b2012-06-20 16:38:30 -070016193 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16194 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16195 }
16196#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016197 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016198 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016199 HS20_OUI_TYPE_SIZE)) )
16200 {
16201 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016202 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016203 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016204
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016205 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016206 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016207 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16208 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016209 VOS_ASSERT(0);
16210 return -ENOMEM;
16211 }
16212 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16213 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016214
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016215 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16216 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16217 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016218 /* Appending OSEN Information Element in Assiciation Request */
16219 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
16220 OSEN_OUI_TYPE_SIZE)) )
16221 {
16222 v_U16_t curAddIELen = pWextState->assocAddIE.length;
16223 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
16224 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016225
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016226 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016227 {
16228 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16229 "Need bigger buffer space");
16230 VOS_ASSERT(0);
16231 return -ENOMEM;
16232 }
16233 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16234 pWextState->assocAddIE.length += eLen + 2;
16235
16236 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
16237 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16238 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16239 }
16240
Abhishek Singh4322e622015-06-10 15:42:54 +053016241 /* Update only for WPA IE */
16242 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
16243 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016244
16245 /* populating as ADDIE in beacon frames */
16246 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016247 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016248 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
16249 {
16250 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16251 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
16252 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16253 {
16254 hddLog(LOGE,
16255 "Coldn't pass "
16256 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
16257 }
16258 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
16259 else
16260 hddLog(LOGE,
16261 "Could not pass on "
16262 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
16263
16264 /* IBSS mode doesn't contain params->proberesp_ies still
16265 beaconIE's need to be populated in probe response frames */
16266 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
16267 {
16268 u16 rem_probe_resp_ie_len = eLen + 2;
16269 u8 probe_rsp_ie_len[3] = {0};
16270 u8 counter = 0;
16271
16272 /* Check Probe Resp Length if it is greater then 255 then
16273 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
16274 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
16275 not able Store More then 255 bytes into One Variable */
16276
16277 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
16278 {
16279 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
16280 {
16281 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
16282 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
16283 }
16284 else
16285 {
16286 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
16287 rem_probe_resp_ie_len = 0;
16288 }
16289 }
16290
16291 rem_probe_resp_ie_len = 0;
16292
16293 if (probe_rsp_ie_len[0] > 0)
16294 {
16295 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16296 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
16297 (tANI_U8*)(genie - 2),
16298 probe_rsp_ie_len[0], NULL,
16299 eANI_BOOLEAN_FALSE)
16300 == eHAL_STATUS_FAILURE)
16301 {
16302 hddLog(LOGE,
16303 "Could not pass"
16304 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
16305 }
16306 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
16307 }
16308
16309 if (probe_rsp_ie_len[1] > 0)
16310 {
16311 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16312 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
16313 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16314 probe_rsp_ie_len[1], NULL,
16315 eANI_BOOLEAN_FALSE)
16316 == eHAL_STATUS_FAILURE)
16317 {
16318 hddLog(LOGE,
16319 "Could not pass"
16320 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
16321 }
16322 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
16323 }
16324
16325 if (probe_rsp_ie_len[2] > 0)
16326 {
16327 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16328 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
16329 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16330 probe_rsp_ie_len[2], NULL,
16331 eANI_BOOLEAN_FALSE)
16332 == eHAL_STATUS_FAILURE)
16333 {
16334 hddLog(LOGE,
16335 "Could not pass"
16336 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
16337 }
16338 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
16339 }
16340
16341 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16342 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
16343 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16344 {
16345 hddLog(LOGE,
16346 "Could not pass"
16347 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
16348 }
16349 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016350 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070016351 break;
16352 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053016353 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16354 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
16355 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
16356 VOS_ASSERT(0);
16357 return -EINVAL;
16358 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016359 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
16360 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16361 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
16362 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
16363 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16364 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016365
Abhishek Singhb16f3562016-01-20 11:08:32 +053016366 /* Appending extended capabilities with Interworking or
16367 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016368 *
16369 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016370 * interworkingService or bsstransition bit is set to 1.
16371 * Driver is only interested in interworkingService and
16372 * bsstransition capability from supplicant.
16373 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016374 * required from supplicat, it needs to be handled while
16375 * sending Assoc Req in LIM.
16376 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016377 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016378 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016379 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016380 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016381 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016382
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016383 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016384 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016385 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16386 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016387 VOS_ASSERT(0);
16388 return -ENOMEM;
16389 }
16390 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16391 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016392
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016393 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16394 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16395 break;
16396 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016397#ifdef FEATURE_WLAN_WAPI
16398 case WLAN_EID_WAPI:
16399 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016400 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016401 pAdapter->wapi_info.nWapiMode);
16402 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016403 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016404 akmsuiteCount = WPA_GET_LE16(tmp);
16405 tmp = tmp + 1;
16406 akmlist = (int *)(tmp);
16407 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16408 {
16409 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16410 }
16411 else
16412 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016413 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016414 VOS_ASSERT(0);
16415 return -EINVAL;
16416 }
16417
16418 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16419 {
16420 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016421 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016422 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016423 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016424 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016425 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016426 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016427 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016428 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
16429 }
16430 break;
16431#endif
16432 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016433 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016434 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016435 /* when Unknown IE is received we should break and continue
16436 * to the next IE in the buffer instead we were returning
16437 * so changing this to break */
16438 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016439 }
16440 genie += eLen;
16441 remLen -= eLen;
16442 }
16443 EXIT();
16444 return 0;
16445}
16446
16447/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016448 * FUNCTION: hdd_isWPAIEPresent
16449 * Parse the received IE to find the WPA IE
16450 *
16451 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016452static bool hdd_isWPAIEPresent(
16453#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16454 const u8 *ie,
16455#else
16456 u8 *ie,
16457#endif
16458 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016459{
16460 v_U8_t eLen = 0;
16461 v_U16_t remLen = ie_len;
16462 v_U8_t elementId = 0;
16463
16464 while (remLen >= 2)
16465 {
16466 elementId = *ie++;
16467 eLen = *ie++;
16468 remLen -= 2;
16469 if (eLen > remLen)
16470 {
16471 hddLog(VOS_TRACE_LEVEL_ERROR,
16472 "%s: IE length is wrong %d", __func__, eLen);
16473 return FALSE;
16474 }
16475 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16476 {
16477 /* OUI - 0x00 0X50 0XF2
16478 WPA Information Element - 0x01
16479 WPA version - 0x01*/
16480 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16481 return TRUE;
16482 }
16483 ie += eLen;
16484 remLen -= eLen;
16485 }
16486 return FALSE;
16487}
16488
16489/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016490 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016491 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016492 * parameters during connect operation.
16493 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016494int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016495 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016496 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016497{
16498 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016499 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016500 ENTER();
16501
16502 /*set wpa version*/
16503 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
16504
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016505 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016506 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053016507 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016508 {
16509 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16510 }
16511 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
16512 {
16513 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16514 }
16515 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016516
16517 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016518 pWextState->wpaVersion);
16519
16520 /*set authentication type*/
16521 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
16522
16523 if (0 > status)
16524 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016525 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016526 "%s: failed to set authentication type ", __func__);
16527 return status;
16528 }
16529
16530 /*set key mgmt type*/
16531 if (req->crypto.n_akm_suites)
16532 {
16533 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
16534 if (0 > status)
16535 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016536 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070016537 __func__);
16538 return status;
16539 }
16540 }
16541
16542 /*set pairwise cipher type*/
16543 if (req->crypto.n_ciphers_pairwise)
16544 {
16545 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
16546 req->crypto.ciphers_pairwise[0], true);
16547 if (0 > status)
16548 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016549 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016550 "%s: failed to set unicast cipher type", __func__);
16551 return status;
16552 }
16553 }
16554 else
16555 {
16556 /*Reset previous cipher suite to none*/
16557 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
16558 if (0 > status)
16559 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016560 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016561 "%s: failed to set unicast cipher type", __func__);
16562 return status;
16563 }
16564 }
16565
16566 /*set group cipher type*/
16567 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
16568 false);
16569
16570 if (0 > status)
16571 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016572 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070016573 __func__);
16574 return status;
16575 }
16576
Chet Lanctot186b5732013-03-18 10:26:30 -070016577#ifdef WLAN_FEATURE_11W
16578 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
16579#endif
16580
Jeff Johnson295189b2012-06-20 16:38:30 -070016581 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
16582 if (req->ie_len)
16583 {
16584 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
16585 if ( 0 > status)
16586 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016587 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016588 __func__);
16589 return status;
16590 }
16591 }
16592
16593 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016594 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016595 {
16596 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
16597 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
16598 )
16599 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016600 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070016601 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
16602 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016603 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016604 __func__);
16605 return -EOPNOTSUPP;
16606 }
16607 else
16608 {
16609 u8 key_len = req->key_len;
16610 u8 key_idx = req->key_idx;
16611
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016612 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016613 && (CSR_MAX_NUM_KEY > key_idx)
16614 )
16615 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016616 hddLog(VOS_TRACE_LEVEL_INFO,
16617 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016618 __func__, key_idx, key_len);
16619 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016620 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070016621 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016622 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016623 (u8)key_len;
16624 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
16625 }
16626 }
16627 }
16628 }
16629
16630 return status;
16631}
16632
16633/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016634 * FUNCTION: wlan_hdd_try_disconnect
16635 * This function is used to disconnect from previous
16636 * connection
16637 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053016638int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016639{
16640 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016641 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016642 hdd_station_ctx_t *pHddStaCtx;
16643 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016644 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016645
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016646 ret = wlan_hdd_validate_context(pHddCtx);
16647 if (0 != ret)
16648 {
16649 return ret;
16650 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016651 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16652
16653 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
16654
16655 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
16656 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053016657 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016658 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
16659 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053016660 /* Indicate disconnect to SME so that in-progress connection or preauth
16661 * can be aborted
16662 */
16663 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
16664 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016665 spin_lock_bh(&pAdapter->lock_for_active_session);
16666 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16667 {
16668 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16669 }
16670 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053016671 hdd_connSetConnectionState(pHddStaCtx,
16672 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016673 /* Issue disconnect to CSR */
16674 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016675 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016676 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016677 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16678 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
16679 hddLog(LOG1,
16680 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
16681 } else if ( 0 != status ) {
16682 hddLog(LOGE,
16683 FL("csrRoamDisconnect failure, returned %d"),
16684 (int)status );
16685 result = -EINVAL;
16686 goto disconnected;
16687 }
16688 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016689 &pAdapter->disconnect_comp_var,
16690 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016691 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
16692 hddLog(LOGE,
16693 "%s: Failed to disconnect, timed out", __func__);
16694 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016695 }
16696 }
16697 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
16698 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016699 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016700 &pAdapter->disconnect_comp_var,
16701 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016702 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016703 {
16704 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016705 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016706 }
16707 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016708disconnected:
16709 hddLog(LOG1,
16710 FL("Set HDD connState to eConnectionState_NotConnected"));
16711 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16712 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016713}
16714
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016715/**
16716 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16717 * @adapter: Pointer to the HDD adapter
16718 * @req: Pointer to the structure cfg_connect_params receieved from user space
16719 *
16720 * This function will start reassociation if bssid hint, channel hint and
16721 * previous bssid parameters are present in the connect request
16722 *
16723 * Return: success if reassociation is happening
16724 * Error code if reassociation is not permitted or not happening
16725 */
16726#ifdef CFG80211_CONNECT_PREV_BSSID
16727static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16728 struct cfg80211_connect_params *req)
16729{
16730 int status = -EPERM;
16731 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
16732 hddLog(VOS_TRACE_LEVEL_INFO,
16733 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
16734 req->channel_hint->hw_value,
16735 MAC_ADDR_ARRAY(req->bssid_hint));
16736 status = hdd_reassoc(adapter, req->bssid_hint,
16737 req->channel_hint->hw_value,
16738 CONNECT_CMD_USERSPACE);
16739 }
16740 return status;
16741}
16742#else
16743static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16744 struct cfg80211_connect_params *req)
16745{
16746 return -EPERM;
16747}
16748#endif
16749
Abhishek Singhe3beee22017-07-31 15:35:40 +053016750/**
16751 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
16752 * connect in HT20 mode
16753 * @hdd_ctx: hdd context
16754 * @adapter: Pointer to the HDD adapter
16755 * @req: Pointer to the structure cfg_connect_params receieved from user space
16756 *
16757 * This function will check if supplicant has indicated to to connect in HT20
16758 * mode. this is currently applicable only for 2.4Ghz mode only.
16759 * if feature is enabled and supplicant indicate HT20 set
16760 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
16761 *
16762 * Return: void
16763 */
16764#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
16765static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16766 hdd_adapter_t *adapter,
16767 struct cfg80211_connect_params *req)
16768{
16769 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16770 tCsrRoamProfile *roam_profile;
16771
16772 roam_profile = &wext_state->roamProfile;
16773 roam_profile->force_24ghz_in_ht20 = false;
16774 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
16775 !(req->ht_capa.cap_info &
16776 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
16777 roam_profile->force_24ghz_in_ht20 = true;
16778
16779 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
16780 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
16781}
16782#else
16783static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16784 hdd_adapter_t *adapter,
16785 struct cfg80211_connect_params *req)
16786{
16787 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16788 tCsrRoamProfile *roam_profile;
16789
16790 roam_profile = &wext_state->roamProfile;
16791 roam_profile->force_24ghz_in_ht20 = false;
16792}
16793#endif
16794
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016795/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053016796 * FUNCTION: __wlan_hdd_cfg80211_connect
16797 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070016798 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016799static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016800 struct net_device *ndev,
16801 struct cfg80211_connect_params *req
16802 )
16803{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016804 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016805 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053016806#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
16807 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016808 const u8 *bssid_hint = req->bssid_hint;
16809#else
16810 const u8 *bssid_hint = NULL;
16811#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016812 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016813 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053016814 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016815
16816 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016817
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016818 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16819 TRACE_CODE_HDD_CFG80211_CONNECT,
16820 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016821 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016822 "%s: device_mode = %s (%d)", __func__,
16823 hdd_device_modetoString(pAdapter->device_mode),
16824 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016825
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016826 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016827 if (!pHddCtx)
16828 {
16829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16830 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053016831 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016832 }
16833
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016834 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016835 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016836 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016837 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016838 }
16839
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053016840 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
16841 return -EINVAL;
16842
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016843 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
16844 if (0 == status)
16845 return status;
16846
Agarwal Ashish51325b52014-06-16 16:50:49 +053016847
Jeff Johnson295189b2012-06-20 16:38:30 -070016848#ifdef WLAN_BTAMP_FEATURE
16849 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016850 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070016851 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016852 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016853 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080016854 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070016855 }
16856#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016857
16858 //If Device Mode is Station Concurrent Sessions Exit BMps
16859 //P2P Mode will be taken care in Open/close adapter
16860 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053016861 (vos_concurrent_open_sessions_running())) {
16862 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
16863 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016864 }
16865
16866 /*Try disconnecting if already in connected state*/
16867 status = wlan_hdd_try_disconnect(pAdapter);
16868 if ( 0 > status)
16869 {
16870 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16871 " connection"));
16872 return -EALREADY;
16873 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053016874 /* Check for max concurrent connections after doing disconnect if any*/
16875 if (vos_max_concurrent_connections_reached()) {
16876 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16877 return -ECONNREFUSED;
16878 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016879
Jeff Johnson295189b2012-06-20 16:38:30 -070016880 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016881 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070016882
16883 if ( 0 > status)
16884 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016885 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070016886 __func__);
16887 return status;
16888 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053016889
16890 if (pHddCtx->spoofMacAddr.isEnabled)
16891 {
16892 hddLog(VOS_TRACE_LEVEL_INFO,
16893 "%s: MAC Spoofing enabled ", __func__);
16894 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
16895 * to fill TxBds for probe request during SSID scan which may happen
16896 * as part of connect command
16897 */
16898 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
16899 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
16900 if (status != VOS_STATUS_SUCCESS)
16901 return -ECONNREFUSED;
16902 }
16903
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016904 if (req->channel)
16905 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070016906 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016907 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053016908
16909 /* Abort if any scan is going on */
16910 status = wlan_hdd_scan_abort(pAdapter);
16911 if (0 != status)
16912 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
16913
Abhishek Singhe3beee22017-07-31 15:35:40 +053016914 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
16915
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016916 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
16917 req->ssid_len, req->bssid,
16918 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016919
Sushant Kaushikd7083982015-03-18 14:33:24 +053016920 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016921 {
16922 //ReEnable BMPS if disabled
16923 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
16924 (NULL != pHddCtx))
16925 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053016926 if (pHddCtx->hdd_wlan_suspended)
16927 {
16928 hdd_set_pwrparams(pHddCtx);
16929 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016930 //ReEnable Bmps and Imps back
16931 hdd_enable_bmps_imps(pHddCtx);
16932 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053016933 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070016934 return status;
16935 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016936 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016937 EXIT();
16938 return status;
16939}
16940
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016941static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
16942 struct net_device *ndev,
16943 struct cfg80211_connect_params *req)
16944{
16945 int ret;
16946 vos_ssr_protect(__func__);
16947 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
16948 vos_ssr_unprotect(__func__);
16949
16950 return ret;
16951}
Jeff Johnson295189b2012-06-20 16:38:30 -070016952
16953/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016954 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070016955 * This function is used to issue a disconnect request to SME
16956 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016957static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016958 struct net_device *dev,
16959 u16 reason
16960 )
16961{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016962 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016963 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016964 tCsrRoamProfile *pRoamProfile;
16965 hdd_station_ctx_t *pHddStaCtx;
16966 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016967#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016968 tANI_U8 staIdx;
16969#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016970
Jeff Johnson295189b2012-06-20 16:38:30 -070016971 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016972
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016973 if (!pAdapter) {
16974 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16975 return -EINVAL;
16976 }
16977
16978 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16979 if (!pHddStaCtx) {
16980 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
16981 return -EINVAL;
16982 }
16983
16984 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16985 status = wlan_hdd_validate_context(pHddCtx);
16986 if (0 != status)
16987 {
16988 return status;
16989 }
16990
16991 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
16992
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016993 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16994 TRACE_CODE_HDD_CFG80211_DISCONNECT,
16995 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016996 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
16997 __func__, hdd_device_modetoString(pAdapter->device_mode),
16998 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016999
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017000 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
17001 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070017002
Jeff Johnson295189b2012-06-20 16:38:30 -070017003 if (NULL != pRoamProfile)
17004 {
17005 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017006 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
17007 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070017008 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017009 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070017010 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017011 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070017012 switch(reason)
17013 {
17014 case WLAN_REASON_MIC_FAILURE:
17015 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
17016 break;
17017
17018 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
17019 case WLAN_REASON_DISASSOC_AP_BUSY:
17020 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
17021 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
17022 break;
17023
17024 case WLAN_REASON_PREV_AUTH_NOT_VALID:
17025 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053017026 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070017027 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
17028 break;
17029
Jeff Johnson295189b2012-06-20 16:38:30 -070017030 default:
17031 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
17032 break;
17033 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017034 pScanInfo = &pHddCtx->scan_info;
17035 if (pScanInfo->mScanPending)
17036 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017037 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017038 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053017039 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017040 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017041 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053017042 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017043#ifdef FEATURE_WLAN_TDLS
17044 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017045 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017046 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017047 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
17048 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017049 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017050 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017051 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017052 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017053 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017054 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017055 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017056 status = sme_DeleteTdlsPeerSta(
17057 WLAN_HDD_GET_HAL_CTX(pAdapter),
17058 pAdapter->sessionId,
17059 mac);
17060 if (status != eHAL_STATUS_SUCCESS) {
17061 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
17062 return -EPERM;
17063 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017064 }
17065 }
17066#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053017067
17068 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
17069 reasonCode,
17070 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017071 status = wlan_hdd_disconnect(pAdapter, reasonCode);
17072 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070017073 {
17074 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017075 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017076 __func__, (int)status );
17077 return -EINVAL;
17078 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017079 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017080 else
17081 {
17082 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
17083 "called while in %d state", __func__,
17084 pHddStaCtx->conn_info.connState);
17085 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017086 }
17087 else
17088 {
17089 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
17090 }
17091
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017092 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017093 return status;
17094}
17095
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017096static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
17097 struct net_device *dev,
17098 u16 reason
17099 )
17100{
17101 int ret;
17102 vos_ssr_protect(__func__);
17103 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
17104 vos_ssr_unprotect(__func__);
17105
17106 return ret;
17107}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017108
Jeff Johnson295189b2012-06-20 16:38:30 -070017109/*
17110 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017111 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070017112 * settings in IBSS mode.
17113 */
17114static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017115 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070017116 struct cfg80211_ibss_params *params
17117 )
17118{
17119 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017120 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070017121 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
17122 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017123
Jeff Johnson295189b2012-06-20 16:38:30 -070017124 ENTER();
17125
17126 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070017127 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070017128
17129 if (params->ie_len && ( NULL != params->ie) )
17130 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017131 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17132 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017133 {
17134 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
17135 encryptionType = eCSR_ENCRYPT_TYPE_AES;
17136 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017137 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017138 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017139 tDot11fIEWPA dot11WPAIE;
17140 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017141 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017142
Wilson Yang00256342013-10-10 23:13:38 -070017143 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017144 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17145 params->ie_len, DOT11F_EID_WPA);
17146 if ( NULL != ie )
17147 {
17148 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
17149 // Unpack the WPA IE
17150 //Skip past the EID byte and length byte - and four byte WiFi OUI
17151 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
17152 &ie[2+4],
17153 ie[1] - 4,
17154 &dot11WPAIE);
17155 /*Extract the multicast cipher, the encType for unicast
17156 cipher for wpa-none is none*/
17157 encryptionType =
17158 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
17159 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017160 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017161
Jeff Johnson295189b2012-06-20 16:38:30 -070017162 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
17163
17164 if (0 > status)
17165 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017166 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070017167 __func__);
17168 return status;
17169 }
17170 }
17171
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017172 pWextState->roamProfile.AuthType.authType[0] =
17173 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070017174 eCSR_AUTH_TYPE_OPEN_SYSTEM;
Jeff Johnson295189b2012-06-20 16:38:30 -070017175 if (params->privacy)
17176 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017177 /* Security enabled IBSS, At this time there is no information available
17178 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070017179 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017180 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070017181 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017182 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070017183 *enable privacy bit in beacons */
17184
17185 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
17186 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017187 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17188 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070017189 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
17190 pWextState->roamProfile.EncryptionType.numEntries = 1;
17191 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070017192 return status;
17193}
17194
17195/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017196 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017197 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017198 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017199static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017200 struct net_device *dev,
17201 struct cfg80211_ibss_params *params
17202 )
17203{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017204 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017205 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17206 tCsrRoamProfile *pRoamProfile;
17207 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017208 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17209 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017210 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070017211
17212 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017213
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017214 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17215 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
17216 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017217 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017218 "%s: device_mode = %s (%d)", __func__,
17219 hdd_device_modetoString(pAdapter->device_mode),
17220 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017221
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017222 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017223 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017224 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017225 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017226 }
17227
17228 if (NULL == pWextState)
17229 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017230 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017231 __func__);
17232 return -EIO;
17233 }
17234
Agarwal Ashish51325b52014-06-16 16:50:49 +053017235 if (vos_max_concurrent_connections_reached()) {
17236 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17237 return -ECONNREFUSED;
17238 }
17239
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017240 /*Try disconnecting if already in connected state*/
17241 status = wlan_hdd_try_disconnect(pAdapter);
17242 if ( 0 > status)
17243 {
17244 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17245 " IBSS connection"));
17246 return -EALREADY;
17247 }
17248
Jeff Johnson295189b2012-06-20 16:38:30 -070017249 pRoamProfile = &pWextState->roamProfile;
17250
17251 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
17252 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017253 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017254 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017255 return -EINVAL;
17256 }
17257
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017258 /* BSSID is provided by upper layers hence no need to AUTO generate */
17259 if (NULL != params->bssid) {
17260 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17261 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
17262 hddLog (VOS_TRACE_LEVEL_ERROR,
17263 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17264 return -EIO;
17265 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017266 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017267 }
krunal sonie9002db2013-11-25 14:24:17 -080017268 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
17269 {
17270 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17271 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
17272 {
17273 hddLog (VOS_TRACE_LEVEL_ERROR,
17274 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17275 return -EIO;
17276 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017277
17278 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080017279 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017280 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080017281 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017282
Jeff Johnson295189b2012-06-20 16:38:30 -070017283 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070017284 if (NULL !=
17285#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17286 params->chandef.chan)
17287#else
17288 params->channel)
17289#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017290 {
17291 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017292 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17293 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
17294 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17295 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017296
17297 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017298 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070017299 ieee80211_frequency_to_channel(
17300#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17301 params->chandef.chan->center_freq);
17302#else
17303 params->channel->center_freq);
17304#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017305
17306 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17307 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070017308 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017309 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
17310 __func__);
17311 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070017312 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017313
17314 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017315 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017316 if (channelNum == validChan[indx])
17317 {
17318 break;
17319 }
17320 }
17321 if (indx >= numChans)
17322 {
17323 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017324 __func__, channelNum);
17325 return -EINVAL;
17326 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017327 /* Set the Operational Channel */
17328 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
17329 channelNum);
17330 pRoamProfile->ChannelInfo.numOfChannels = 1;
17331 pHddStaCtx->conn_info.operationChannel = channelNum;
17332 pRoamProfile->ChannelInfo.ChannelList =
17333 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070017334 }
17335
17336 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017337 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070017338 if (status < 0)
17339 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017340 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070017341 __func__);
17342 return status;
17343 }
17344
17345 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017346 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053017347 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017348 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017349
17350 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017351 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017352
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017353 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017354 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017355}
17356
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017357static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17358 struct net_device *dev,
17359 struct cfg80211_ibss_params *params
17360 )
17361{
17362 int ret = 0;
17363
17364 vos_ssr_protect(__func__);
17365 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17366 vos_ssr_unprotect(__func__);
17367
17368 return ret;
17369}
17370
Jeff Johnson295189b2012-06-20 16:38:30 -070017371/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017372 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017373 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017374 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017375static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017376 struct net_device *dev
17377 )
17378{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017379 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017380 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17381 tCsrRoamProfile *pRoamProfile;
17382 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017383 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017384 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017385#ifdef WLAN_FEATURE_RMC
17386 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17387#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017388
17389 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017390
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017391 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17392 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17393 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017394 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017395 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017396 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017397 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017398 }
17399
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017400 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17401 hdd_device_modetoString(pAdapter->device_mode),
17402 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017403 if (NULL == pWextState)
17404 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017405 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017406 __func__);
17407 return -EIO;
17408 }
17409
17410 pRoamProfile = &pWextState->roamProfile;
17411
17412 /* Issue disconnect only if interface type is set to IBSS */
17413 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17414 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017415 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017416 __func__);
17417 return -EINVAL;
17418 }
17419
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017420#ifdef WLAN_FEATURE_RMC
17421 /* Clearing add IE of beacon */
17422 if (ccmCfgSetStr(pHddCtx->hHal,
17423 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17424 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17425 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17426 {
17427 hddLog (VOS_TRACE_LEVEL_ERROR,
17428 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17429 return -EINVAL;
17430 }
17431 if (ccmCfgSetInt(pHddCtx->hHal,
17432 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17433 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17434 {
17435 hddLog (VOS_TRACE_LEVEL_ERROR,
17436 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17437 __func__);
17438 return -EINVAL;
17439 }
17440
17441 // Reset WNI_CFG_PROBE_RSP Flags
17442 wlan_hdd_reset_prob_rspies(pAdapter);
17443
17444 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17445 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17446 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17447 {
17448 hddLog (VOS_TRACE_LEVEL_ERROR,
17449 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17450 __func__);
17451 return -EINVAL;
17452 }
17453#endif
17454
Jeff Johnson295189b2012-06-20 16:38:30 -070017455 /* Issue Disconnect request */
17456 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017457 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17458 pAdapter->sessionId,
17459 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17460 if (!HAL_STATUS_SUCCESS(hal_status)) {
17461 hddLog(LOGE,
17462 FL("sme_RoamDisconnect failed hal_status(%d)"),
17463 hal_status);
17464 return -EAGAIN;
17465 }
17466 status = wait_for_completion_timeout(
17467 &pAdapter->disconnect_comp_var,
17468 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17469 if (!status) {
17470 hddLog(LOGE,
17471 FL("wait on disconnect_comp_var failed"));
17472 return -ETIMEDOUT;
17473 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017474
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017475 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017476 return 0;
17477}
17478
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017479static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17480 struct net_device *dev
17481 )
17482{
17483 int ret = 0;
17484
17485 vos_ssr_protect(__func__);
17486 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17487 vos_ssr_unprotect(__func__);
17488
17489 return ret;
17490}
17491
Jeff Johnson295189b2012-06-20 16:38:30 -070017492/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017493 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017494 * This function is used to set the phy parameters
17495 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17496 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017497static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017498 u32 changed)
17499{
17500 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17501 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017502 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017503
17504 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017505
17506 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017507 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17508 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017509
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017510 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017511 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017512 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017513 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017514 }
17515
Jeff Johnson295189b2012-06-20 16:38:30 -070017516 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17517 {
17518 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17519 WNI_CFG_RTS_THRESHOLD_STAMAX :
17520 wiphy->rts_threshold;
17521
17522 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017523 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017524 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017525 hddLog(VOS_TRACE_LEVEL_ERROR,
17526 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017527 __func__, rts_threshold);
17528 return -EINVAL;
17529 }
17530
17531 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17532 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017533 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017534 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017535 hddLog(VOS_TRACE_LEVEL_ERROR,
17536 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017537 __func__, rts_threshold);
17538 return -EIO;
17539 }
17540
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017541 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017542 rts_threshold);
17543 }
17544
17545 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17546 {
17547 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17548 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17549 wiphy->frag_threshold;
17550
17551 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017552 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017553 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017554 hddLog(VOS_TRACE_LEVEL_ERROR,
17555 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017556 frag_threshold);
17557 return -EINVAL;
17558 }
17559
17560 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
17561 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017562 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017563 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017564 hddLog(VOS_TRACE_LEVEL_ERROR,
17565 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017566 __func__, frag_threshold);
17567 return -EIO;
17568 }
17569
17570 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
17571 frag_threshold);
17572 }
17573
17574 if ((changed & WIPHY_PARAM_RETRY_SHORT)
17575 || (changed & WIPHY_PARAM_RETRY_LONG))
17576 {
17577 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
17578 wiphy->retry_short :
17579 wiphy->retry_long;
17580
17581 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17582 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17583 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017584 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017585 __func__, retry_value);
17586 return -EINVAL;
17587 }
17588
17589 if (changed & WIPHY_PARAM_RETRY_SHORT)
17590 {
17591 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17592 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017593 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017594 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017595 hddLog(VOS_TRACE_LEVEL_ERROR,
17596 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017597 __func__, retry_value);
17598 return -EIO;
17599 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017600 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017601 __func__, retry_value);
17602 }
17603 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17604 {
17605 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17606 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017607 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017608 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017609 hddLog(VOS_TRACE_LEVEL_ERROR,
17610 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017611 __func__, retry_value);
17612 return -EIO;
17613 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017614 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017615 __func__, retry_value);
17616 }
17617 }
17618
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017619 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017620 return 0;
17621}
17622
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017623static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17624 u32 changed)
17625{
17626 int ret;
17627
17628 vos_ssr_protect(__func__);
17629 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17630 vos_ssr_unprotect(__func__);
17631
17632 return ret;
17633}
17634
Jeff Johnson295189b2012-06-20 16:38:30 -070017635/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017636 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017637 * This function is used to set the txpower
17638 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017639static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017640#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17641 struct wireless_dev *wdev,
17642#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017643#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017644 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017645#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017646 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017647#endif
17648 int dbm)
17649{
17650 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017651 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017652 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17653 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017654 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017655
17656 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017657
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017658 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17659 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17660 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017661 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017662 if (0 != status)
17663 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017664 return status;
17665 }
17666
17667 hHal = pHddCtx->hHal;
17668
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017669 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17670 dbm, ccmCfgSetCallback,
17671 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017672 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017673 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017674 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17675 return -EIO;
17676 }
17677
17678 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17679 dbm);
17680
17681 switch(type)
17682 {
17683 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17684 /* Fall through */
17685 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17686 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17687 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017688 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17689 __func__);
17690 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017691 }
17692 break;
17693 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017694 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017695 __func__);
17696 return -EOPNOTSUPP;
17697 break;
17698 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017699 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17700 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017701 return -EIO;
17702 }
17703
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017704 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017705 return 0;
17706}
17707
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017708static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17709#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17710 struct wireless_dev *wdev,
17711#endif
17712#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17713 enum tx_power_setting type,
17714#else
17715 enum nl80211_tx_power_setting type,
17716#endif
17717 int dbm)
17718{
17719 int ret;
17720 vos_ssr_protect(__func__);
17721 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17722#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17723 wdev,
17724#endif
17725#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17726 type,
17727#else
17728 type,
17729#endif
17730 dbm);
17731 vos_ssr_unprotect(__func__);
17732
17733 return ret;
17734}
17735
Jeff Johnson295189b2012-06-20 16:38:30 -070017736/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017737 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017738 * This function is used to read the txpower
17739 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017740static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017741#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17742 struct wireless_dev *wdev,
17743#endif
17744 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070017745{
17746
17747 hdd_adapter_t *pAdapter;
17748 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017749 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017750
Jeff Johnsone7245742012-09-05 17:12:55 -070017751 ENTER();
17752
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017753 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017754 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017755 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017756 *dbm = 0;
17757 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017758 }
17759
Jeff Johnson295189b2012-06-20 16:38:30 -070017760 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
17761 if (NULL == pAdapter)
17762 {
17763 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
17764 return -ENOENT;
17765 }
17766
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017767 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17768 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
17769 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070017770 wlan_hdd_get_classAstats(pAdapter);
17771 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
17772
Jeff Johnsone7245742012-09-05 17:12:55 -070017773 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017774 return 0;
17775}
17776
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017777static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
17778#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17779 struct wireless_dev *wdev,
17780#endif
17781 int *dbm)
17782{
17783 int ret;
17784
17785 vos_ssr_protect(__func__);
17786 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
17787#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17788 wdev,
17789#endif
17790 dbm);
17791 vos_ssr_unprotect(__func__);
17792
17793 return ret;
17794}
17795
Dustin Brown8c1d4092017-07-28 18:08:01 +053017796/*
17797 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
17798 * @stats: summary stats to use as a source
17799 * @info: kernel station_info struct to use as a destination
17800 *
17801 * Return: None
17802 */
17803static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
17804 struct station_info *info)
17805{
17806 int i;
17807
17808 info->rx_packets = stats->rx_frm_cnt;
17809 info->tx_packets = 0;
17810 info->tx_retries = 0;
17811 info->tx_failed = 0;
17812
17813 for (i = 0; i < 4; ++i) {
17814 info->tx_packets += stats->tx_frm_cnt[i];
17815 info->tx_retries += stats->multiple_retry_cnt[i];
17816 info->tx_failed += stats->fail_cnt[i];
17817 }
17818
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017819#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
17820 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017821 info->filled |= STATION_INFO_TX_PACKETS |
17822 STATION_INFO_TX_RETRIES |
17823 STATION_INFO_TX_FAILED |
17824 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017825#else
17826 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
17827 BIT(NL80211_STA_INFO_TX_RETRIES) |
17828 BIT(NL80211_STA_INFO_TX_FAILED) |
17829 BIT(NL80211_STA_INFO_RX_PACKETS);
17830#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053017831}
17832
17833/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017834 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
17835 * @adapter: sap adapter pointer
17836 * @staid: station id of the client
17837 * @rssi: rssi value to fill
17838 *
17839 * Return: None
17840 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053017841void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017842wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
17843{
17844 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
17845
17846 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
17847}
17848
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017849#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
17850 !defined(WITH_BACKPORTS)
17851static inline void wlan_hdd_fill_station_info_signal(struct station_info
17852 *sinfo)
17853{
17854 sinfo->filled |= STATION_INFO_SIGNAL;
17855}
17856#else
17857static inline void wlan_hdd_fill_station_info_signal(struct station_info
17858 *sinfo)
17859{
17860 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
17861}
17862#endif
17863
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017864/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053017865 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
17866 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017867 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053017868 * @info: kernel station_info struct to populate
17869 *
17870 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
17871 * support "station dump" and "station get" for SAP vdevs, even though they
17872 * aren't technically stations.
17873 *
17874 * Return: errno
17875 */
17876static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017877wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
17878#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17879 const u8* mac,
17880#else
17881 u8* mac,
17882#endif
17883 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017884{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017885 v_MACADDR_t *peerMacAddr;
17886 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017887 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017888 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017889
17890 status = wlan_hdd_get_station_stats(adapter);
17891 if (!VOS_IS_STATUS_SUCCESS(status)) {
17892 hddLog(VOS_TRACE_LEVEL_ERROR,
17893 "Failed to get SAP stats; status:%d", status);
17894 return 0;
17895 }
17896
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017897 peerMacAddr = (v_MACADDR_t *)mac;
17898 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
17899 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
17900 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
17901
17902 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
17903 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017904 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017905 }
17906
Dustin Brown8c1d4092017-07-28 18:08:01 +053017907 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
17908
17909 return 0;
17910}
17911
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017912static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017913#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17914 const u8* mac,
17915#else
17916 u8* mac,
17917#endif
17918 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070017919{
17920 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
17921 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17922 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053017923 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017924
17925 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
17926 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070017927
17928 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
17929 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
17930 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
17931 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
17932 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
17933 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
17934 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017935 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017936 tANI_U16 myRate;
17937 tANI_U16 currentRate = 0;
17938 tANI_U8 maxSpeedMCS = 0;
17939 tANI_U8 maxMCSIdx = 0;
17940 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053017941 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070017942 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017943 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017944
Leo Chang6f8870f2013-03-26 18:11:36 -070017945#ifdef WLAN_FEATURE_11AC
17946 tANI_U32 vht_mcs_map;
17947 eDataRate11ACMaxMcs vhtMaxMcs;
17948#endif /* WLAN_FEATURE_11AC */
17949
Jeff Johnsone7245742012-09-05 17:12:55 -070017950 ENTER();
17951
Dustin Brown8c1d4092017-07-28 18:08:01 +053017952 status = wlan_hdd_validate_context(pHddCtx);
17953 if (0 != status)
17954 {
17955 return status;
17956 }
17957
17958 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017959 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053017960
Jeff Johnson295189b2012-06-20 16:38:30 -070017961 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17962 (0 == ssidlen))
17963 {
17964 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
17965 " Invalid ssidlen, %d", __func__, ssidlen);
17966 /*To keep GUI happy*/
17967 return 0;
17968 }
17969
Mukul Sharma811205f2014-07-09 21:07:30 +053017970 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17971 {
17972 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17973 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053017974 /* return a cached value */
17975 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053017976 return 0;
17977 }
17978
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053017979 wlan_hdd_get_station_stats(pAdapter);
17980 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017981
Kiet Lam3b17fc82013-09-27 05:24:08 +053017982 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017983 wlan_hdd_get_snr(pAdapter, &snr);
17984 pHddStaCtx->conn_info.signal = sinfo->signal;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053017985 pHddStaCtx->cache_conn_info.signal = sinfo->signal;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017986 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053017987 pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017988 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053017989
c_hpothu09f19542014-05-30 21:53:31 +053017990 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053017991 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
17992 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053017993 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053017994 {
17995 rate_flags = pAdapter->maxRateFlags;
17996 }
c_hpothu44ff4e02014-05-08 00:13:57 +053017997
Jeff Johnson295189b2012-06-20 16:38:30 -070017998 //convert to the UI units of 100kbps
17999 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
18000
18001#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070018002 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 -070018003 sinfo->signal,
18004 pCfg->reportMaxLinkSpeed,
18005 myRate,
18006 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018007 (int) pCfg->linkSpeedRssiMid,
18008 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070018009 (int) rate_flags,
18010 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070018011#endif //LINKSPEED_DEBUG_ENABLED
18012
18013 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
18014 {
18015 // we do not want to necessarily report the current speed
18016 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
18017 {
18018 // report the max possible speed
18019 rssidx = 0;
18020 }
18021 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
18022 {
18023 // report the max possible speed with RSSI scaling
18024 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
18025 {
18026 // report the max possible speed
18027 rssidx = 0;
18028 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018029 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070018030 {
18031 // report middle speed
18032 rssidx = 1;
18033 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018034 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
18035 {
18036 // report middle speed
18037 rssidx = 2;
18038 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018039 else
18040 {
18041 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018042 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070018043 }
18044 }
18045 else
18046 {
18047 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
18048 hddLog(VOS_TRACE_LEVEL_ERROR,
18049 "%s: Invalid value for reportMaxLinkSpeed: %u",
18050 __func__, pCfg->reportMaxLinkSpeed);
18051 rssidx = 0;
18052 }
18053
18054 maxRate = 0;
18055
18056 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018057 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
18058 OperationalRates, &ORLeng))
18059 {
18060 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18061 /*To keep GUI happy*/
18062 return 0;
18063 }
18064
Jeff Johnson295189b2012-06-20 16:38:30 -070018065 for (i = 0; i < ORLeng; i++)
18066 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018067 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018068 {
18069 /* Validate Rate Set */
18070 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
18071 {
18072 currentRate = supported_data_rate[j].supported_rate[rssidx];
18073 break;
18074 }
18075 }
18076 /* Update MAX rate */
18077 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18078 }
18079
18080 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018081 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
18082 ExtendedRates, &ERLeng))
18083 {
18084 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18085 /*To keep GUI happy*/
18086 return 0;
18087 }
18088
Jeff Johnson295189b2012-06-20 16:38:30 -070018089 for (i = 0; i < ERLeng; i++)
18090 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018091 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018092 {
18093 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
18094 {
18095 currentRate = supported_data_rate[j].supported_rate[rssidx];
18096 break;
18097 }
18098 }
18099 /* Update MAX rate */
18100 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18101 }
c_hpothu79aab322014-07-14 21:11:01 +053018102
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018103 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053018104 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018105 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053018106 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070018107 {
c_hpothu79aab322014-07-14 21:11:01 +053018108 if (rate_flags & eHAL_TX_RATE_VHT80)
18109 mode = 2;
18110 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
18111 mode = 1;
18112 else
18113 mode = 0;
18114
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018115 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
18116 MCSRates, &MCSLeng))
18117 {
18118 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18119 /*To keep GUI happy*/
18120 return 0;
18121 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018122 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070018123#ifdef WLAN_FEATURE_11AC
18124 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018125 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070018126 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018127 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018128 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070018129 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070018130 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018131 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018132 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018133 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070018134 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018135 maxMCSIdx = 7;
18136 }
18137 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
18138 {
18139 maxMCSIdx = 8;
18140 }
18141 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
18142 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018143 //VHT20 is supporting 0~8
18144 if (rate_flags & eHAL_TX_RATE_VHT20)
18145 maxMCSIdx = 8;
18146 else
18147 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070018148 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018149
c_hpothu79aab322014-07-14 21:11:01 +053018150 if (0 != rssidx)/*check for scaled */
18151 {
18152 //get middle rate MCS index if rssi=1/2
18153 for (i=0; i <= maxMCSIdx; i++)
18154 {
18155 if (sinfo->signal <= rssiMcsTbl[mode][i])
18156 {
18157 maxMCSIdx = i;
18158 break;
18159 }
18160 }
18161 }
18162
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018163 if (rate_flags & eHAL_TX_RATE_VHT80)
18164 {
18165 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
18166 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
18167 }
18168 else if (rate_flags & eHAL_TX_RATE_VHT40)
18169 {
18170 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
18171 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
18172 }
18173 else if (rate_flags & eHAL_TX_RATE_VHT20)
18174 {
18175 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
18176 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
18177 }
18178
Leo Chang6f8870f2013-03-26 18:11:36 -070018179 maxSpeedMCS = 1;
18180 if (currentRate > maxRate)
18181 {
18182 maxRate = currentRate;
18183 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018184
Leo Chang6f8870f2013-03-26 18:11:36 -070018185 }
18186 else
18187#endif /* WLAN_FEATURE_11AC */
18188 {
18189 if (rate_flags & eHAL_TX_RATE_HT40)
18190 {
18191 rateFlag |= 1;
18192 }
18193 if (rate_flags & eHAL_TX_RATE_SGI)
18194 {
18195 rateFlag |= 2;
18196 }
18197
Girish Gowli01abcee2014-07-31 20:18:55 +053018198 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053018199 if (rssidx == 1 || rssidx == 2)
18200 {
18201 //get middle rate MCS index if rssi=1/2
18202 for (i=0; i <= 7; i++)
18203 {
18204 if (sinfo->signal <= rssiMcsTbl[mode][i])
18205 {
18206 temp = i+1;
18207 break;
18208 }
18209 }
18210 }
c_hpothu79aab322014-07-14 21:11:01 +053018211
18212 for (i = 0; i < MCSLeng; i++)
18213 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018214 for (j = 0; j < temp; j++)
18215 {
18216 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
18217 {
18218 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018219 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018220 break;
18221 }
18222 }
18223 if ((j < temp) && (currentRate > maxRate))
18224 {
18225 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070018226 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018227 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018228 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018229 }
18230 }
18231
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018232 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
18233 {
18234 maxRate = myRate;
18235 maxSpeedMCS = 1;
18236 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18237 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018238 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053018239 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070018240 {
18241 maxRate = myRate;
18242 if (rate_flags & eHAL_TX_RATE_LEGACY)
18243 {
18244 maxSpeedMCS = 0;
18245 }
18246 else
18247 {
18248 maxSpeedMCS = 1;
18249 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18250 }
18251 }
18252
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018253 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070018254 {
18255 sinfo->txrate.legacy = maxRate;
18256#ifdef LINKSPEED_DEBUG_ENABLED
18257 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
18258#endif //LINKSPEED_DEBUG_ENABLED
18259 }
18260 else
18261 {
18262 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070018263#ifdef WLAN_FEATURE_11AC
18264 sinfo->txrate.nss = 1;
18265 if (rate_flags & eHAL_TX_RATE_VHT80)
18266 {
18267 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018268#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18269 defined(WITH_BACKPORTS)
18270 sinfo->txrate.bw = RATE_INFO_BW_80;
18271#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018272 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018273#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018274 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018275 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070018276 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018277 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018278#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18279 defined(WITH_BACKPORTS)
18280 sinfo->txrate.bw = RATE_INFO_BW_40;
18281#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018282 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018283#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018284 }
18285 else if (rate_flags & eHAL_TX_RATE_VHT20)
18286 {
18287 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18288 }
18289#endif /* WLAN_FEATURE_11AC */
18290 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
18291 {
18292 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18293 if (rate_flags & eHAL_TX_RATE_HT40)
18294 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018295#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18296 defined(WITH_BACKPORTS)
18297 sinfo->txrate.bw = RATE_INFO_BW_40;
18298#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018299 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018300#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018301 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018302 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018303 if (rate_flags & eHAL_TX_RATE_SGI)
18304 {
18305 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18306 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018307
Jeff Johnson295189b2012-06-20 16:38:30 -070018308#ifdef LINKSPEED_DEBUG_ENABLED
18309 pr_info("Reporting MCS rate %d flags %x\n",
18310 sinfo->txrate.mcs,
18311 sinfo->txrate.flags );
18312#endif //LINKSPEED_DEBUG_ENABLED
18313 }
18314 }
18315 else
18316 {
18317 // report current rate instead of max rate
18318
18319 if (rate_flags & eHAL_TX_RATE_LEGACY)
18320 {
18321 //provide to the UI in units of 100kbps
18322 sinfo->txrate.legacy = myRate;
18323#ifdef LINKSPEED_DEBUG_ENABLED
18324 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
18325#endif //LINKSPEED_DEBUG_ENABLED
18326 }
18327 else
18328 {
18329 //must be MCS
18330 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018331#ifdef WLAN_FEATURE_11AC
18332 sinfo->txrate.nss = 1;
18333 if (rate_flags & eHAL_TX_RATE_VHT80)
18334 {
18335 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18336 }
18337 else
18338#endif /* WLAN_FEATURE_11AC */
18339 {
18340 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18341 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018342 if (rate_flags & eHAL_TX_RATE_SGI)
18343 {
18344 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18345 }
18346 if (rate_flags & eHAL_TX_RATE_HT40)
18347 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018348#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18349 defined(WITH_BACKPORTS)
18350 sinfo->txrate.bw = RATE_INFO_BW_40;
18351#else
Jeff Johnson295189b2012-06-20 16:38:30 -070018352 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018353#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018354 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018355#ifdef WLAN_FEATURE_11AC
18356 else if (rate_flags & eHAL_TX_RATE_VHT80)
18357 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018358#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18359 defined(WITH_BACKPORTS)
18360 sinfo->txrate.bw = RATE_INFO_BW_80;
18361#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018362 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018363#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018364 }
18365#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018366#ifdef LINKSPEED_DEBUG_ENABLED
18367 pr_info("Reporting actual MCS rate %d flags %x\n",
18368 sinfo->txrate.mcs,
18369 sinfo->txrate.flags );
18370#endif //LINKSPEED_DEBUG_ENABLED
18371 }
18372 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018373
18374#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18375 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018376 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018377#else
18378 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18379#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018380
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018381 sinfo->tx_packets =
18382 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18383 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18384 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18385 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18386
18387 sinfo->tx_retries =
18388 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18389 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18390 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18391 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18392
18393 sinfo->tx_failed =
18394 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18395 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18396 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18397 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18398
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018399#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18400 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018401 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018402 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018403 STATION_INFO_TX_PACKETS |
18404 STATION_INFO_TX_RETRIES |
18405 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018406#else
18407 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18408 BIT(NL80211_STA_INFO_TX_PACKETS) |
18409 BIT(NL80211_STA_INFO_TX_RETRIES) |
18410 BIT(NL80211_STA_INFO_TX_FAILED);
18411#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018412
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018413 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018414
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018415 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18416 &sinfo->txrate, sizeof(sinfo->txrate));
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018417 vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate,
18418 &sinfo->txrate, sizeof(sinfo->txrate));
18419
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018420 if (rate_flags & eHAL_TX_RATE_LEGACY)
18421 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18422 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18423 sinfo->rx_packets);
18424 else
18425 hddLog(LOG1,
18426 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18427 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18428 sinfo->tx_packets, sinfo->rx_packets);
18429
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018430 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18431 TRACE_CODE_HDD_CFG80211_GET_STA,
18432 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018433 EXIT();
18434 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018435}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018436#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18437static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18438 const u8* mac, struct station_info *sinfo)
18439#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018440static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18441 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018442#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018443{
18444 int ret;
18445
18446 vos_ssr_protect(__func__);
18447 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18448 vos_ssr_unprotect(__func__);
18449
18450 return ret;
18451}
18452
18453static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018454 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018455{
18456 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018457 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018458 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018459 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018460
Jeff Johnsone7245742012-09-05 17:12:55 -070018461 ENTER();
18462
Jeff Johnson295189b2012-06-20 16:38:30 -070018463 if (NULL == pAdapter)
18464 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018465 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018466 return -ENODEV;
18467 }
18468
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018469 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18470 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18471 pAdapter->sessionId, timeout));
18472
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018473 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018474 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018475 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018476 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018477 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018478 }
18479
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018480 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
18481 (TRUE == pHddCtx->hdd_wlan_suspended) &&
18482 (pHddCtx->cfg_ini->fhostArpOffload) &&
18483 (eConnectionState_Associated ==
18484 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
18485 {
Amar Singhald53568e2013-09-26 11:03:45 -070018486
18487 hddLog(VOS_TRACE_LEVEL_INFO,
18488 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053018489 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018490 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18491 {
18492 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018493 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018494 __func__, vos_status);
18495 }
18496 }
18497
Jeff Johnson295189b2012-06-20 16:38:30 -070018498 /**The get power cmd from the supplicant gets updated by the nl only
18499 *on successful execution of the function call
18500 *we are oppositely mapped w.r.t mode in the driver
18501 **/
18502 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
18503
18504 if (VOS_STATUS_E_FAILURE == vos_status)
18505 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018506 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18507 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018508 return -EINVAL;
18509 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018510 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018511 return 0;
18512}
18513
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018514static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
18515 struct net_device *dev, bool mode, int timeout)
18516{
18517 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018518
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018519 vos_ssr_protect(__func__);
18520 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
18521 vos_ssr_unprotect(__func__);
18522
18523 return ret;
18524}
Sushant Kaushik084f6592015-09-10 13:11:56 +053018525
Jeff Johnson295189b2012-06-20 16:38:30 -070018526#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018527static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
18528 struct net_device *netdev,
18529 u8 key_index)
18530{
18531 ENTER();
18532 return 0;
18533}
18534
Jeff Johnson295189b2012-06-20 16:38:30 -070018535static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018536 struct net_device *netdev,
18537 u8 key_index)
18538{
18539 int ret;
18540 vos_ssr_protect(__func__);
18541 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
18542 vos_ssr_unprotect(__func__);
18543 return ret;
18544}
18545#endif //LINUX_VERSION_CODE
18546
18547#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18548static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18549 struct net_device *dev,
18550 struct ieee80211_txq_params *params)
18551{
18552 ENTER();
18553 return 0;
18554}
18555#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18556static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18557 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018558{
Jeff Johnsone7245742012-09-05 17:12:55 -070018559 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070018560 return 0;
18561}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018562#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070018563
18564#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18565static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018566 struct net_device *dev,
18567 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018568{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018569 int ret;
18570
18571 vos_ssr_protect(__func__);
18572 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
18573 vos_ssr_unprotect(__func__);
18574 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018575}
18576#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18577static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
18578 struct ieee80211_txq_params *params)
18579{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018580 int ret;
18581
18582 vos_ssr_protect(__func__);
18583 ret = __wlan_hdd_set_txq_params(wiphy, params);
18584 vos_ssr_unprotect(__func__);
18585 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018586}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018587#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018588
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018589static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018590 struct net_device *dev,
18591 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070018592{
18593 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018594 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018595 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018596 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018597 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018598 v_CONTEXT_t pVosContext = NULL;
18599 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018600
Jeff Johnsone7245742012-09-05 17:12:55 -070018601 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018602
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018603 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070018604 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018605 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018606 return -EINVAL;
18607 }
18608
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018609 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18610 TRACE_CODE_HDD_CFG80211_DEL_STA,
18611 pAdapter->sessionId, pAdapter->device_mode));
18612
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018613 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18614 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018615 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018616 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018617 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018618 }
18619
Jeff Johnson295189b2012-06-20 16:38:30 -070018620 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018621 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018622 )
18623 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018624 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
18625 pSapCtx = VOS_GET_SAP_CB(pVosContext);
18626 if(pSapCtx == NULL){
18627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18628 FL("psapCtx is NULL"));
18629 return -ENOENT;
18630 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053018631 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
18632 {
18633 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
18634 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
18635 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
18636 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018637 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070018638 {
18639 v_U16_t i;
18640 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
18641 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018642 if ((pSapCtx->aStaInfo[i].isUsed) &&
18643 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070018644 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018645 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018646 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018647 ETHER_ADDR_LEN);
18648
Jeff Johnson295189b2012-06-20 16:38:30 -070018649 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018650 "%s: Delete STA with MAC::"
18651 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018652 __func__,
18653 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18654 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018655 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018656 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018657 }
18658 }
18659 }
18660 else
18661 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018662
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018663 vos_status = hdd_softap_GetStaId(pAdapter,
18664 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018665 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18666 {
18667 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018668 "%s: Skip this DEL STA as this is not used::"
18669 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018670 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018671 return -ENOENT;
18672 }
18673
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018674 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018675 {
18676 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018677 "%s: Skip this DEL STA as deauth is in progress::"
18678 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018679 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018680 return -ENOENT;
18681 }
18682
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018683 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018684
Jeff Johnson295189b2012-06-20 16:38:30 -070018685 hddLog(VOS_TRACE_LEVEL_INFO,
18686 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018687 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018688 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018689 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018690
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018691 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018692 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18693 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018694 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018695 hddLog(VOS_TRACE_LEVEL_INFO,
18696 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018697 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018698 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018699 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018700 return -ENOENT;
18701 }
18702
Jeff Johnson295189b2012-06-20 16:38:30 -070018703 }
18704 }
18705
18706 EXIT();
18707
18708 return 0;
18709}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018710
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018711#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018712int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018713 struct net_device *dev,
18714 struct station_del_parameters *param)
18715#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018716#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018717int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018718 struct net_device *dev, const u8 *mac)
18719#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018720int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018721 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018722#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018723#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018724{
18725 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018726 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018727
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018728 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018729
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018730#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018731 if (NULL == param) {
18732 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018733 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018734 return -EINVAL;
18735 }
18736
18737 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
18738 param->subtype, &delStaParams);
18739
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018740#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053018741 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018742 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018743#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018744 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
18745
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018746 vos_ssr_unprotect(__func__);
18747
18748 return ret;
18749}
18750
18751static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018752 struct net_device *dev,
18753#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18754 const u8 *mac,
18755#else
18756 u8 *mac,
18757#endif
18758 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018759{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018760 hdd_adapter_t *pAdapter;
18761 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018762 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018763#ifdef FEATURE_WLAN_TDLS
18764 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018765
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018766 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018767
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018768 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18769 if (NULL == pAdapter)
18770 {
18771 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18772 "%s: Adapter is NULL",__func__);
18773 return -EINVAL;
18774 }
18775 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18776 status = wlan_hdd_validate_context(pHddCtx);
18777 if (0 != status)
18778 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018779 return status;
18780 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018781
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018782 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18783 TRACE_CODE_HDD_CFG80211_ADD_STA,
18784 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018785 mask = params->sta_flags_mask;
18786
18787 set = params->sta_flags_set;
18788
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018789 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018790 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
18791 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018792
18793 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
18794 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080018795 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018796 }
18797 }
18798#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018799 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018800 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018801}
18802
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018803#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18804static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18805 struct net_device *dev, const u8 *mac,
18806 struct station_parameters *params)
18807#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018808static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18809 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018810#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018811{
18812 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018813
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018814 vos_ssr_protect(__func__);
18815 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
18816 vos_ssr_unprotect(__func__);
18817
18818 return ret;
18819}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018820#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070018821
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018822static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070018823 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018824{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018825 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18826 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018827 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018828 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018829 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018830 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070018831
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018832 ENTER();
18833
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018834 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018835 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018836 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018837 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018838 return -EINVAL;
18839 }
18840
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018841 if (!pmksa) {
18842 hddLog(LOGE, FL("pmksa is NULL"));
18843 return -EINVAL;
18844 }
18845
18846 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070018847 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018848 pmksa->bssid, pmksa->pmkid);
18849 return -EINVAL;
18850 }
18851
18852 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
18853 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18854
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018855 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18856 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018857 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018858 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018859 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018860 }
18861
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018862 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018863 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18864
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018865 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
18866 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018867
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018868 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018869 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018870 &pmk_id, 1, FALSE);
18871
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018872 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18873 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
18874 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018875
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018876 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018877 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018878}
18879
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018880static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
18881 struct cfg80211_pmksa *pmksa)
18882{
18883 int ret;
18884
18885 vos_ssr_protect(__func__);
18886 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
18887 vos_ssr_unprotect(__func__);
18888
18889 return ret;
18890}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018891
Wilson Yang6507c4e2013-10-01 20:11:19 -070018892
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018893static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070018894 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018895{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018896 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18897 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018898 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018899 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018900
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018901 ENTER();
18902
Wilson Yang6507c4e2013-10-01 20:11:19 -070018903 /* Validate pAdapter */
18904 if (NULL == pAdapter)
18905 {
18906 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
18907 return -EINVAL;
18908 }
18909
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018910 if (!pmksa) {
18911 hddLog(LOGE, FL("pmksa is NULL"));
18912 return -EINVAL;
18913 }
18914
18915 if (!pmksa->bssid) {
18916 hddLog(LOGE, FL("pmksa->bssid is NULL"));
18917 return -EINVAL;
18918 }
18919
Kiet Lam98c46a12014-10-31 15:34:57 -070018920 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
18921 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18922
Wilson Yang6507c4e2013-10-01 20:11:19 -070018923 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18924 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018925 if (0 != status)
18926 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018927 return status;
18928 }
18929
18930 /*Retrieve halHandle*/
18931 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18932
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018933 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18934 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
18935 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018936 /* Delete the PMKID CSR cache */
18937 if (eHAL_STATUS_SUCCESS !=
18938 sme_RoamDelPMKIDfromCache(halHandle,
18939 pAdapter->sessionId, pmksa->bssid, FALSE)) {
18940 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
18941 MAC_ADDR_ARRAY(pmksa->bssid));
18942 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018943 }
18944
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018945 EXIT();
18946 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018947}
18948
Wilson Yang6507c4e2013-10-01 20:11:19 -070018949
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018950static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
18951 struct cfg80211_pmksa *pmksa)
18952{
18953 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018954
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018955 vos_ssr_protect(__func__);
18956 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
18957 vos_ssr_unprotect(__func__);
18958
18959 return ret;
18960
18961}
18962
18963static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018964{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018965 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18966 tHalHandle halHandle;
18967 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018968 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018969
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018970 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070018971
18972 /* Validate pAdapter */
18973 if (NULL == pAdapter)
18974 {
18975 hddLog(VOS_TRACE_LEVEL_ERROR,
18976 "%s: Invalid Adapter" ,__func__);
18977 return -EINVAL;
18978 }
18979
18980 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18981 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018982 if (0 != status)
18983 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018984 return status;
18985 }
18986
18987 /*Retrieve halHandle*/
18988 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18989
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018990 /* Flush the PMKID cache in CSR */
18991 if (eHAL_STATUS_SUCCESS !=
18992 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
18993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
18994 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018995 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018996 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080018997 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018998}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018999
19000static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
19001{
19002 int ret;
19003
19004 vos_ssr_protect(__func__);
19005 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
19006 vos_ssr_unprotect(__func__);
19007
19008 return ret;
19009}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019010#endif
19011
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019012#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019013static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19014 struct net_device *dev,
19015 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019016{
19017 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19018 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019019 hdd_context_t *pHddCtx;
19020 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019021
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019022 ENTER();
19023
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019024 if (NULL == pAdapter)
19025 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019026 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019027 return -ENODEV;
19028 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019029 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19030 ret = wlan_hdd_validate_context(pHddCtx);
19031 if (0 != ret)
19032 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019033 return ret;
19034 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019035 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019036 if (NULL == pHddStaCtx)
19037 {
19038 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
19039 return -EINVAL;
19040 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019041
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019042 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19043 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
19044 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019045 // Added for debug on reception of Re-assoc Req.
19046 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
19047 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019048 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019049 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080019050 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019051 }
19052
19053#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080019054 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019055 ftie->ie_len);
19056#endif
19057
19058 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053019059 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
19060 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019061 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019062
19063 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019064 return 0;
19065}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019066
19067static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19068 struct net_device *dev,
19069 struct cfg80211_update_ft_ies_params *ftie)
19070{
19071 int ret;
19072
19073 vos_ssr_protect(__func__);
19074 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
19075 vos_ssr_unprotect(__func__);
19076
19077 return ret;
19078}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019079#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019080
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019081#ifdef FEATURE_WLAN_SCAN_PNO
19082
19083void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
19084 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
19085{
19086 int ret;
19087 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
19088 hdd_context_t *pHddCtx;
19089
Nirav Shah80830bf2013-12-31 16:35:12 +053019090 ENTER();
19091
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019092 if (NULL == pAdapter)
19093 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019095 "%s: HDD adapter is Null", __func__);
19096 return ;
19097 }
19098
19099 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19100 if (NULL == pHddCtx)
19101 {
19102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19103 "%s: HDD context is Null!!!", __func__);
19104 return ;
19105 }
19106
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019107 spin_lock(&pHddCtx->schedScan_lock);
19108 if (TRUE == pHddCtx->isWiphySuspended)
19109 {
19110 pHddCtx->isSchedScanUpdatePending = TRUE;
19111 spin_unlock(&pHddCtx->schedScan_lock);
19112 hddLog(VOS_TRACE_LEVEL_INFO,
19113 "%s: Update cfg80211 scan database after it resume", __func__);
19114 return ;
19115 }
19116 spin_unlock(&pHddCtx->schedScan_lock);
19117
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019118 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
19119
19120 if (0 > ret)
19121 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053019122 else
19123 {
19124 /* Acquire wakelock to handle the case where APP's tries to suspend
19125 * immediatly after the driver gets connect request(i.e after pno)
19126 * from supplicant, this result in app's is suspending and not able
19127 * to process the connect request to AP */
19128 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
19129 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019130 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19132 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019133}
19134
19135/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019136 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019137 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019138 */
19139static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
19140{
19141 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
19142 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019143 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019144 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19145 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053019146
19147 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
19148 {
19149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19150 "%s: PNO is allowed only in STA interface", __func__);
19151 return eHAL_STATUS_FAILURE;
19152 }
19153
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019154 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
19155
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019156 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053019157 * active sessions. PNO is allowed only in case when sap session
19158 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019159 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019160 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
19161 {
19162 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019163 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019164
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019165 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
19166 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
19167 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
19168 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053019169 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
19170 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053019171 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019172 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019173 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019174 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019175 }
19176 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19177 pAdapterNode = pNext;
19178 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019179 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019180}
19181
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019182void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
19183{
19184 hdd_adapter_t *pAdapter = callbackContext;
19185 hdd_context_t *pHddCtx;
19186
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019187 ENTER();
19188
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019189 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
19190 {
19191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19192 FL("Invalid adapter or adapter has invalid magic"));
19193 return;
19194 }
19195
19196 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19197 if (0 != wlan_hdd_validate_context(pHddCtx))
19198 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019199 return;
19200 }
19201
c_hpothub53c45d2014-08-18 16:53:14 +053019202 if (VOS_STATUS_SUCCESS != status)
19203 {
19204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019205 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053019206 pHddCtx->isPnoEnable = FALSE;
19207 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019208
19209 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
19210 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019211 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019212}
19213
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019214#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
19215 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
19216/**
19217 * hdd_config_sched_scan_plan() - configures the sched scan plans
19218 * from the framework.
19219 * @pno_req: pointer to PNO scan request
19220 * @request: pointer to scan request from framework
19221 *
19222 * Return: None
19223 */
19224static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
19225 struct cfg80211_sched_scan_request *request,
19226 hdd_context_t *hdd_ctx)
19227{
19228 v_U32_t i = 0;
19229
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019230 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019231 for (i = 0; i < request->n_scan_plans; i++)
19232 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019233 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
19234 request->scan_plans[i].iterations;
19235 pno_req->scanTimers.aTimerValues[i].uTimerValue =
19236 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019237 }
19238}
19239#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019240static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019241 struct cfg80211_sched_scan_request *request,
19242 hdd_context_t *hdd_ctx)
19243{
19244 v_U32_t i, temp_int;
19245 /* Driver gets only one time interval which is hardcoded in
19246 * supplicant for 10000ms. Taking power consumption into account 6
19247 * timers will be used, Timervalue is increased exponentially
19248 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
19249 * timer is configurable through INI param gPNOScanTimerRepeatValue.
19250 * If it is set to 0 only one timer will be used and PNO scan cycle
19251 * will be repeated after each interval specified by supplicant
19252 * till PNO is disabled.
19253 */
19254 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019255 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019256 HDD_PNO_SCAN_TIMERS_SET_ONE;
19257 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019258 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019259 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
19260
19261 temp_int = (request->interval)/1000;
19262 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19263 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
19264 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019265 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019266 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019267 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019268 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019269 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019270 temp_int *= 2;
19271 }
19272 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019273 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019274}
19275#endif
19276
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019277/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019278 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
19279 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019280 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019281static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019282 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19283{
19284 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019285 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019286 hdd_context_t *pHddCtx;
19287 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019288 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053019289 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
19290 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019291 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
19292 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019293 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019294 hdd_config_t *pConfig = NULL;
19295 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019296
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019297 ENTER();
19298
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019299 if (NULL == pAdapter)
19300 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019302 "%s: HDD adapter is Null", __func__);
19303 return -ENODEV;
19304 }
19305
19306 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019307 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019308
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019309 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019310 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019311 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019312 }
19313
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019314 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019315 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19316 if (NULL == hHal)
19317 {
19318 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19319 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019320 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019321 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019322 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19323 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
19324 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019325 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053019326 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019327 {
19328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19329 "%s: aborting the existing scan is unsuccessfull", __func__);
19330 return -EBUSY;
19331 }
19332
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019333 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019334 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019336 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019337 return -EBUSY;
19338 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019339
c_hpothu37f21312014-04-09 21:49:54 +053019340 if (TRUE == pHddCtx->isPnoEnable)
19341 {
19342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19343 FL("already PNO is enabled"));
19344 return -EBUSY;
19345 }
c_hpothu225aa7c2014-10-22 17:45:13 +053019346
19347 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
19348 {
19349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19350 "%s: abort ROC failed ", __func__);
19351 return -EBUSY;
19352 }
19353
c_hpothu37f21312014-04-09 21:49:54 +053019354 pHddCtx->isPnoEnable = TRUE;
19355
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019356 pnoRequest.enable = 1; /*Enable PNO */
19357 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019358
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019359 if (( !pnoRequest.ucNetworksCount ) ||
19360 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019361 {
19362 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019363 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019364 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019365 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019366 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019367 goto error;
19368 }
19369
19370 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
19371 {
19372 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019373 "%s: Incorrect number of channels %d",
19374 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019375 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019376 goto error;
19377 }
19378
19379 /* Framework provides one set of channels(all)
19380 * common for all saved profile */
19381 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
19382 channels_allowed, &num_channels_allowed))
19383 {
19384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19385 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019386 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019387 goto error;
19388 }
19389 /* Checking each channel against allowed channel list */
19390 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053019391 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019392 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019393 char chList [(request->n_channels*5)+1];
19394 int len;
19395 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019396 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019397 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019398 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019399 if (request->channels[i]->hw_value == channels_allowed[indx])
19400 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019401 if ((!pConfig->enableDFSPnoChnlScan) &&
19402 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
19403 {
19404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19405 "%s : Dropping DFS channel : %d",
19406 __func__,channels_allowed[indx]);
19407 num_ignore_dfs_ch++;
19408 break;
19409 }
19410
Nirav Shah80830bf2013-12-31 16:35:12 +053019411 valid_ch[num_ch++] = request->channels[i]->hw_value;
19412 len += snprintf(chList+len, 5, "%d ",
19413 request->channels[i]->hw_value);
19414 break ;
19415 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019416 }
19417 }
Nirav Shah80830bf2013-12-31 16:35:12 +053019418 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019419
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019420 /*If all channels are DFS and dropped, then ignore the PNO request*/
19421 if (num_ignore_dfs_ch == request->n_channels)
19422 {
19423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19424 "%s : All requested channels are DFS channels", __func__);
19425 ret = -EINVAL;
19426 goto error;
19427 }
19428 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019429
19430 pnoRequest.aNetworks =
19431 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19432 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019433 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019434 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19435 FL("failed to allocate memory aNetworks %u"),
19436 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19437 goto error;
19438 }
19439 vos_mem_zero(pnoRequest.aNetworks,
19440 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19441
19442 /* Filling per profile params */
19443 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
19444 {
19445 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019446 request->match_sets[i].ssid.ssid_len;
19447
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019448 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
19449 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019450 {
19451 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019452 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019453 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019454 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019455 goto error;
19456 }
19457
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019458 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019459 request->match_sets[i].ssid.ssid,
19460 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19462 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019463 i, pnoRequest.aNetworks[i].ssId.ssId);
19464 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
19465 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
19466 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019467
19468 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019469 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
19470 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019471
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019472 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019473 }
19474
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019475 for (i = 0; i < request->n_ssids; i++)
19476 {
19477 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019478 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019479 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019480 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019481 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019482 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019483 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019484 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019485 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019486 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019487 break;
19488 }
19489 j++;
19490 }
19491 }
19492 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19493 "Number of hidden networks being Configured = %d",
19494 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019495 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080019496 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019497
19498 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19499 if (pnoRequest.p24GProbeTemplate == NULL)
19500 {
19501 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19502 FL("failed to allocate memory p24GProbeTemplate %u"),
19503 SIR_PNO_MAX_PB_REQ_SIZE);
19504 goto error;
19505 }
19506
19507 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19508 if (pnoRequest.p5GProbeTemplate == NULL)
19509 {
19510 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19511 FL("failed to allocate memory p5GProbeTemplate %u"),
19512 SIR_PNO_MAX_PB_REQ_SIZE);
19513 goto error;
19514 }
19515
19516 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19517 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19518
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053019519 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
19520 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019521 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019522 pnoRequest.us24GProbeTemplateLen = request->ie_len;
19523 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
19524 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019525
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019526 pnoRequest.us5GProbeTemplateLen = request->ie_len;
19527 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
19528 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019529 }
19530
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019531 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053019532
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019533 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019534
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019535 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019536 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19537 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019538 pAdapter->pno_req_status = 0;
19539
Nirav Shah80830bf2013-12-31 16:35:12 +053019540 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19541 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019542 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
19543 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053019544
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019545 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019546 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019547 hdd_cfg80211_sched_scan_done_callback, pAdapter);
19548 if (eHAL_STATUS_SUCCESS != status)
19549 {
19550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019551 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019552 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019553 goto error;
19554 }
19555
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019556 ret = wait_for_completion_timeout(
19557 &pAdapter->pno_comp_var,
19558 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19559 if (0 >= ret)
19560 {
19561 // Did not receive the response for PNO enable in time.
19562 // Assuming the PNO enable was success.
19563 // Returning error from here, because we timeout, results
19564 // in side effect of Wifi (Wifi Setting) not to work.
19565 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19566 FL("Timed out waiting for PNO to be Enabled"));
19567 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019568 }
19569
19570 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053019571 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019572
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019573error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019574 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19575 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053019576 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019577 if (pnoRequest.aNetworks)
19578 vos_mem_free(pnoRequest.aNetworks);
19579 if (pnoRequest.p24GProbeTemplate)
19580 vos_mem_free(pnoRequest.p24GProbeTemplate);
19581 if (pnoRequest.p5GProbeTemplate)
19582 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019583
19584 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019585 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019586}
19587
19588/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019589 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
19590 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019591 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019592static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
19593 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19594{
19595 int ret;
19596
19597 vos_ssr_protect(__func__);
19598 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
19599 vos_ssr_unprotect(__func__);
19600
19601 return ret;
19602}
19603
19604/*
19605 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
19606 * Function to disable PNO
19607 */
19608static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019609 struct net_device *dev)
19610{
19611 eHalStatus status = eHAL_STATUS_FAILURE;
19612 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19613 hdd_context_t *pHddCtx;
19614 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019615 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019616 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019617
19618 ENTER();
19619
19620 if (NULL == pAdapter)
19621 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019623 "%s: HDD adapter is Null", __func__);
19624 return -ENODEV;
19625 }
19626
19627 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019628
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019629 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019630 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019632 "%s: HDD context is Null", __func__);
19633 return -ENODEV;
19634 }
19635
19636 /* The return 0 is intentional when isLogpInProgress and
19637 * isLoadUnloadInProgress. We did observe a crash due to a return of
19638 * failure in sched_scan_stop , especially for a case where the unload
19639 * of the happens at the same time. The function __cfg80211_stop_sched_scan
19640 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
19641 * success. If it returns a failure , then its next invocation due to the
19642 * clean up of the second interface will have the dev pointer corresponding
19643 * to the first one leading to a crash.
19644 */
19645 if (pHddCtx->isLogpInProgress)
19646 {
19647 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19648 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019649 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019650 return ret;
19651 }
19652
Mihir Shete18156292014-03-11 15:38:30 +053019653 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019654 {
19655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19656 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19657 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019658 }
19659
19660 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19661 if (NULL == hHal)
19662 {
19663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19664 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019665 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019666 }
19667
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019668 pnoRequest.enable = 0; /* Disable PNO */
19669 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019670
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019671 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19672 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19673 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019674
19675 INIT_COMPLETION(pAdapter->pno_comp_var);
19676 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19677 pnoRequest.callbackContext = pAdapter;
19678 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019679 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019680 pAdapter->sessionId,
19681 NULL, pAdapter);
19682 if (eHAL_STATUS_SUCCESS != status)
19683 {
19684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19685 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019686 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019687 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019688 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019689 ret = wait_for_completion_timeout(
19690 &pAdapter->pno_comp_var,
19691 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19692 if (0 >= ret)
19693 {
19694 // Did not receive the response for PNO disable in time.
19695 // Assuming the PNO disable was success.
19696 // Returning error from here, because we timeout, results
19697 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019699 FL("Timed out waiting for PNO to be disabled"));
19700 ret = 0;
19701 }
19702
19703 ret = pAdapter->pno_req_status;
19704 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019705
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019706error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019708 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019709
19710 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019711 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019712}
19713
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019714/*
19715 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19716 * NL interface to disable PNO
19717 */
19718static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19719 struct net_device *dev)
19720{
19721 int ret;
19722
19723 vos_ssr_protect(__func__);
19724 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19725 vos_ssr_unprotect(__func__);
19726
19727 return ret;
19728}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019729#endif /*FEATURE_WLAN_SCAN_PNO*/
19730
19731
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019732#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019733#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019734static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19735 struct net_device *dev,
19736 u8 *peer, u8 action_code,
19737 u8 dialog_token,
19738 u16 status_code, u32 peer_capability,
19739 const u8 *buf, size_t len)
19740#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019741#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
19742 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019743static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19744 struct net_device *dev,
19745 const u8 *peer, u8 action_code,
19746 u8 dialog_token, u16 status_code,
19747 u32 peer_capability, bool initiator,
19748 const u8 *buf, size_t len)
19749#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19750static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19751 struct net_device *dev,
19752 const u8 *peer, u8 action_code,
19753 u8 dialog_token, u16 status_code,
19754 u32 peer_capability, const u8 *buf,
19755 size_t len)
19756#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19757static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19758 struct net_device *dev,
19759 u8 *peer, u8 action_code,
19760 u8 dialog_token,
19761 u16 status_code, u32 peer_capability,
19762 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019763#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019764static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19765 struct net_device *dev,
19766 u8 *peer, u8 action_code,
19767 u8 dialog_token,
19768 u16 status_code, const u8 *buf,
19769 size_t len)
19770#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019771#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019772{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019773 hdd_adapter_t *pAdapter;
19774 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019775 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070019776 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080019777 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070019778 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019779 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019780 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019781#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019782 u32 peer_capability = 0;
19783#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019784 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019785 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019786 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019787
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019788 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19789 if (NULL == pAdapter)
19790 {
19791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19792 "%s: Adapter is NULL",__func__);
19793 return -EINVAL;
19794 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019795 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19796 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
19797 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019798
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019799 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019800 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019801 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019803 "Invalid arguments");
19804 return -EINVAL;
19805 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019806
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019807 if (pHddCtx->isLogpInProgress)
19808 {
19809 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19810 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053019811 wlan_hdd_tdls_set_link_status(pAdapter,
19812 peer,
19813 eTDLS_LINK_IDLE,
19814 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019815 return -EBUSY;
19816 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019817
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019818 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
19819 {
19820 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19821 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19822 return -EAGAIN;
19823 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019824
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019825 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
19826 if (!pHddTdlsCtx) {
19827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19828 "%s: pHddTdlsCtx not valid.", __func__);
Hanumanth Reddy Pothula36dfa522018-03-12 16:42:08 +053019829 return -EINVAL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019830 }
19831
Hoonki Lee27511902013-03-14 18:19:06 -070019832 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019833 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019835 "%s: TDLS mode is disabled OR not enabled in FW."
19836 MAC_ADDRESS_STR " action %d declined.",
19837 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019838 return -ENOTSUPP;
19839 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019840
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019841 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19842
19843 if( NULL == pHddStaCtx )
19844 {
19845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19846 "%s: HDD station context NULL ",__func__);
19847 return -EINVAL;
19848 }
19849
19850 /* STA should be connected and authenticated
19851 * before sending any TDLS frames
19852 */
19853 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
19854 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
19855 {
19856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19857 "STA is not connected or unauthenticated. "
19858 "connState %u, uIsAuthenticated %u",
19859 pHddStaCtx->conn_info.connState,
19860 pHddStaCtx->conn_info.uIsAuthenticated);
19861 return -EAGAIN;
19862 }
19863
Hoonki Lee27511902013-03-14 18:19:06 -070019864 /* other than teardown frame, other mgmt frames are not sent if disabled */
19865 if (SIR_MAC_TDLS_TEARDOWN != action_code)
19866 {
19867 /* if tdls_mode is disabled to respond to peer's request */
19868 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
19869 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019871 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019872 " TDLS mode is disabled. action %d declined.",
19873 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070019874
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019875 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070019876 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053019877
19878 if (vos_max_concurrent_connections_reached())
19879 {
19880 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
19881 return -EINVAL;
19882 }
Hoonki Lee27511902013-03-14 18:19:06 -070019883 }
19884
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019885 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
19886 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053019887 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019888 {
19889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019890 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019891 " TDLS setup is ongoing. action %d declined.",
19892 __func__, MAC_ADDR_ARRAY(peer), action_code);
19893 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019894 }
19895 }
19896
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019897 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
19898 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080019899 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019900 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19901 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019902 {
19903 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
19904 we return error code at 'add_station()'. Hence we have this
19905 check again in addtion to add_station().
19906 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019907 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019908 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19910 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019911 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
19912 __func__, MAC_ADDR_ARRAY(peer), action_code,
19913 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053019914 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080019915 }
19916 else
19917 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019918 /* maximum reached. tweak to send error code to peer and return
19919 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019920 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19922 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019923 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
19924 __func__, MAC_ADDR_ARRAY(peer), status_code,
19925 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070019926 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019927 /* fall through to send setup resp with failure status
19928 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019929 }
19930 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019931 else
19932 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019933 mutex_lock(&pHddCtx->tdls_lock);
19934 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019935 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019936 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019937 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019939 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
19940 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019941 return -EPERM;
19942 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019943 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019944 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019945 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019946
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019948 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019949 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
19950 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019951
Hoonki Leea34dd892013-02-05 22:56:02 -080019952 /*Except teardown responder will not be used so just make 0*/
19953 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019954 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080019955 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019956
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019957 mutex_lock(&pHddCtx->tdls_lock);
19958 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019959
19960 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
19961 responder = pTdlsPeer->is_responder;
19962 else
Hoonki Leea34dd892013-02-05 22:56:02 -080019963 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019965 "%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 -070019966 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
19967 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019968 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019969 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080019970 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019971 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019972 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019973
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019974 /* Discard TDLS setup if peer is removed by user app */
19975 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
19976 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19977 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
19978 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
19979
19980 mutex_lock(&pHddCtx->tdls_lock);
19981 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19982 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
19983 mutex_unlock(&pHddCtx->tdls_lock);
19984 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
19985 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
19986 MAC_ADDR_ARRAY(peer), action_code);
19987 return -EINVAL;
19988 }
19989 mutex_unlock(&pHddCtx->tdls_lock);
19990 }
19991
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019992 /* For explicit trigger of DIS_REQ come out of BMPS for
19993 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070019994 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053019995 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019996 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
19997 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070019998 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019999 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020001 "%s: Sending frame action_code %u.Disable BMPS", __func__,
20002 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020003 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
20004 if (status != VOS_STATUS_SUCCESS) {
20005 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020006 } else {
20007 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020008 }
Hoonki Lee14621352013-04-16 17:51:19 -070020009 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020010 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020011 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020012 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
20013 }
20014 }
Hoonki Lee14621352013-04-16 17:51:19 -070020015 }
20016
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020017 /* make sure doesn't call send_mgmt() while it is pending */
20018 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
20019 {
20020 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080020021 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020022 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020023 ret = -EBUSY;
20024 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020025 }
20026
20027 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020028 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
20029
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020030 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
20031 pAdapter->sessionId, peer, action_code, dialog_token,
20032 status_code, peer_capability, (tANI_U8 *)buf, len,
20033 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020034
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020035 if (VOS_STATUS_SUCCESS != status)
20036 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20038 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020039 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020040 ret = -EINVAL;
20041 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020042 }
20043
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20045 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
20046 WAIT_TIME_TDLS_MGMT);
20047
Hoonki Leed37cbb32013-04-20 00:31:14 -070020048 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
20049 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
20050
20051 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020052 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070020053 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070020054 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070020055 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020056 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080020057
20058 if (pHddCtx->isLogpInProgress)
20059 {
20060 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20061 "%s: LOGP in Progress. Ignore!!!", __func__);
20062 return -EAGAIN;
20063 }
Abhishek Singh837adf22015-10-01 17:37:37 +053020064 if (rc <= 0)
20065 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
20066 WLAN_LOG_INDICATOR_HOST_DRIVER,
20067 WLAN_LOG_REASON_HDD_TIME_OUT,
20068 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080020069
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020070 ret = -EINVAL;
20071 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020072 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020073 else
20074 {
20075 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20076 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
20077 __func__, rc, pAdapter->mgmtTxCompletionStatus);
20078 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020079
Gopichand Nakkala05922802013-03-14 12:23:19 -070020080 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070020081 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020082 ret = max_sta_failed;
20083 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070020084 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020085
Hoonki Leea34dd892013-02-05 22:56:02 -080020086 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
20087 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020088 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020089 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20090 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020091 }
20092 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
20093 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020094 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020095 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20096 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020097 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020098
20099 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020100
20101tx_failed:
20102 /* add_station will be called before sending TDLS_SETUP_REQ and
20103 * TDLS_SETUP_RSP and as part of add_station driver will enable
20104 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
20105 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
20106 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
20107 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
20108 */
20109
20110 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20111 (SIR_MAC_TDLS_SETUP_RSP == action_code))
20112 wlan_hdd_tdls_check_bmps(pAdapter);
20113 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020114}
20115
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020116#if TDLS_MGMT_VERSION2
20117static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20118 u8 *peer, u8 action_code, u8 dialog_token,
20119 u16 status_code, u32 peer_capability,
20120 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020121#else /* TDLS_MGMT_VERSION2 */
20122#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20123static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20124 struct net_device *dev,
20125 const u8 *peer, u8 action_code,
20126 u8 dialog_token, u16 status_code,
20127 u32 peer_capability, bool initiator,
20128 const u8 *buf, size_t len)
20129#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20130static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20131 struct net_device *dev,
20132 const u8 *peer, u8 action_code,
20133 u8 dialog_token, u16 status_code,
20134 u32 peer_capability, const u8 *buf,
20135 size_t len)
20136#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20137static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20138 struct net_device *dev,
20139 u8 *peer, u8 action_code,
20140 u8 dialog_token,
20141 u16 status_code, u32 peer_capability,
20142 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020143#else
20144static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20145 u8 *peer, u8 action_code, u8 dialog_token,
20146 u16 status_code, const u8 *buf, size_t len)
20147#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020148#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020149{
20150 int ret;
20151
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020152 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020153#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020154 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20155 dialog_token, status_code,
20156 peer_capability, buf, len);
20157#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020158#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20159 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020160 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20161 dialog_token, status_code,
20162 peer_capability, initiator,
20163 buf, len);
20164#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20165 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20166 dialog_token, status_code,
20167 peer_capability, buf, len);
20168#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20169 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20170 dialog_token, status_code,
20171 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020172#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020173 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20174 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020175#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020176#endif
20177 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020178
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020179 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020180}
Atul Mittal115287b2014-07-08 13:26:33 +053020181
20182int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020183#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20184 const u8 *peer,
20185#else
Atul Mittal115287b2014-07-08 13:26:33 +053020186 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020187#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020188 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053020189 cfg80211_exttdls_callback callback)
20190{
20191
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020192 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053020193 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020194 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053020195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20196 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
20197 __func__, MAC_ADDR_ARRAY(peer));
20198
20199 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20200 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20201
20202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020203 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20204 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20205 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020206 return -ENOTSUPP;
20207 }
20208
20209 /* To cater the requirement of establishing the TDLS link
20210 * irrespective of the data traffic , get an entry of TDLS peer.
20211 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020212 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020213 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
20214 if (pTdlsPeer == NULL) {
20215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20216 "%s: peer " MAC_ADDRESS_STR " not existing",
20217 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020218 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020219 return -EINVAL;
20220 }
20221
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020222 /* check FW TDLS Off Channel capability */
20223 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020224 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020225 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020226 {
20227 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
20228 pTdlsPeer->peerParams.global_operating_class =
20229 tdls_peer_params->global_operating_class;
20230 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
20231 pTdlsPeer->peerParams.min_bandwidth_kbps =
20232 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020233 /* check configured channel is valid, non dfs and
20234 * not current operating channel */
20235 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
20236 tdls_peer_params->channel)) &&
20237 (pHddStaCtx) &&
20238 (tdls_peer_params->channel !=
20239 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020240 {
20241 pTdlsPeer->isOffChannelConfigured = TRUE;
20242 }
20243 else
20244 {
20245 pTdlsPeer->isOffChannelConfigured = FALSE;
20246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20247 "%s: Configured Tdls Off Channel is not valid", __func__);
20248
20249 }
20250 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020251 "%s: tdls_off_channel %d isOffChannelConfigured %d "
20252 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020253 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020254 pTdlsPeer->isOffChannelConfigured,
20255 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020256 }
20257 else
20258 {
20259 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020260 "%s: TDLS off channel FW capability %d, "
20261 "host capab %d or Invalid TDLS Peer Params", __func__,
20262 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
20263 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020264 }
20265
Atul Mittal115287b2014-07-08 13:26:33 +053020266 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
20267
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020268 mutex_unlock(&pHddCtx->tdls_lock);
20269
Atul Mittal115287b2014-07-08 13:26:33 +053020270 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20271 " %s TDLS Add Force Peer Failed",
20272 __func__);
20273 return -EINVAL;
20274 }
20275 /*EXT TDLS*/
20276
20277 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020278 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020279 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20280 " %s TDLS set callback Failed",
20281 __func__);
20282 return -EINVAL;
20283 }
20284
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020285 mutex_unlock(&pHddCtx->tdls_lock);
20286
Atul Mittal115287b2014-07-08 13:26:33 +053020287 return(0);
20288
20289}
20290
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020291int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
20292#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20293 const u8 *peer
20294#else
20295 u8 *peer
20296#endif
20297)
Atul Mittal115287b2014-07-08 13:26:33 +053020298{
20299
20300 hddTdlsPeer_t *pTdlsPeer;
20301 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020302
Atul Mittal115287b2014-07-08 13:26:33 +053020303 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20304 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
20305 __func__, MAC_ADDR_ARRAY(peer));
20306
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020307 if (0 != wlan_hdd_validate_context(pHddCtx)) {
20308 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
20309 return -EINVAL;
20310 }
20311
Atul Mittal115287b2014-07-08 13:26:33 +053020312 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20313 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20314
20315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020316 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20317 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20318 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020319 return -ENOTSUPP;
20320 }
20321
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020322 mutex_lock(&pHddCtx->tdls_lock);
20323 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053020324
20325 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020326 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020327 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020328 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053020329 __func__, MAC_ADDR_ARRAY(peer));
20330 return -EINVAL;
20331 }
20332 else {
20333 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
20334 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020335 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
20336 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020337 /* if channel switch is configured, reset
20338 the channel for this peer */
20339 if (TRUE == pTdlsPeer->isOffChannelConfigured)
20340 {
20341 pTdlsPeer->peerParams.channel = 0;
20342 pTdlsPeer->isOffChannelConfigured = FALSE;
20343 }
Atul Mittal115287b2014-07-08 13:26:33 +053020344 }
20345
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020346 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020347 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020348 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053020349 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020350 }
Atul Mittal115287b2014-07-08 13:26:33 +053020351
20352 /*EXT TDLS*/
20353
20354 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020355 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020356 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20357 " %s TDLS set callback Failed",
20358 __func__);
20359 return -EINVAL;
20360 }
Atul Mittal115287b2014-07-08 13:26:33 +053020361
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020362 mutex_unlock(&pHddCtx->tdls_lock);
20363
20364 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053020365}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020366static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020367#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20368 const u8 *peer,
20369#else
20370 u8 *peer,
20371#endif
20372 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020373{
20374 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20375 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020376 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020377 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020378
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020379 ENTER();
20380
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020381 if (!pAdapter) {
20382 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
20383 return -EINVAL;
20384 }
20385
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020386 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20387 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
20388 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020389 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020390 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070020392 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020393 return -EINVAL;
20394 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020395
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020396 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020397 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020398 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020399 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020400 }
20401
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020402
20403 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020404 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020405 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020407 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
20408 "Cannot process TDLS commands",
20409 pHddCtx->cfg_ini->fEnableTDLSSupport,
20410 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020411 return -ENOTSUPP;
20412 }
20413
20414 switch (oper) {
20415 case NL80211_TDLS_ENABLE_LINK:
20416 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020417 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020418 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053020419 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
20420 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053020421 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020422 tANI_U16 numCurrTdlsPeers = 0;
20423 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020424 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020425 tSirMacAddr peerMac;
20426 int channel;
20427 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020428
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20430 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
20431 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020432
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020433 mutex_lock(&pHddCtx->tdls_lock);
20434 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020435 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053020436 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020437 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020438 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20439 " (oper %d) not exsting. ignored",
20440 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20441 return -EINVAL;
20442 }
20443
20444 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20445 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20446 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20447 "NL80211_TDLS_ENABLE_LINK");
20448
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020449 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
20450 {
20451 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
20452 MAC_ADDRESS_STR " failed",
20453 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020454 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020455 return -EINVAL;
20456 }
20457
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020458 /* before starting tdls connection, set tdls
20459 * off channel established status to default value */
20460 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020461
20462 mutex_unlock(&pHddCtx->tdls_lock);
20463
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053020464 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020465 /* TDLS Off Channel, Disable tdls channel switch,
20466 when there are more than one tdls link */
20467 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053020468 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020469 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020470 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020471 /* get connected peer and send disable tdls off chan */
20472 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020473 if ((connPeer) &&
20474 (connPeer->isOffChannelSupported == TRUE) &&
20475 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020476 {
20477 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20478 "%s: More then one peer connected, Disable "
20479 "TDLS channel switch", __func__);
20480
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020481 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020482 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
20483 channel = connPeer->peerParams.channel;
20484
20485 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020486
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020487 ret = sme_SendTdlsChanSwitchReq(
20488 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020489 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020490 peerMac,
20491 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020492 TDLS_OFF_CHANNEL_BW_OFFSET,
20493 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020494 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020495 hddLog(VOS_TRACE_LEVEL_ERROR,
20496 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020497 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020498 }
20499 else
20500 {
20501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20502 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020503 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020504 "isOffChannelConfigured %d",
20505 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020506 (connPeer ? (connPeer->isOffChannelSupported)
20507 : -1),
20508 (connPeer ? (connPeer->isOffChannelConfigured)
20509 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020510 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020511 }
20512 }
20513
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020514 mutex_lock(&pHddCtx->tdls_lock);
20515 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20516 if ( NULL == pTdlsPeer ) {
20517 mutex_unlock(&pHddCtx->tdls_lock);
20518 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20519 "%s: " MAC_ADDRESS_STR
20520 " (oper %d) peer got freed in other context. ignored",
20521 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20522 return -EINVAL;
20523 }
20524 peer_status = pTdlsPeer->link_status;
20525 mutex_unlock(&pHddCtx->tdls_lock);
20526
20527 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020528 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020529 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053020530
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020531 if (0 != wlan_hdd_tdls_get_link_establish_params(
20532 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020533 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020534 return -EINVAL;
20535 }
20536 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020537
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020538 ret = sme_SendTdlsLinkEstablishParams(
20539 WLAN_HDD_GET_HAL_CTX(pAdapter),
20540 pAdapter->sessionId, peer,
20541 &tdlsLinkEstablishParams);
20542 if (ret != VOS_STATUS_SUCCESS) {
20543 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
20544 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020545 /* Send TDLS peer UAPSD capabilities to the firmware and
20546 * register with the TL on after the response for this operation
20547 * is received .
20548 */
20549 ret = wait_for_completion_interruptible_timeout(
20550 &pAdapter->tdls_link_establish_req_comp,
20551 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053020552
20553 mutex_lock(&pHddCtx->tdls_lock);
20554 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20555 if ( NULL == pTdlsPeer ) {
20556 mutex_unlock(&pHddCtx->tdls_lock);
20557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20558 "%s %d: " MAC_ADDRESS_STR
20559 " (oper %d) peer got freed in other context. ignored",
20560 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
20561 (int)oper);
20562 return -EINVAL;
20563 }
20564 peer_status = pTdlsPeer->link_status;
20565 mutex_unlock(&pHddCtx->tdls_lock);
20566
20567 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020568 {
20569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020570 FL("Link Establish Request Failed Status %ld"),
20571 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020572 return -EINVAL;
20573 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020574 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020575
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020576 mutex_lock(&pHddCtx->tdls_lock);
20577 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20578 if ( NULL == pTdlsPeer ) {
20579 mutex_unlock(&pHddCtx->tdls_lock);
20580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20581 "%s: " MAC_ADDRESS_STR
20582 " (oper %d) peer got freed in other context. ignored",
20583 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20584 return -EINVAL;
20585 }
20586
Atul Mittal115287b2014-07-08 13:26:33 +053020587 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20588 eTDLS_LINK_CONNECTED,
20589 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020590 staDesc.ucSTAId = pTdlsPeer->staId;
20591 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053020592
20593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20594 "%s: tdlsLinkEstablishParams of peer "
20595 MAC_ADDRESS_STR "uapsdQueues: %d"
20596 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
20597 "isResponder: %d peerstaId: %d",
20598 __func__,
20599 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
20600 tdlsLinkEstablishParams.uapsdQueues,
20601 tdlsLinkEstablishParams.qos,
20602 tdlsLinkEstablishParams.maxSp,
20603 tdlsLinkEstablishParams.isBufSta,
20604 tdlsLinkEstablishParams.isOffChannelSupported,
20605 tdlsLinkEstablishParams.isResponder,
20606 pTdlsPeer->staId);
20607
20608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20609 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
20610 __func__,
20611 staDesc.ucSTAId,
20612 staDesc.ucQosEnabled);
20613
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020614 ret = WLANTL_UpdateTdlsSTAClient(
20615 pHddCtx->pvosContext,
20616 &staDesc);
20617 if (ret != VOS_STATUS_SUCCESS) {
20618 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
20619 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053020620
Gopichand Nakkala471708b2013-06-04 20:03:01 +053020621 /* Mark TDLS client Authenticated .*/
20622 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
20623 pTdlsPeer->staId,
20624 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020625 if (VOS_STATUS_SUCCESS == status)
20626 {
Hoonki Lee14621352013-04-16 17:51:19 -070020627 if (pTdlsPeer->is_responder == 0)
20628 {
20629 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020630 tdlsConnInfo_t *tdlsInfo;
20631
20632 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
20633
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020634 if (!vos_timer_is_initialized(
20635 &pTdlsPeer->initiatorWaitTimeoutTimer))
20636 {
20637 /* Initialize initiator wait callback */
20638 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020639 &pTdlsPeer->initiatorWaitTimeoutTimer,
20640 VOS_TIMER_TYPE_SW,
20641 wlan_hdd_tdls_initiator_wait_cb,
20642 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020643 }
Hoonki Lee14621352013-04-16 17:51:19 -070020644 wlan_hdd_tdls_timer_restart(pAdapter,
20645 &pTdlsPeer->initiatorWaitTimeoutTimer,
20646 WAIT_TIME_TDLS_INITIATOR);
20647 /* suspend initiator TX until it receives direct packet from the
20648 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020649 ret = WLANTL_SuspendDataTx(
20650 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20651 &staId, NULL);
20652 if (ret != VOS_STATUS_SUCCESS) {
20653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20654 }
Hoonki Lee14621352013-04-16 17:51:19 -070020655 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020656
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020657 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020658 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020659 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020660 suppChannelLen =
20661 tdlsLinkEstablishParams.supportedChannelsLen;
20662
20663 if ((suppChannelLen > 0) &&
20664 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20665 {
20666 tANI_U8 suppPeerChannel = 0;
20667 int i = 0;
20668 for (i = 0U; i < suppChannelLen; i++)
20669 {
20670 suppPeerChannel =
20671 tdlsLinkEstablishParams.supportedChannels[i];
20672
20673 pTdlsPeer->isOffChannelSupported = FALSE;
20674 if (suppPeerChannel ==
20675 pTdlsPeer->peerParams.channel)
20676 {
20677 pTdlsPeer->isOffChannelSupported = TRUE;
20678 break;
20679 }
20680 }
20681 }
20682 else
20683 {
20684 pTdlsPeer->isOffChannelSupported = FALSE;
20685 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020686 }
20687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20688 "%s: TDLS channel switch request for channel "
20689 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020690 "%d isOffChannelSupported %d", __func__,
20691 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020692 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020693 suppChannelLen,
20694 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020695
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020696 /* TDLS Off Channel, Enable tdls channel switch,
20697 when their is only one tdls link and it supports */
20698 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20699 if ((numCurrTdlsPeers == 1) &&
20700 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20701 (TRUE == pTdlsPeer->isOffChannelConfigured))
20702 {
20703 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20704 "%s: Send TDLS channel switch request for channel %d",
20705 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020706
20707 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020708 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20709 channel = pTdlsPeer->peerParams.channel;
20710
20711 mutex_unlock(&pHddCtx->tdls_lock);
20712
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020713 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20714 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020715 peerMac,
20716 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020717 TDLS_OFF_CHANNEL_BW_OFFSET,
20718 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020719 if (ret != VOS_STATUS_SUCCESS) {
20720 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20721 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020722 }
20723 else
20724 {
20725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20726 "%s: TDLS channel switch request not sent"
20727 " numCurrTdlsPeers %d "
20728 "isOffChannelSupported %d "
20729 "isOffChannelConfigured %d",
20730 __func__, numCurrTdlsPeers,
20731 pTdlsPeer->isOffChannelSupported,
20732 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020733 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020734 }
20735
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020736 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020737 else
20738 mutex_unlock(&pHddCtx->tdls_lock);
20739
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020740 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020741
20742 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020743 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
20744 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020745 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020746 int ac;
20747 uint8 ucAc[4] = { WLANTL_AC_VO,
20748 WLANTL_AC_VI,
20749 WLANTL_AC_BK,
20750 WLANTL_AC_BE };
20751 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
20752 for(ac=0; ac < 4; ac++)
20753 {
20754 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20755 pTdlsPeer->staId, ucAc[ac],
20756 tlTid[ac], tlTid[ac], 0, 0,
20757 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020758 if (status != VOS_STATUS_SUCCESS) {
20759 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
20760 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020761 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020762 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020763 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020764
Bhargav Shah66896792015-10-01 18:17:37 +053020765 /* stop TCP delack timer if TDLS is enable */
20766 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20767 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053020768 hdd_wlan_tdls_enable_link_event(peer,
20769 pTdlsPeer->isOffChannelSupported,
20770 pTdlsPeer->isOffChannelConfigured,
20771 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020772 }
20773 break;
20774 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080020775 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020776 tANI_U16 numCurrTdlsPeers = 0;
20777 hddTdlsPeer_t *connPeer = NULL;
20778
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020779 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20780 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
20781 __func__, MAC_ADDR_ARRAY(peer));
20782
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020783 mutex_lock(&pHddCtx->tdls_lock);
20784 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020785
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020786
Sunil Dutt41de4e22013-11-14 18:09:02 +053020787 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020788 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020789 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20790 " (oper %d) not exsting. ignored",
20791 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20792 return -EINVAL;
20793 }
20794
20795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20796 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20797 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20798 "NL80211_TDLS_DISABLE_LINK");
20799
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020800 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080020801 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020802 long status;
20803
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020804 /* set tdls off channel status to false for this peer */
20805 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053020806 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20807 eTDLS_LINK_TEARING,
20808 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
20809 eTDLS_LINK_UNSPECIFIED:
20810 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020811 mutex_unlock(&pHddCtx->tdls_lock);
20812
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020813 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
20814
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020815 status = sme_DeleteTdlsPeerSta(
20816 WLAN_HDD_GET_HAL_CTX(pAdapter),
20817 pAdapter->sessionId, peer );
20818 if (status != VOS_STATUS_SUCCESS) {
20819 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
20820 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020821
20822 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
20823 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020824
20825 mutex_lock(&pHddCtx->tdls_lock);
20826 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20827 if ( NULL == pTdlsPeer ) {
20828 mutex_unlock(&pHddCtx->tdls_lock);
20829 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20830 " peer was freed in other context",
20831 __func__, MAC_ADDR_ARRAY(peer));
20832 return -EINVAL;
20833 }
20834
Atul Mittal271a7652014-09-12 13:18:22 +053020835 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053020836 eTDLS_LINK_IDLE,
20837 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020838 mutex_unlock(&pHddCtx->tdls_lock);
20839
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020840 if (status <= 0)
20841 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20843 "%s: Del station failed status %ld",
20844 __func__, status);
20845 return -EPERM;
20846 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020847
20848 /* TDLS Off Channel, Enable tdls channel switch,
20849 when their is only one tdls link and it supports */
20850 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20851 if (numCurrTdlsPeers == 1)
20852 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020853 tSirMacAddr peerMac;
20854 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020855
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020856 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020857 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020858
20859 if (connPeer == NULL) {
20860 mutex_unlock(&pHddCtx->tdls_lock);
20861 hddLog(VOS_TRACE_LEVEL_ERROR,
20862 "%s connPeer is NULL", __func__);
20863 return -EINVAL;
20864 }
20865
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020866 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
20867 channel = connPeer->peerParams.channel;
20868
20869 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20870 "%s: TDLS channel switch "
20871 "isOffChannelSupported %d "
20872 "isOffChannelConfigured %d "
20873 "isOffChannelEstablished %d",
20874 __func__,
20875 (connPeer ? connPeer->isOffChannelSupported : -1),
20876 (connPeer ? connPeer->isOffChannelConfigured : -1),
20877 (connPeer ? connPeer->isOffChannelEstablished : -1));
20878
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020879 if ((connPeer) &&
20880 (connPeer->isOffChannelSupported == TRUE) &&
20881 (connPeer->isOffChannelConfigured == TRUE))
20882 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020883 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020884 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020885 status = sme_SendTdlsChanSwitchReq(
20886 WLAN_HDD_GET_HAL_CTX(pAdapter),
20887 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020888 peerMac,
20889 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020890 TDLS_OFF_CHANNEL_BW_OFFSET,
20891 TDLS_CHANNEL_SWITCH_ENABLE);
20892 if (status != VOS_STATUS_SUCCESS) {
20893 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
20894 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020895 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020896 else
20897 mutex_unlock(&pHddCtx->tdls_lock);
20898 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020899 else
20900 {
20901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20902 "%s: TDLS channel switch request not sent "
20903 "numCurrTdlsPeers %d ",
20904 __func__, numCurrTdlsPeers);
20905 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020906 }
20907 else
20908 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020909 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020910 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20911 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080020912 }
Bhargav Shah66896792015-10-01 18:17:37 +053020913 if (numCurrTdlsPeers == 0) {
20914 /* start TCP delack timer if TDLS is disable */
20915 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20916 hdd_manage_delack_timer(pHddCtx);
20917 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020918 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020919 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020920 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020921 {
Atul Mittal115287b2014-07-08 13:26:33 +053020922 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020923
Atul Mittal115287b2014-07-08 13:26:33 +053020924 if (0 != status)
20925 {
20926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020927 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053020928 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020929 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053020930 break;
20931 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020932 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020933 {
Atul Mittal115287b2014-07-08 13:26:33 +053020934 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
20935 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020936 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053020937 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020938
Atul Mittal115287b2014-07-08 13:26:33 +053020939 if (0 != status)
20940 {
20941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020942 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053020943 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053020944 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053020945 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020946 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020947 case NL80211_TDLS_DISCOVERY_REQ:
20948 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020949 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020950 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020951 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020952 return -ENOTSUPP;
20953 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20955 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020956 return -ENOTSUPP;
20957 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020958
20959 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020960 return 0;
20961}
Chilam NG571c65a2013-01-19 12:27:36 +053020962
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020963static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020964#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20965 const u8 *peer,
20966#else
20967 u8 *peer,
20968#endif
20969 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020970{
20971 int ret;
20972
20973 vos_ssr_protect(__func__);
20974 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
20975 vos_ssr_unprotect(__func__);
20976
20977 return ret;
20978}
20979
Chilam NG571c65a2013-01-19 12:27:36 +053020980int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
20981 struct net_device *dev, u8 *peer)
20982{
Arif Hussaina7c8e412013-11-20 11:06:42 -080020983 hddLog(VOS_TRACE_LEVEL_INFO,
20984 "tdls send discover req: "MAC_ADDRESS_STR,
20985 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020986#if TDLS_MGMT_VERSION2
20987 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20988 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20989#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020990#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20991 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20992 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
20993#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20994 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20995 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20996#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20997 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20998 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20999#else
Chilam NG571c65a2013-01-19 12:27:36 +053021000 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21001 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021002#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021003#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053021004}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021005#endif
21006
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021007#ifdef WLAN_FEATURE_GTK_OFFLOAD
21008/*
21009 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
21010 * Callback rountine called upon receiving response for
21011 * get offload info
21012 */
21013void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
21014 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
21015{
21016
21017 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021018 tANI_U8 tempReplayCounter[8];
21019 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021020
21021 ENTER();
21022
21023 if (NULL == pAdapter)
21024 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053021025 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021026 "%s: HDD adapter is Null", __func__);
21027 return ;
21028 }
21029
21030 if (NULL == pGtkOffloadGetInfoRsp)
21031 {
21032 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21033 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
21034 return ;
21035 }
21036
21037 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
21038 {
21039 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21040 "%s: wlan Failed to get replay counter value",
21041 __func__);
21042 return ;
21043 }
21044
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021045 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21046 /* Update replay counter */
21047 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
21048 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21049
21050 {
21051 /* changing from little to big endian since supplicant
21052 * works on big endian format
21053 */
21054 int i;
21055 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21056
21057 for (i = 0; i < 8; i++)
21058 {
21059 tempReplayCounter[7-i] = (tANI_U8)p[i];
21060 }
21061 }
21062
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021063 /* Update replay counter to NL */
21064 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021065 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021066}
21067
21068/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021069 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021070 * This function is used to offload GTK rekeying job to the firmware.
21071 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021072int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021073 struct cfg80211_gtk_rekey_data *data)
21074{
21075 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21076 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21077 hdd_station_ctx_t *pHddStaCtx;
21078 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021079 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021080 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021081 eHalStatus status = eHAL_STATUS_FAILURE;
21082
21083 ENTER();
21084
21085 if (NULL == pAdapter)
21086 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053021087 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021088 "%s: HDD adapter is Null", __func__);
21089 return -ENODEV;
21090 }
21091
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053021092 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21093 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
21094 pAdapter->sessionId, pAdapter->device_mode));
21095
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021096 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021097 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021098 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021099 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021100 }
21101
21102 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21103 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
21104 if (NULL == hHal)
21105 {
21106 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21107 "%s: HAL context is Null!!!", __func__);
21108 return -EAGAIN;
21109 }
21110
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021111 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
21112 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
21113 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
21114 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021115 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021116 {
21117 /* changing from big to little endian since driver
21118 * works on little endian format
21119 */
21120 tANI_U8 *p =
21121 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
21122 int i;
21123
21124 for (i = 0; i < 8; i++)
21125 {
21126 p[7-i] = data->replay_ctr[i];
21127 }
21128 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021129
21130 if (TRUE == pHddCtx->hdd_wlan_suspended)
21131 {
21132 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021133 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
21134 sizeof (tSirGtkOffloadParams));
21135 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021136 pAdapter->sessionId);
21137
21138 if (eHAL_STATUS_SUCCESS != status)
21139 {
21140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21141 "%s: sme_SetGTKOffload failed, returned %d",
21142 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021143
21144 /* Need to clear any trace of key value in the memory.
21145 * Thus zero out the memory even though it is local
21146 * variable.
21147 */
21148 vos_mem_zero(&hddGtkOffloadReqParams,
21149 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021150 return status;
21151 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21153 "%s: sme_SetGTKOffload successfull", __func__);
21154 }
21155 else
21156 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021157 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21158 "%s: wlan not suspended GTKOffload request is stored",
21159 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021160 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021161
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021162 /* Need to clear any trace of key value in the memory.
21163 * Thus zero out the memory even though it is local
21164 * variable.
21165 */
21166 vos_mem_zero(&hddGtkOffloadReqParams,
21167 sizeof(hddGtkOffloadReqParams));
21168
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021169 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021170 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021171}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021172
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021173int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
21174 struct cfg80211_gtk_rekey_data *data)
21175{
21176 int ret;
21177
21178 vos_ssr_protect(__func__);
21179 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
21180 vos_ssr_unprotect(__func__);
21181
21182 return ret;
21183}
21184#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021185/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021186 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021187 * This function is used to set access control policy
21188 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021189static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21190 struct net_device *dev,
21191 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021192{
21193 int i;
21194 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21195 hdd_hostapd_state_t *pHostapdState;
21196 tsap_Config_t *pConfig;
21197 v_CONTEXT_t pVosContext = NULL;
21198 hdd_context_t *pHddCtx;
21199 int status;
21200
21201 ENTER();
21202
21203 if (NULL == pAdapter)
21204 {
21205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21206 "%s: HDD adapter is Null", __func__);
21207 return -ENODEV;
21208 }
21209
21210 if (NULL == params)
21211 {
21212 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21213 "%s: params is Null", __func__);
21214 return -EINVAL;
21215 }
21216
21217 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21218 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021219 if (0 != status)
21220 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021221 return status;
21222 }
21223
21224 pVosContext = pHddCtx->pvosContext;
21225 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
21226
21227 if (NULL == pHostapdState)
21228 {
21229 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21230 "%s: pHostapdState is Null", __func__);
21231 return -EINVAL;
21232 }
21233
21234 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
21235 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021236 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21237 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
21238 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021239
21240 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
21241 {
21242 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
21243
21244 /* default value */
21245 pConfig->num_accept_mac = 0;
21246 pConfig->num_deny_mac = 0;
21247
21248 /**
21249 * access control policy
21250 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
21251 * listed in hostapd.deny file.
21252 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
21253 * listed in hostapd.accept file.
21254 */
21255 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
21256 {
21257 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
21258 }
21259 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
21260 {
21261 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
21262 }
21263 else
21264 {
21265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21266 "%s:Acl Policy : %d is not supported",
21267 __func__, params->acl_policy);
21268 return -ENOTSUPP;
21269 }
21270
21271 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
21272 {
21273 pConfig->num_accept_mac = params->n_acl_entries;
21274 for (i = 0; i < params->n_acl_entries; i++)
21275 {
21276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21277 "** Add ACL MAC entry %i in WhiletList :"
21278 MAC_ADDRESS_STR, i,
21279 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21280
21281 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
21282 sizeof(qcmacaddr));
21283 }
21284 }
21285 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
21286 {
21287 pConfig->num_deny_mac = params->n_acl_entries;
21288 for (i = 0; i < params->n_acl_entries; i++)
21289 {
21290 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21291 "** Add ACL MAC entry %i in BlackList :"
21292 MAC_ADDRESS_STR, i,
21293 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21294
21295 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
21296 sizeof(qcmacaddr));
21297 }
21298 }
21299
21300 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
21301 {
21302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21303 "%s: SAP Set Mac Acl fail", __func__);
21304 return -EINVAL;
21305 }
21306 }
21307 else
21308 {
21309 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053021310 "%s: Invalid device_mode = %s (%d)",
21311 __func__, hdd_device_modetoString(pAdapter->device_mode),
21312 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021313 return -EINVAL;
21314 }
21315
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021316 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021317 return 0;
21318}
21319
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021320static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21321 struct net_device *dev,
21322 const struct cfg80211_acl_data *params)
21323{
21324 int ret;
21325 vos_ssr_protect(__func__);
21326 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
21327 vos_ssr_unprotect(__func__);
21328
21329 return ret;
21330}
21331
Leo Chang9056f462013-08-01 19:21:11 -070021332#ifdef WLAN_NL80211_TESTMODE
21333#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070021334void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070021335(
21336 void *pAdapter,
21337 void *indCont
21338)
21339{
Leo Changd9df8aa2013-09-26 13:32:26 -070021340 tSirLPHBInd *lphbInd;
21341 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053021342 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070021343
21344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021345 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070021346
c_hpothu73f35e62014-04-18 13:40:08 +053021347 if (pAdapter == NULL)
21348 {
21349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21350 "%s: pAdapter is NULL\n",__func__);
21351 return;
21352 }
21353
Leo Chang9056f462013-08-01 19:21:11 -070021354 if (NULL == indCont)
21355 {
21356 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021357 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070021358 return;
21359 }
21360
c_hpothu73f35e62014-04-18 13:40:08 +053021361 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070021362 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070021363 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053021364 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070021365 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070021366 GFP_ATOMIC);
21367 if (!skb)
21368 {
21369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21370 "LPHB timeout, NL buffer alloc fail");
21371 return;
21372 }
21373
Leo Changac3ba772013-10-07 09:47:04 -070021374 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070021375 {
21376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21377 "WLAN_HDD_TM_ATTR_CMD put fail");
21378 goto nla_put_failure;
21379 }
Leo Changac3ba772013-10-07 09:47:04 -070021380 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070021381 {
21382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21383 "WLAN_HDD_TM_ATTR_TYPE put fail");
21384 goto nla_put_failure;
21385 }
Leo Changac3ba772013-10-07 09:47:04 -070021386 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070021387 sizeof(tSirLPHBInd), lphbInd))
21388 {
21389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21390 "WLAN_HDD_TM_ATTR_DATA put fail");
21391 goto nla_put_failure;
21392 }
Leo Chang9056f462013-08-01 19:21:11 -070021393 cfg80211_testmode_event(skb, GFP_ATOMIC);
21394 return;
21395
21396nla_put_failure:
21397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21398 "NLA Put fail");
21399 kfree_skb(skb);
21400
21401 return;
21402}
21403#endif /* FEATURE_WLAN_LPHB */
21404
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021405static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070021406{
21407 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
21408 int err = 0;
21409#ifdef FEATURE_WLAN_LPHB
21410 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070021411 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021412
21413 ENTER();
21414
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021415 err = wlan_hdd_validate_context(pHddCtx);
21416 if (0 != err)
21417 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021418 return err;
21419 }
Leo Chang9056f462013-08-01 19:21:11 -070021420#endif /* FEATURE_WLAN_LPHB */
21421
21422 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
21423 if (err)
21424 {
21425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21426 "%s Testmode INV ATTR", __func__);
21427 return err;
21428 }
21429
21430 if (!tb[WLAN_HDD_TM_ATTR_CMD])
21431 {
21432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21433 "%s Testmode INV CMD", __func__);
21434 return -EINVAL;
21435 }
21436
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021437 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21438 TRACE_CODE_HDD_CFG80211_TESTMODE,
21439 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070021440 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
21441 {
21442#ifdef FEATURE_WLAN_LPHB
21443 /* Low Power Heartbeat configuration request */
21444 case WLAN_HDD_TM_CMD_WLAN_HB:
21445 {
21446 int buf_len;
21447 void *buf;
21448 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080021449 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070021450
21451 if (!tb[WLAN_HDD_TM_ATTR_DATA])
21452 {
21453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21454 "%s Testmode INV DATA", __func__);
21455 return -EINVAL;
21456 }
21457
21458 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
21459 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080021460
Manjeet Singh3c577442017-02-10 19:03:38 +053021461 if (buf_len > sizeof(*hb_params)) {
21462 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
21463 buf_len);
21464 return -ERANGE;
21465 }
21466
Amar Singhal05852702014-02-04 14:40:00 -080021467 hb_params_temp =(tSirLPHBReq *)buf;
21468 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
21469 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
21470 return -EINVAL;
21471
Leo Chang9056f462013-08-01 19:21:11 -070021472 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
21473 if (NULL == hb_params)
21474 {
21475 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21476 "%s Request Buffer Alloc Fail", __func__);
21477 return -EINVAL;
21478 }
21479
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053021480 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070021481 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070021482 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
21483 hb_params,
21484 wlan_hdd_cfg80211_lphb_ind_handler);
21485 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070021486 {
Leo Changd9df8aa2013-09-26 13:32:26 -070021487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21488 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070021489 vos_mem_free(hb_params);
21490 }
Leo Chang9056f462013-08-01 19:21:11 -070021491 return 0;
21492 }
21493#endif /* FEATURE_WLAN_LPHB */
21494 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021495 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21496 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070021497 return -EOPNOTSUPP;
21498 }
21499
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021500 EXIT();
21501 return err;
Leo Chang9056f462013-08-01 19:21:11 -070021502}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021503
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053021504static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
21505#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
21506 struct wireless_dev *wdev,
21507#endif
21508 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021509{
21510 int ret;
21511
21512 vos_ssr_protect(__func__);
21513 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
21514 vos_ssr_unprotect(__func__);
21515
21516 return ret;
21517}
Leo Chang9056f462013-08-01 19:21:11 -070021518#endif /* CONFIG_NL80211_TESTMODE */
21519
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021520extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021521static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021522 struct net_device *dev,
21523 int idx, struct survey_info *survey)
21524{
21525 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21526 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053021527 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021528 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053021529 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021530 v_S7_t snr,rssi;
21531 int status, i, j, filled = 0;
21532
21533 ENTER();
21534
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021535 if (NULL == pAdapter)
21536 {
21537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21538 "%s: HDD adapter is Null", __func__);
21539 return -ENODEV;
21540 }
21541
21542 if (NULL == wiphy)
21543 {
21544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21545 "%s: wiphy is Null", __func__);
21546 return -ENODEV;
21547 }
21548
21549 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21550 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021551 if (0 != status)
21552 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021553 return status;
21554 }
21555
Mihir Sheted9072e02013-08-21 17:02:29 +053021556 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21557
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021558 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053021559 0 != pAdapter->survey_idx ||
21560 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021561 {
21562 /* The survey dump ops when implemented completely is expected to
21563 * return a survey of all channels and the ops is called by the
21564 * kernel with incremental values of the argument 'idx' till it
21565 * returns -ENONET. But we can only support the survey for the
21566 * operating channel for now. survey_idx is used to track
21567 * that the ops is called only once and then return -ENONET for
21568 * the next iteration
21569 */
21570 pAdapter->survey_idx = 0;
21571 return -ENONET;
21572 }
21573
Mukul Sharma9d5233b2015-06-11 20:28:20 +053021574 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
21575 {
21576 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21577 "%s: Roaming in progress, hence return ", __func__);
21578 return -ENONET;
21579 }
21580
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021581 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
21582
21583 wlan_hdd_get_snr(pAdapter, &snr);
21584 wlan_hdd_get_rssi(pAdapter, &rssi);
21585
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021586 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21587 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
21588 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021589 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
21590 hdd_wlan_get_freq(channel, &freq);
21591
21592
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053021593 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021594 {
21595 if (NULL == wiphy->bands[i])
21596 {
21597 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
21598 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
21599 continue;
21600 }
21601
21602 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
21603 {
21604 struct ieee80211_supported_band *band = wiphy->bands[i];
21605
21606 if (band->channels[j].center_freq == (v_U16_t)freq)
21607 {
21608 survey->channel = &band->channels[j];
21609 /* The Rx BDs contain SNR values in dB for the received frames
21610 * while the supplicant expects noise. So we calculate and
21611 * return the value of noise (dBm)
21612 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
21613 */
21614 survey->noise = rssi - snr;
21615 survey->filled = SURVEY_INFO_NOISE_DBM;
21616 filled = 1;
21617 }
21618 }
21619 }
21620
21621 if (filled)
21622 pAdapter->survey_idx = 1;
21623 else
21624 {
21625 pAdapter->survey_idx = 0;
21626 return -ENONET;
21627 }
21628
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021629 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021630 return 0;
21631}
21632
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021633static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
21634 struct net_device *dev,
21635 int idx, struct survey_info *survey)
21636{
21637 int ret;
21638
21639 vos_ssr_protect(__func__);
21640 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
21641 vos_ssr_unprotect(__func__);
21642
21643 return ret;
21644}
21645
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021646/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021647 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021648 * this is called when cfg80211 driver resume
21649 * driver updates latest sched_scan scan result(if any) to cfg80211 database
21650 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021651int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021652{
21653 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21654 hdd_adapter_t *pAdapter;
21655 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21656 VOS_STATUS status = VOS_STATUS_SUCCESS;
21657
21658 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021659
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021660 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021661 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021662 return 0;
21663 }
21664
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021665 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21666 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021667
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021668 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021669 {
21670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21671 "%s: Resume SoftAP", __func__);
21672 hdd_set_wlan_suspend_mode(false);
21673 }
21674
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021675 spin_lock(&pHddCtx->schedScan_lock);
21676 pHddCtx->isWiphySuspended = FALSE;
21677 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21678 {
21679 spin_unlock(&pHddCtx->schedScan_lock);
21680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21681 "%s: Return resume is not due to PNO indication", __func__);
21682 return 0;
21683 }
21684 // Reset flag to avoid updatating cfg80211 data old results again
21685 pHddCtx->isSchedScanUpdatePending = FALSE;
21686 spin_unlock(&pHddCtx->schedScan_lock);
21687
21688 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21689
21690 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21691 {
21692 pAdapter = pAdapterNode->pAdapter;
21693 if ( (NULL != pAdapter) &&
21694 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21695 {
21696 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021697 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21699 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021700 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021701 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021702 {
21703 /* Acquire wakelock to handle the case where APP's tries to
21704 * suspend immediately after updating the scan results. Whis
21705 * results in app's is in suspended state and not able to
21706 * process the connect request to AP
21707 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021708 hdd_prevent_suspend_timeout(2000,
21709 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021710 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021711 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021712
21713 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21714 "%s : cfg80211 scan result database updated", __func__);
21715
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021716 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021717 return 0;
21718
21719 }
21720 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21721 pAdapterNode = pNext;
21722 }
21723
21724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21725 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021726 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021727 return 0;
21728}
21729
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021730int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21731{
21732 int ret;
21733
21734 vos_ssr_protect(__func__);
21735 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
21736 vos_ssr_unprotect(__func__);
21737
21738 return ret;
21739}
21740
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021741/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021742 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021743 * this is called when cfg80211 driver suspends
21744 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021745int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021746 struct cfg80211_wowlan *wow)
21747{
21748 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021749 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021750
21751 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021752
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021753 ret = wlan_hdd_validate_context(pHddCtx);
21754 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021755 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021756 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021757 }
21758
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021759 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021760 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21761 "%s: Suspend SoftAP", __func__);
21762 hdd_set_wlan_suspend_mode(true);
21763 }
21764
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021765
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021766 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21767 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
21768 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021769 pHddCtx->isWiphySuspended = TRUE;
21770
21771 EXIT();
21772
21773 return 0;
21774}
21775
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021776int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
21777 struct cfg80211_wowlan *wow)
21778{
21779 int ret;
21780
21781 vos_ssr_protect(__func__);
21782 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
21783 vos_ssr_unprotect(__func__);
21784
21785 return ret;
21786}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021787
21788#ifdef FEATURE_OEM_DATA_SUPPORT
21789static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021790 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021791{
21792 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21793
21794 ENTER();
21795
21796 if (wlan_hdd_validate_context(pHddCtx)) {
21797 return;
21798 }
21799 if (!pMsg)
21800 {
21801 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
21802 return;
21803 }
21804
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021805 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021806
21807 EXIT();
21808 return;
21809
21810}
21811
21812void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021813 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021814{
21815 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21816
21817 ENTER();
21818
21819 if (wlan_hdd_validate_context(pHddCtx)) {
21820 return;
21821 }
21822
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021823 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021824
21825 switch(evType) {
21826 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021827 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021828 break;
21829 default:
21830 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
21831 break;
21832 }
21833 EXIT();
21834}
21835#endif
21836
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021837#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21838 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021839/**
21840 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
21841 * @wiphy: Pointer to wiphy
21842 * @wdev: Pointer to wireless device structure
21843 *
21844 * This function is used to abort an ongoing scan
21845 *
21846 * Return: None
21847 */
21848static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21849 struct wireless_dev *wdev)
21850{
21851 struct net_device *dev = wdev->netdev;
21852 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21853 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
21854 int ret;
21855
21856 ENTER();
21857
21858 if (NULL == adapter) {
21859 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
21860 return;
21861 }
21862
21863 ret = wlan_hdd_validate_context(hdd_ctx);
21864 if (0 != ret)
21865 return;
21866
21867 wlan_hdd_scan_abort(adapter);
21868
21869 return;
21870}
21871
21872/**
21873 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
21874 * @wiphy: Pointer to wiphy
21875 * @wdev: Pointer to wireless device structure
21876 *
21877 * Return: None
21878 */
21879void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21880 struct wireless_dev *wdev)
21881{
21882 vos_ssr_protect(__func__);
21883 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
21884 vos_ssr_unprotect(__func__);
21885
21886 return;
21887}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021888#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021889
Abhishek Singh936c6932017-11-07 17:28:23 +053021890#ifdef CHANNEL_SWITCH_SUPPORTED
21891/**
21892 * __wlan_hdd_cfg80211_channel_switch()- function to switch
21893 * channel in SAP/GO
21894 * @wiphy: wiphy pointer
21895 * @dev: dev pointer.
21896 * @csa_params: Change channel params
21897 *
21898 * This function is called to switch channel in SAP/GO
21899 *
21900 * Return: 0 if success else return non zero
21901 */
21902static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21903 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21904{
21905 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21906 hdd_context_t *hdd_ctx;
21907 uint8_t channel;
21908 int ret;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053021909 ptSapContext sap_ctx;
Abhishek Singh936c6932017-11-07 17:28:23 +053021910 v_CONTEXT_t vos_ctx;
21911
21912 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
21913
21914 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
21915 ret = wlan_hdd_validate_context(hdd_ctx);
21916 if (ret)
21917 return ret;
21918
21919 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
21920 if (!vos_ctx) {
21921 hddLog(LOGE, FL("Vos ctx is null"));
21922 return -EINVAL;
21923 }
21924
Abhishek Singh10e17cf2018-03-12 14:34:22 +053021925 if (WLAN_HDD_SOFTAP != adapter->device_mode)
Abhishek Singh936c6932017-11-07 17:28:23 +053021926 return -ENOTSUPP;
21927
Abhishek Singh10e17cf2018-03-12 14:34:22 +053021928 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
21929 if (!sap_ctx) {
21930 hddLog(LOGE, FL("sap_ctx is NULL"));
21931 return -EINVAL;
21932 }
21933
21934 ret = wlansap_chk_n_set_chan_change_in_progress(sap_ctx);
21935 if (ret)
21936 return ret;
21937
21938 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
21939
Abhishek Singh936c6932017-11-07 17:28:23 +053021940 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053021941 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053021942
Abhishek Singh10e17cf2018-03-12 14:34:22 +053021943 if (ret) {
21944 wlansap_reset_chan_change_in_progress(sap_ctx);
21945 complete(&sap_ctx->ecsa_info.chan_switch_comp);
21946 }
21947
Abhishek Singh936c6932017-11-07 17:28:23 +053021948 return ret;
21949}
21950
21951/**
21952 * wlan_hdd_cfg80211_channel_switch()- function to switch
21953 * channel in SAP/GO
21954 * @wiphy: wiphy pointer
21955 * @dev: dev pointer.
21956 * @csa_params: Change channel params
21957 *
21958 * This function is called to switch channel in SAP/GO
21959 *
21960 * Return: 0 if success else return non zero
21961 */
21962static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21963 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21964{
21965 int ret;
21966
21967 vos_ssr_protect(__func__);
21968 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
21969 vos_ssr_unprotect(__func__);
21970
21971 return ret;
21972}
21973#endif
21974
Jeff Johnson295189b2012-06-20 16:38:30 -070021975/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053021976static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070021977{
21978 .add_virtual_intf = wlan_hdd_add_virtual_intf,
21979 .del_virtual_intf = wlan_hdd_del_virtual_intf,
21980 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
21981 .change_station = wlan_hdd_change_station,
21982#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
21983 .add_beacon = wlan_hdd_cfg80211_add_beacon,
21984 .del_beacon = wlan_hdd_cfg80211_del_beacon,
21985 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021986#else
21987 .start_ap = wlan_hdd_cfg80211_start_ap,
21988 .change_beacon = wlan_hdd_cfg80211_change_beacon,
21989 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070021990#endif
21991 .change_bss = wlan_hdd_cfg80211_change_bss,
21992 .add_key = wlan_hdd_cfg80211_add_key,
21993 .get_key = wlan_hdd_cfg80211_get_key,
21994 .del_key = wlan_hdd_cfg80211_del_key,
21995 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021996#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070021997 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021998#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021999 .scan = wlan_hdd_cfg80211_scan,
22000 .connect = wlan_hdd_cfg80211_connect,
22001 .disconnect = wlan_hdd_cfg80211_disconnect,
22002 .join_ibss = wlan_hdd_cfg80211_join_ibss,
22003 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
22004 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
22005 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
22006 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070022007 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
22008 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053022009 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070022010#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
22011 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
22012 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
22013 .set_txq_params = wlan_hdd_set_txq_params,
22014#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022015 .get_station = wlan_hdd_cfg80211_get_station,
22016 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
22017 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022018 .add_station = wlan_hdd_cfg80211_add_station,
22019#ifdef FEATURE_WLAN_LFR
22020 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
22021 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
22022 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
22023#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070022024#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
22025 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
22026#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080022027#ifdef FEATURE_WLAN_TDLS
22028 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
22029 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
22030#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053022031#ifdef WLAN_FEATURE_GTK_OFFLOAD
22032 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
22033#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053022034#ifdef FEATURE_WLAN_SCAN_PNO
22035 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
22036 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
22037#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022038 .resume = wlan_hdd_cfg80211_resume_wlan,
22039 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053022040 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070022041#ifdef WLAN_NL80211_TESTMODE
22042 .testmode_cmd = wlan_hdd_cfg80211_testmode,
22043#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022044 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022045#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22046 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022047 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022048#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053022049#ifdef CHANNEL_SWITCH_SUPPORTED
22050 .channel_switch = wlan_hdd_cfg80211_channel_switch,
22051#endif
22052
Jeff Johnson295189b2012-06-20 16:38:30 -070022053};
22054