blob: 219608307420d045e8aa24ab33d4eca8d314ad85 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05302 * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053066#include <linux/etherdevice.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067#include <wlan_hdd_includes.h>
68#include <net/arp.h>
69#include <net/cfg80211.h>
70#include <linux/wireless.h>
71#include <wlan_hdd_wowl.h>
72#include <aniGlobal.h>
73#include "ccmApi.h"
74#include "sirParams.h"
75#include "dot11f.h"
76#include "wlan_hdd_assoc.h"
77#include "wlan_hdd_wext.h"
78#include "sme_Api.h"
79#include "wlan_hdd_p2p.h"
80#include "wlan_hdd_cfg80211.h"
81#include "wlan_hdd_hostapd.h"
82#include "sapInternal.h"
83#include "wlan_hdd_softap_tx_rx.h"
84#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053085#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053086#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053087#include "wlan_hdd_trace.h"
88#include "vos_types.h"
89#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070090#ifdef WLAN_BTAMP_FEATURE
91#include "bap_hdd_misc.h"
92#endif
93#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080094#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053095#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053096#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053097#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070098#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053099#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +0530100#include "wlan_logging_sock_svc.h"
Agrawal Ashishcfe83282016-09-29 13:03:45 +0530101#include "wlan_hdd_misc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530102
Jeff Johnson295189b2012-06-20 16:38:30 -0700103
104#define g_mode_rates_size (12)
105#define a_mode_rates_size (8)
106#define FREQ_BASE_80211G (2407)
107#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700108#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530109#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800111 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700112
113#define HDD2GHZCHAN(freq, chan, flag) { \
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530114 .band = HDD_NL80211_BAND_2GHZ, \
Jeff Johnson295189b2012-06-20 16:38:30 -0700115 .center_freq = (freq), \
116 .hw_value = (chan),\
117 .flags = (flag), \
118 .max_antenna_gain = 0 ,\
119 .max_power = 30, \
120}
121
122#define HDD5GHZCHAN(freq, chan, flag) { \
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530123 .band = HDD_NL80211_BAND_5GHZ, \
Jeff Johnson295189b2012-06-20 16:38:30 -0700124 .center_freq = (freq), \
125 .hw_value = (chan),\
126 .flags = (flag), \
127 .max_antenna_gain = 0 ,\
128 .max_power = 30, \
129}
130
131#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
132{\
133 .bitrate = rate, \
134 .hw_value = rate_id, \
135 .flags = flag, \
136}
137
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530138#ifdef WLAN_FEATURE_VOWIFI_11R
139#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
140#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
141#endif
142
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530143#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530144#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530145
Sunil Duttc69bccb2014-05-26 21:30:20 +0530146#ifdef WLAN_FEATURE_LINK_LAYER_STATS
147/*
148 * Used to allocate the size of 4096 for the link layer stats.
149 * The size of 4096 is considered assuming that all data per
150 * respective event fit with in the limit.Please take a call
151 * on the limit based on the data requirements on link layer
152 * statistics.
153 */
154#define LL_STATS_EVENT_BUF_SIZE 4096
155#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530156#ifdef WLAN_FEATURE_EXTSCAN
157/*
158 * Used to allocate the size of 4096 for the EXTScan NL data.
159 * The size of 4096 is considered assuming that all data per
160 * respective event fit with in the limit.Please take a call
161 * on the limit based on the data requirements.
162 */
163
164#define EXTSCAN_EVENT_BUF_SIZE 4096
165#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
166#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530167
Atul Mittal115287b2014-07-08 13:26:33 +0530168/*EXT TDLS*/
169/*
170 * Used to allocate the size of 4096 for the TDLS.
171 * The size of 4096 is considered assuming that all data per
172 * respective event fit with in the limit.Please take a call
173 * on the limit based on the data requirements on link layer
174 * statistics.
175 */
176#define EXTTDLS_EVENT_BUF_SIZE 4096
177
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530178/*
179 * Values for Mac spoofing feature
180 *
181 */
182#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
183#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
184#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530185#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
186
Anurag Chouhan343af7e2016-12-16 13:11:19 +0530187/*
188 * max_sched_scan_plans defined to 10
189 */
190#define MAX_SCHED_SCAN_PLANS 10
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530191
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530192static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700193{
194 WLAN_CIPHER_SUITE_WEP40,
195 WLAN_CIPHER_SUITE_WEP104,
196 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800197#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700198#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
199 WLAN_CIPHER_SUITE_KRK,
200 WLAN_CIPHER_SUITE_CCMP,
201#else
202 WLAN_CIPHER_SUITE_CCMP,
203#endif
204#ifdef FEATURE_WLAN_WAPI
205 WLAN_CIPHER_SUITE_SMS4,
206#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700207#ifdef WLAN_FEATURE_11W
208 WLAN_CIPHER_SUITE_AES_CMAC,
209#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700210};
211
Agrawal Ashish97dec502015-11-26 20:20:58 +0530212const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530213{
Jeff Johnson295189b2012-06-20 16:38:30 -0700214 HDD2GHZCHAN(2412, 1, 0) ,
215 HDD2GHZCHAN(2417, 2, 0) ,
216 HDD2GHZCHAN(2422, 3, 0) ,
217 HDD2GHZCHAN(2427, 4, 0) ,
218 HDD2GHZCHAN(2432, 5, 0) ,
219 HDD2GHZCHAN(2437, 6, 0) ,
220 HDD2GHZCHAN(2442, 7, 0) ,
221 HDD2GHZCHAN(2447, 8, 0) ,
222 HDD2GHZCHAN(2452, 9, 0) ,
223 HDD2GHZCHAN(2457, 10, 0) ,
224 HDD2GHZCHAN(2462, 11, 0) ,
225 HDD2GHZCHAN(2467, 12, 0) ,
226 HDD2GHZCHAN(2472, 13, 0) ,
227 HDD2GHZCHAN(2484, 14, 0) ,
228};
229
Agrawal Ashish97dec502015-11-26 20:20:58 +0530230const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700231{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700232 HDD5GHZCHAN(4920, 240, 0) ,
233 HDD5GHZCHAN(4940, 244, 0) ,
234 HDD5GHZCHAN(4960, 248, 0) ,
235 HDD5GHZCHAN(4980, 252, 0) ,
236 HDD5GHZCHAN(5040, 208, 0) ,
237 HDD5GHZCHAN(5060, 212, 0) ,
238 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 HDD5GHZCHAN(5180, 36, 0) ,
240 HDD5GHZCHAN(5200, 40, 0) ,
241 HDD5GHZCHAN(5220, 44, 0) ,
242 HDD5GHZCHAN(5240, 48, 0) ,
243 HDD5GHZCHAN(5260, 52, 0) ,
244 HDD5GHZCHAN(5280, 56, 0) ,
245 HDD5GHZCHAN(5300, 60, 0) ,
246 HDD5GHZCHAN(5320, 64, 0) ,
247 HDD5GHZCHAN(5500,100, 0) ,
248 HDD5GHZCHAN(5520,104, 0) ,
249 HDD5GHZCHAN(5540,108, 0) ,
250 HDD5GHZCHAN(5560,112, 0) ,
251 HDD5GHZCHAN(5580,116, 0) ,
252 HDD5GHZCHAN(5600,120, 0) ,
253 HDD5GHZCHAN(5620,124, 0) ,
254 HDD5GHZCHAN(5640,128, 0) ,
255 HDD5GHZCHAN(5660,132, 0) ,
256 HDD5GHZCHAN(5680,136, 0) ,
257 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800258#ifdef FEATURE_WLAN_CH144
259 HDD5GHZCHAN(5720,144, 0) ,
260#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 HDD5GHZCHAN(5745,149, 0) ,
262 HDD5GHZCHAN(5765,153, 0) ,
263 HDD5GHZCHAN(5785,157, 0) ,
264 HDD5GHZCHAN(5805,161, 0) ,
265 HDD5GHZCHAN(5825,165, 0) ,
266};
267
268static struct ieee80211_rate g_mode_rates[] =
269{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530270 HDD_G_MODE_RATETAB(10, 0x1, 0),
271 HDD_G_MODE_RATETAB(20, 0x2, 0),
272 HDD_G_MODE_RATETAB(55, 0x4, 0),
273 HDD_G_MODE_RATETAB(110, 0x8, 0),
274 HDD_G_MODE_RATETAB(60, 0x10, 0),
275 HDD_G_MODE_RATETAB(90, 0x20, 0),
276 HDD_G_MODE_RATETAB(120, 0x40, 0),
277 HDD_G_MODE_RATETAB(180, 0x80, 0),
278 HDD_G_MODE_RATETAB(240, 0x100, 0),
279 HDD_G_MODE_RATETAB(360, 0x200, 0),
280 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530282};
Jeff Johnson295189b2012-06-20 16:38:30 -0700283
284static struct ieee80211_rate a_mode_rates[] =
285{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530286 HDD_G_MODE_RATETAB(60, 0x10, 0),
287 HDD_G_MODE_RATETAB(90, 0x20, 0),
288 HDD_G_MODE_RATETAB(120, 0x40, 0),
289 HDD_G_MODE_RATETAB(180, 0x80, 0),
290 HDD_G_MODE_RATETAB(240, 0x100, 0),
291 HDD_G_MODE_RATETAB(360, 0x200, 0),
292 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 HDD_G_MODE_RATETAB(540, 0x800, 0),
294};
295
296static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
297{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530298 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700299 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530300 .band = HDD_NL80211_BAND_2GHZ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700301 .bitrates = g_mode_rates,
302 .n_bitrates = g_mode_rates_size,
303 .ht_cap.ht_supported = 1,
304 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
305 | IEEE80211_HT_CAP_GRN_FLD
306 | IEEE80211_HT_CAP_DSSSCCK40
307 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
308 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
309 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
310 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
311 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
312 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
313};
314
Jeff Johnson295189b2012-06-20 16:38:30 -0700315static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
316{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530317 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700318 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530319 .band = HDD_NL80211_BAND_5GHZ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700320 .bitrates = a_mode_rates,
321 .n_bitrates = a_mode_rates_size,
322 .ht_cap.ht_supported = 1,
323 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
324 | IEEE80211_HT_CAP_GRN_FLD
325 | IEEE80211_HT_CAP_DSSSCCK40
326 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
327 | IEEE80211_HT_CAP_SGI_40
328 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
329 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
330 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
331 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
332 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
333 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
334};
335
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530336/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700337 TX/RX direction for each kind of interface */
338static const struct ieee80211_txrx_stypes
339wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
340 [NL80211_IFTYPE_STATION] = {
341 .tx = 0xffff,
342 .rx = BIT(SIR_MAC_MGMT_ACTION) |
343 BIT(SIR_MAC_MGMT_PROBE_REQ),
344 },
345 [NL80211_IFTYPE_AP] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
348 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
349 BIT(SIR_MAC_MGMT_PROBE_REQ) |
350 BIT(SIR_MAC_MGMT_DISASSOC) |
351 BIT(SIR_MAC_MGMT_AUTH) |
352 BIT(SIR_MAC_MGMT_DEAUTH) |
353 BIT(SIR_MAC_MGMT_ACTION),
354 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700355 [NL80211_IFTYPE_ADHOC] = {
356 .tx = 0xffff,
357 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
358 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
359 BIT(SIR_MAC_MGMT_PROBE_REQ) |
360 BIT(SIR_MAC_MGMT_DISASSOC) |
361 BIT(SIR_MAC_MGMT_AUTH) |
362 BIT(SIR_MAC_MGMT_DEAUTH) |
363 BIT(SIR_MAC_MGMT_ACTION),
364 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700365 [NL80211_IFTYPE_P2P_CLIENT] = {
366 .tx = 0xffff,
367 .rx = BIT(SIR_MAC_MGMT_ACTION) |
368 BIT(SIR_MAC_MGMT_PROBE_REQ),
369 },
370 [NL80211_IFTYPE_P2P_GO] = {
371 /* This is also same as for SoftAP */
372 .tx = 0xffff,
373 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
374 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
375 BIT(SIR_MAC_MGMT_PROBE_REQ) |
376 BIT(SIR_MAC_MGMT_DISASSOC) |
377 BIT(SIR_MAC_MGMT_AUTH) |
378 BIT(SIR_MAC_MGMT_DEAUTH) |
379 BIT(SIR_MAC_MGMT_ACTION),
380 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700381};
382
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800383#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800384static const struct ieee80211_iface_limit
385wlan_hdd_iface_limit[] = {
386 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800387 /* max = 3 ; Our driver create two interfaces during driver init
388 * wlan0 and p2p0 interfaces. p2p0 is considered as station
389 * interface until a group is formed. In JB architecture, once the
390 * group is formed, interface type of p2p0 is changed to P2P GO or
391 * Client.
392 * When supplicant remove the group, it first issue a set interface
393 * cmd to change the mode back to Station. In JB this works fine as
394 * we advertize two station type interface during driver init.
395 * Some vendors create separate interface for P2P GO/Client,
396 * after group formation(Third one). But while group remove
397 * supplicant first tries to change the mode(3rd interface) to STATION
398 * But as we advertized only two sta type interfaces nl80211 was
399 * returning error for the third one which was leading to failure in
400 * delete interface. Ideally while removing the group, supplicant
401 * should not try to change the 3rd interface mode to Station type.
402 * Till we get a fix in wpa_supplicant, we advertize max STA
403 * interface type to 3
404 */
405 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800406 .types = BIT(NL80211_IFTYPE_STATION),
407 },
408 {
409 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700410 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 },
412 {
413 .max = 1,
414 .types = BIT(NL80211_IFTYPE_P2P_GO) |
415 BIT(NL80211_IFTYPE_P2P_CLIENT),
416 },
417};
418
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530419/* interface limits for sta + monitor SCC */
420static const struct ieee80211_iface_limit
421wlan_hdd_iface_sta_mon_limit[] = {
422 {
423 .max = 1,
424 .types = BIT(NL80211_IFTYPE_STATION),
425 },
426 {
427 .max = 1, /* Monitor interface */
428 .types = BIT(NL80211_IFTYPE_MONITOR),
429 },
430};
431
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800432/* By default, only single channel concurrency is allowed */
433static struct ieee80211_iface_combination
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530434wlan_hdd_iface_combination[] = {
435 {
436 .limits = wlan_hdd_iface_limit,
437 .num_different_channels = 1,
438 /*
439 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
440 * and p2p0 interfaces during driver init
441 * Some vendors create separate interface for P2P operations.
442 * wlan0: STA interface
443 * p2p0: P2P Device interface, action frames goes
444 * through this interface.
445 * p2p-xx: P2P interface, After GO negotiation this interface is
446 * created for p2p operations(GO/CLIENT interface).
447 */
448 .max_interfaces = WLAN_MAX_INTERFACES,
449 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
450 .beacon_int_infra_match = false,
451 },
452 {
453 .limits = wlan_hdd_iface_sta_mon_limit,
454 .num_different_channels = 1,
455 .max_interfaces = WLAN_STA_AND_MON_INTERFACES,
456 .n_limits = ARRAY_SIZE(wlan_hdd_iface_sta_mon_limit),
457 .beacon_int_infra_match = false,
458 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800459};
460#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800461
Nachiket Kukade5b2e7332018-04-06 14:40:22 +0530462#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
463static const struct wiphy_wowlan_support wowlan_support_cfg80211_init = {
464 .flags = WIPHY_WOWLAN_MAGIC_PKT,
465 .n_patterns = WOWL_MAX_PTRNS_ALLOWED,
466 .pattern_min_len = 1,
467 .pattern_max_len = WOWL_PTRN_MAX_SIZE,
468};
469#endif
470
Jeff Johnson295189b2012-06-20 16:38:30 -0700471static struct cfg80211_ops wlan_hdd_cfg80211_ops;
472
473/* Data rate 100KBPS based on IE Index */
474struct index_data_rate_type
475{
476 v_U8_t beacon_rate_index;
477 v_U16_t supported_rate[4];
478};
479
480/* 11B, 11G Rate table include Basic rate and Extended rate
481 The IDX field is the rate index
482 The HI field is the rate when RSSI is strong or being ignored
483 (in this case we report actual rate)
484 The MID field is the rate when RSSI is moderate
485 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
486 The LO field is the rate when RSSI is low
487 (in this case we don't report rates, actual current rate used)
488 */
489static const struct
490{
491 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700492 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700493} supported_data_rate[] =
494{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700495/* IDX HI HM LM LO (RSSI-based index */
496 {2, { 10, 10, 10, 0}},
497 {4, { 20, 20, 10, 0}},
498 {11, { 55, 20, 10, 0}},
499 {12, { 60, 55, 20, 0}},
500 {18, { 90, 55, 20, 0}},
501 {22, {110, 55, 20, 0}},
502 {24, {120, 90, 60, 0}},
503 {36, {180, 120, 60, 0}},
504 {44, {220, 180, 60, 0}},
505 {48, {240, 180, 90, 0}},
506 {66, {330, 180, 90, 0}},
507 {72, {360, 240, 90, 0}},
508 {96, {480, 240, 120, 0}},
509 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700510};
511
512/* MCS Based rate table */
513static struct index_data_rate_type supported_mcs_rate[] =
514{
515/* MCS L20 L40 S20 S40 */
516 {0, {65, 135, 72, 150}},
517 {1, {130, 270, 144, 300}},
518 {2, {195, 405, 217, 450}},
519 {3, {260, 540, 289, 600}},
520 {4, {390, 810, 433, 900}},
521 {5, {520, 1080, 578, 1200}},
522 {6, {585, 1215, 650, 1350}},
523 {7, {650, 1350, 722, 1500}}
524};
525
Leo Chang6f8870f2013-03-26 18:11:36 -0700526#ifdef WLAN_FEATURE_11AC
527
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530528#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700529
530struct index_vht_data_rate_type
531{
532 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530533 v_U16_t supported_VHT80_rate[2];
534 v_U16_t supported_VHT40_rate[2];
535 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700536};
537
538typedef enum
539{
540 DATA_RATE_11AC_MAX_MCS_7,
541 DATA_RATE_11AC_MAX_MCS_8,
542 DATA_RATE_11AC_MAX_MCS_9,
543 DATA_RATE_11AC_MAX_MCS_NA
544} eDataRate11ACMaxMcs;
545
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530546/* SSID broadcast type */
547typedef enum eSSIDBcastType
548{
549 eBCAST_UNKNOWN = 0,
550 eBCAST_NORMAL = 1,
551 eBCAST_HIDDEN = 2,
552} tSSIDBcastType;
553
Leo Chang6f8870f2013-03-26 18:11:36 -0700554/* MCS Based VHT rate table */
555static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
556{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530557/* MCS L80 S80 L40 S40 L20 S40*/
558 {0, {293, 325}, {135, 150}, {65, 72}},
559 {1, {585, 650}, {270, 300}, {130, 144}},
560 {2, {878, 975}, {405, 450}, {195, 217}},
561 {3, {1170, 1300}, {540, 600}, {260, 289}},
562 {4, {1755, 1950}, {810, 900}, {390, 433}},
563 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
564 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
565 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
566 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
567 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700568};
569#endif /* WLAN_FEATURE_11AC */
570
c_hpothu79aab322014-07-14 21:11:01 +0530571/*array index points to MCS and array value points respective rssi*/
572static int rssiMcsTbl[][10] =
573{
574/*MCS 0 1 2 3 4 5 6 7 8 9*/
575 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
576 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
577 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
578};
579
Jeff Johnson295189b2012-06-20 16:38:30 -0700580extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530581#ifdef FEATURE_WLAN_SCAN_PNO
582static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
583#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700584
Leo Chang9056f462013-08-01 19:21:11 -0700585#ifdef WLAN_NL80211_TESTMODE
586enum wlan_hdd_tm_attr
587{
588 WLAN_HDD_TM_ATTR_INVALID = 0,
589 WLAN_HDD_TM_ATTR_CMD = 1,
590 WLAN_HDD_TM_ATTR_DATA = 2,
591 WLAN_HDD_TM_ATTR_TYPE = 3,
592 /* keep last */
593 WLAN_HDD_TM_ATTR_AFTER_LAST,
594 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
595};
596
597enum wlan_hdd_tm_cmd
598{
599 WLAN_HDD_TM_CMD_WLAN_HB = 1,
600};
601
602#define WLAN_HDD_TM_DATA_MAX_LEN 5000
603
604static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
605{
606 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
607 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
608 .len = WLAN_HDD_TM_DATA_MAX_LEN },
609};
610#endif /* WLAN_NL80211_TESTMODE */
611
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800612#ifdef FEATURE_WLAN_CH_AVOID
613/*
614 * FUNCTION: wlan_hdd_send_avoid_freq_event
615 * This is called when wlan driver needs to send vendor specific
616 * avoid frequency range event to userspace
617 */
618int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
619 tHddAvoidFreqList *pAvoidFreqList)
620{
621 struct sk_buff *vendor_event;
622
623 ENTER();
624
625 if (!pHddCtx)
626 {
627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
628 "%s: HDD context is null", __func__);
629 return -1;
630 }
631
632 if (!pAvoidFreqList)
633 {
634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
635 "%s: pAvoidFreqList is null", __func__);
636 return -1;
637 }
638
639 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530640#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
641 NULL,
642#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800643 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530644 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800645 GFP_KERNEL);
646 if (!vendor_event)
647 {
648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
649 "%s: cfg80211_vendor_event_alloc failed", __func__);
650 return -1;
651 }
652
653 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
654 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
655
656 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
657
658 EXIT();
659 return 0;
660}
661#endif /* FEATURE_WLAN_CH_AVOID */
662
Srinivas Dasari030bad32015-02-18 23:23:54 +0530663/*
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +0530664 * define short names for the global vendor params
665 * used by QCA_NL80211_VENDOR_SUBCMD_HANG
666 */
667#define HANG_REASON_INDEX QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX
668
669/**
670 * hdd_convert_hang_reason() - Convert cds recovery reason to vendor specific
671 * hang reason
672 * @reason: cds recovery reason
673 *
674 * Return: Vendor specific reason code
675 */
676static enum qca_wlan_vendor_hang_reason
677hdd_convert_hang_reason(enum vos_hang_reason reason)
678{
679 unsigned int ret_val;
680
681 switch (reason) {
682 case VOS_GET_MSG_BUFF_FAILURE:
683 ret_val = QCA_WLAN_HANG_GET_MSG_BUFF_FAILURE;
684 break;
685 case VOS_ACTIVE_LIST_TIMEOUT:
686 ret_val = QCA_WLAN_HANG_ACTIVE_LIST_TIMEOUT;
687 break;
688 case VOS_SCAN_REQ_EXPIRED:
689 ret_val = QCA_WLAN_HANG_SCAN_REQ_EXPIRED;
690 break;
691 case VOS_TRANSMISSIONS_TIMEOUT:
692 ret_val = QCA_WLAN_HANG_TRANSMISSIONS_TIMEOUT;
693 break;
694 case VOS_DXE_FAILURE:
695 ret_val = QCA_WLAN_HANG_DXE_FAILURE;
696 break;
697 case VOS_WDI_FAILURE:
698 ret_val = QCA_WLAN_HANG_WDI_FAILURE;
699 break;
700 case VOS_REASON_UNSPECIFIED:
701 default:
702 ret_val = QCA_WLAN_HANG_REASON_UNSPECIFIED;
703 }
704 return ret_val;
705}
706
707/**
708 * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace
709 * @hdd_ctx: Pointer to hdd context
710 * @reason: cds recovery reason
711 *
712 * Return: 0 on success or failure reason
713 */
714int wlan_hdd_send_hang_reason_event(hdd_context_t *hdd_ctx,
715 enum vos_hang_reason reason)
716{
717 struct sk_buff *vendor_event;
718 enum qca_wlan_vendor_hang_reason hang_reason;
719
720 ENTER();
721
722 if (!hdd_ctx) {
723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
724 "HDD context is null");
725 return -EINVAL;
726 }
727
728 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
729#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
730 NULL,
731#endif
732 sizeof(unsigned int),
733 HANG_REASON_INDEX,
734 GFP_KERNEL);
735 if (!vendor_event) {
736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
737 "cfg80211_vendor_event_alloc failed");
738 return -ENOMEM;
739 }
740
741 hang_reason = hdd_convert_hang_reason(reason);
742
743 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_HANG_REASON,
744 (unsigned int) hang_reason)) {
745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
746 "QCA_WLAN_VENDOR_ATTR_HANG_REASON put fail");
747 kfree_skb(vendor_event);
748 return -EINVAL;
749 }
750
751 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
752
753 EXIT();
754 return 0;
755}
756#undef HANG_REASON_INDEX
757
758/*
Srinivas Dasari030bad32015-02-18 23:23:54 +0530759 * FUNCTION: __wlan_hdd_cfg80211_nan_request
760 * This is called when wlan driver needs to send vendor specific
761 * nan request event.
762 */
763static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
764 struct wireless_dev *wdev,
765 const void *data, int data_len)
766{
767 tNanRequestReq nan_req;
768 VOS_STATUS status;
769 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530770 struct net_device *dev = wdev->netdev;
771 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
772 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530773 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
774
775 if (0 == data_len)
776 {
777 hddLog(VOS_TRACE_LEVEL_ERROR,
778 FL("NAN - Invalid Request, length = 0"));
779 return ret_val;
780 }
781
782 if (NULL == data)
783 {
784 hddLog(VOS_TRACE_LEVEL_ERROR,
785 FL("NAN - Invalid Request, data is NULL"));
786 return ret_val;
787 }
788
789 status = wlan_hdd_validate_context(pHddCtx);
790 if (0 != status)
791 {
792 hddLog(VOS_TRACE_LEVEL_ERROR,
793 FL("HDD context is not valid"));
794 return -EINVAL;
795 }
796
797 hddLog(LOG1, FL("Received NAN command"));
798 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
799 (tANI_U8 *)data, data_len);
800
801 /* check the NAN Capability */
802 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
803 {
804 hddLog(VOS_TRACE_LEVEL_ERROR,
805 FL("NAN is not supported by Firmware"));
806 return -EINVAL;
807 }
808
809 nan_req.request_data_len = data_len;
810 nan_req.request_data = data;
811
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530812 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530813 if (VOS_STATUS_SUCCESS == status)
814 {
815 ret_val = 0;
816 }
817 return ret_val;
818}
819
820/*
821 * FUNCTION: wlan_hdd_cfg80211_nan_request
822 * Wrapper to protect the nan vendor command from ssr
823 */
824static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
825 struct wireless_dev *wdev,
826 const void *data, int data_len)
827{
828 int ret;
829
830 vos_ssr_protect(__func__);
831 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
832 vos_ssr_unprotect(__func__);
833
834 return ret;
835}
836
837/*
838 * FUNCTION: wlan_hdd_cfg80211_nan_callback
839 * This is a callback function and it gets called
840 * when we need to report nan response event to
841 * upper layers.
842 */
843static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
844{
845 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
846 struct sk_buff *vendor_event;
847 int status;
848 tSirNanEvent *data;
849
850 ENTER();
851 if (NULL == msg)
852 {
853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
854 FL(" msg received here is null"));
855 return;
856 }
857 data = msg;
858
859 status = wlan_hdd_validate_context(pHddCtx);
860
861 if (0 != status)
862 {
863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
864 FL("HDD context is not valid"));
865 return;
866 }
867
868 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530869#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
870 NULL,
871#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530872 data->event_data_len +
873 NLMSG_HDRLEN,
874 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
875 GFP_KERNEL);
876
877 if (!vendor_event)
878 {
879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
880 FL("cfg80211_vendor_event_alloc failed"));
881 return;
882 }
883 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
884 data->event_data_len, data->event_data))
885 {
886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
887 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
888 kfree_skb(vendor_event);
889 return;
890 }
891 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
892 EXIT();
893}
894
895/*
896 * FUNCTION: wlan_hdd_cfg80211_nan_init
897 * This function is called to register the callback to sme layer
898 */
899inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
900{
901 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
902}
903
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530904/*
905 * define short names for the global vendor params
906 * used by __wlan_hdd_cfg80211_get_station_cmd()
907 */
908#define STATION_INVALID \
909 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
910#define STATION_INFO \
911 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
912#define STATION_ASSOC_FAIL_REASON \
913 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +0530914#define STATION_REMOTE \
915 QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530916#define STATION_MAX \
917 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
918
919static const struct nla_policy
920hdd_get_station_policy[STATION_MAX + 1] = {
921 [STATION_INFO] = {.type = NLA_FLAG},
922 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
923};
924
925/**
926 * hdd_get_station_assoc_fail() - Handle get station assoc fail
927 * @hdd_ctx: HDD context within host driver
928 * @wdev: wireless device
929 *
930 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
931 * Validate cmd attributes and send the station info to upper layers.
932 *
933 * Return: Success(0) or reason code for failure
934 */
935static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
936 hdd_adapter_t *adapter)
937{
938 struct sk_buff *skb = NULL;
939 uint32_t nl_buf_len;
940 hdd_station_ctx_t *hdd_sta_ctx;
941
942 nl_buf_len = NLMSG_HDRLEN;
943 nl_buf_len += sizeof(uint32_t);
944 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
945
946 if (!skb) {
947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
948 return -ENOMEM;
949 }
950
951 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
952
953 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
954 hdd_sta_ctx->conn_info.assoc_status_code)) {
955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
956 goto fail;
957 }
958 return cfg80211_vendor_cmd_reply(skb);
959fail:
960 if (skb)
961 kfree_skb(skb);
962 return -EINVAL;
963}
964
965/**
966 * hdd_map_auth_type() - transform auth type specific to
967 * vendor command
968 * @auth_type: csr auth type
969 *
970 * Return: Success(0) or reason code for failure
971 */
972static int hdd_convert_auth_type(uint32_t auth_type)
973{
974 uint32_t ret_val;
975
976 switch (auth_type) {
977 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
978 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
979 break;
980 case eCSR_AUTH_TYPE_SHARED_KEY:
981 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
982 break;
983 case eCSR_AUTH_TYPE_WPA:
984 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
985 break;
986 case eCSR_AUTH_TYPE_WPA_PSK:
987 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
988 break;
989 case eCSR_AUTH_TYPE_AUTOSWITCH:
990 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
991 break;
992 case eCSR_AUTH_TYPE_WPA_NONE:
993 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
994 break;
995 case eCSR_AUTH_TYPE_RSN:
996 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
997 break;
998 case eCSR_AUTH_TYPE_RSN_PSK:
999 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
1000 break;
1001 case eCSR_AUTH_TYPE_FT_RSN:
1002 ret_val = QCA_WLAN_AUTH_TYPE_FT;
1003 break;
1004 case eCSR_AUTH_TYPE_FT_RSN_PSK:
1005 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
1006 break;
1007 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
1008 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
1009 break;
1010 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
1011 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
1012 break;
1013#ifdef FEATURE_WLAN_ESE
1014 case eCSR_AUTH_TYPE_CCKM_WPA:
1015 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
1016 break;
1017 case eCSR_AUTH_TYPE_CCKM_RSN:
1018 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
1019 break;
1020#endif
1021 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
1022 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
1023 break;
1024 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
1025 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
1026 break;
1027 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
1028 case eCSR_AUTH_TYPE_FAILED:
1029 case eCSR_AUTH_TYPE_NONE:
1030 default:
1031 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
1032 break;
1033 }
1034 return ret_val;
1035}
1036
1037/**
1038 * hdd_map_dot_11_mode() - transform dot11mode type specific to
1039 * vendor command
1040 * @dot11mode: dot11mode
1041 *
1042 * Return: Success(0) or reason code for failure
1043 */
1044static int hdd_convert_dot11mode(uint32_t dot11mode)
1045{
1046 uint32_t ret_val;
1047
1048 switch (dot11mode) {
1049 case eCSR_CFG_DOT11_MODE_11A:
1050 ret_val = QCA_WLAN_802_11_MODE_11A;
1051 break;
1052 case eCSR_CFG_DOT11_MODE_11B:
1053 ret_val = QCA_WLAN_802_11_MODE_11B;
1054 break;
1055 case eCSR_CFG_DOT11_MODE_11G:
1056 ret_val = QCA_WLAN_802_11_MODE_11G;
1057 break;
1058 case eCSR_CFG_DOT11_MODE_11N:
1059 ret_val = QCA_WLAN_802_11_MODE_11N;
1060 break;
1061 case eCSR_CFG_DOT11_MODE_11AC:
1062 ret_val = QCA_WLAN_802_11_MODE_11AC;
1063 break;
1064 case eCSR_CFG_DOT11_MODE_AUTO:
1065 case eCSR_CFG_DOT11_MODE_ABG:
1066 default:
1067 ret_val = QCA_WLAN_802_11_MODE_INVALID;
1068 }
1069 return ret_val;
1070}
1071
1072/**
1073 * hdd_add_tx_bitrate() - add tx bitrate attribute
1074 * @skb: pointer to sk buff
1075 * @hdd_sta_ctx: pointer to hdd station context
1076 * @idx: attribute index
1077 *
1078 * Return: Success(0) or reason code for failure
1079 */
1080static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
1081 hdd_station_ctx_t *hdd_sta_ctx,
1082 int idx)
1083{
1084 struct nlattr *nla_attr;
1085 uint32_t bitrate, bitrate_compat;
1086
1087 nla_attr = nla_nest_start(skb, idx);
1088 if (!nla_attr)
1089 goto fail;
1090 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301091 bitrate = cfg80211_calculate_bitrate(
1092 &hdd_sta_ctx->cache_conn_info.txrate);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301093
1094 /* report 16-bit bitrate only if we can */
1095 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
1096 if (bitrate > 0 &&
1097 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
1098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1099 goto fail;
1100 }
1101 if (bitrate_compat > 0 &&
1102 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
1103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1104 goto fail;
1105 }
1106 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301107 hdd_sta_ctx->cache_conn_info.txrate.nss)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1109 goto fail;
1110 }
1111 nla_nest_end(skb, nla_attr);
1112 return 0;
1113fail:
1114 return -EINVAL;
1115}
1116
1117/**
1118 * hdd_add_sta_info() - add station info attribute
1119 * @skb: pointer to sk buff
1120 * @hdd_sta_ctx: pointer to hdd station context
1121 * @idx: attribute index
1122 *
1123 * Return: Success(0) or reason code for failure
1124 */
1125static int32_t hdd_add_sta_info(struct sk_buff *skb,
1126 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1127{
1128 struct nlattr *nla_attr;
1129
1130 nla_attr = nla_nest_start(skb, idx);
1131 if (!nla_attr)
1132 goto fail;
1133 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301134 (hdd_sta_ctx->cache_conn_info.signal + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1136 goto fail;
1137 }
1138 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1139 goto fail;
1140 nla_nest_end(skb, nla_attr);
1141 return 0;
1142fail:
1143 return -EINVAL;
1144}
1145
1146/**
1147 * hdd_add_survey_info() - add survey info attribute
1148 * @skb: pointer to sk buff
1149 * @hdd_sta_ctx: pointer to hdd station context
1150 * @idx: attribute index
1151 *
1152 * Return: Success(0) or reason code for failure
1153 */
1154static int32_t hdd_add_survey_info(struct sk_buff *skb,
1155 hdd_station_ctx_t *hdd_sta_ctx,
1156 int idx)
1157{
1158 struct nlattr *nla_attr;
1159
1160 nla_attr = nla_nest_start(skb, idx);
1161 if (!nla_attr)
1162 goto fail;
1163 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301164 hdd_sta_ctx->cache_conn_info.freq) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301165 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301166 (hdd_sta_ctx->cache_conn_info.noise + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301167 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1168 goto fail;
1169 }
1170 nla_nest_end(skb, nla_attr);
1171 return 0;
1172fail:
1173 return -EINVAL;
1174}
1175
1176/**
1177 * hdd_add_link_standard_info() - add link info attribute
1178 * @skb: pointer to sk buff
1179 * @hdd_sta_ctx: pointer to hdd station context
1180 * @idx: attribute index
1181 *
1182 * Return: Success(0) or reason code for failure
1183 */
1184static int32_t
1185hdd_add_link_standard_info(struct sk_buff *skb,
1186 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1187{
1188 struct nlattr *nla_attr;
1189
1190 nla_attr = nla_nest_start(skb, idx);
1191 if (!nla_attr)
1192 goto fail;
1193 if (nla_put(skb,
1194 NL80211_ATTR_SSID,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301195 hdd_sta_ctx->cache_conn_info.SSID.SSID.length,
1196 hdd_sta_ctx->cache_conn_info.SSID.SSID.ssId)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1198 goto fail;
1199 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301200 if (nla_put(skb, NL80211_ATTR_MAC, VOS_MAC_ADDR_SIZE,
1201 hdd_sta_ctx->cache_conn_info.bssId))
1202 goto fail;
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301203 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1204 goto fail;
1205 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1206 goto fail;
1207 nla_nest_end(skb, nla_attr);
1208 return 0;
1209fail:
1210 return -EINVAL;
1211}
1212
1213/**
1214 * hdd_add_ap_standard_info() - add ap info attribute
1215 * @skb: pointer to sk buff
1216 * @hdd_sta_ctx: pointer to hdd station context
1217 * @idx: attribute index
1218 *
1219 * Return: Success(0) or reason code for failure
1220 */
1221static int32_t
1222hdd_add_ap_standard_info(struct sk_buff *skb,
1223 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1224{
1225 struct nlattr *nla_attr;
1226
1227 nla_attr = nla_nest_start(skb, idx);
1228 if (!nla_attr)
1229 goto fail;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301230 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301231 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301232 sizeof(hdd_sta_ctx->cache_conn_info.vht_caps),
1233 &hdd_sta_ctx->cache_conn_info.vht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301234 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1235 goto fail;
1236 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301237 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301238 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301239 sizeof(hdd_sta_ctx->cache_conn_info.ht_caps),
1240 &hdd_sta_ctx->cache_conn_info.ht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301241 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1242 goto fail;
1243 }
1244 nla_nest_end(skb, nla_attr);
1245 return 0;
1246fail:
1247 return -EINVAL;
1248}
1249
1250/**
1251 * hdd_get_station_info() - send BSS information to supplicant
1252 * @hdd_ctx: pointer to hdd context
1253 * @adapter: pointer to adapter
1254 *
1255 * Return: 0 if success else error status
1256 */
1257static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1258 hdd_adapter_t *adapter)
1259{
1260 struct sk_buff *skb = NULL;
1261 uint8_t *tmp_hs20 = NULL;
1262 uint32_t nl_buf_len;
1263 hdd_station_ctx_t *hdd_sta_ctx;
1264
1265 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1266
1267 nl_buf_len = NLMSG_HDRLEN;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301268
1269 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.SSID.SSID.length) +
1270 VOS_MAC_ADDR_SIZE +
1271 sizeof(hdd_sta_ctx->cache_conn_info.freq) +
1272 sizeof(hdd_sta_ctx->cache_conn_info.noise) +
1273 sizeof(hdd_sta_ctx->cache_conn_info.signal) +
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301274 (sizeof(uint32_t) * 2) +
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301275 sizeof(hdd_sta_ctx->cache_conn_info.txrate.nss) +
1276 sizeof(hdd_sta_ctx->cache_conn_info.roam_count) +
1277 sizeof(hdd_sta_ctx->cache_conn_info.authType) +
1278 sizeof(hdd_sta_ctx->cache_conn_info.dot11Mode);
1279 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
1280 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.vht_caps);
1281 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
1282 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_caps);
1283 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) {
1284 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->
1285 cache_conn_info.hs20vendor_ie);
1286 nl_buf_len +=
1287 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie) -
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301288 1);
1289 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301290 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
1291 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_operation);
1292 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
1293 nl_buf_len +=
1294 sizeof(hdd_sta_ctx->cache_conn_info.vht_operation);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301295
1296
1297 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1298 if (!skb) {
1299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1300 __func__, __LINE__);
1301 return -ENOMEM;
1302 }
1303
1304 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1305 LINK_INFO_STANDARD_NL80211_ATTR)) {
1306 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1307 goto fail;
1308 }
1309 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1310 AP_INFO_STANDARD_NL80211_ATTR)) {
1311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1312 goto fail;
1313 }
1314 if (nla_put_u32(skb, INFO_ROAM_COUNT,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301315 hdd_sta_ctx->cache_conn_info.roam_count) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301316 nla_put_u32(skb, INFO_AKM,
1317 hdd_convert_auth_type(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301318 hdd_sta_ctx->cache_conn_info.authType)) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301319 nla_put_u32(skb, WLAN802_11_MODE,
1320 hdd_convert_dot11mode(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301321 hdd_sta_ctx->cache_conn_info.dot11Mode))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1323 goto fail;
1324 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301325 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301326 if (nla_put(skb, HT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301327 (sizeof(hdd_sta_ctx->cache_conn_info.ht_operation)),
1328 &hdd_sta_ctx->cache_conn_info.ht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1330 goto fail;
1331 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301332 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301333 if (nla_put(skb, VHT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301334 (sizeof(hdd_sta_ctx->
1335 cache_conn_info.vht_operation)),
1336 &hdd_sta_ctx->cache_conn_info.vht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1338 goto fail;
1339 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301340 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301341 if (nla_put(skb, AP_INFO_HS20_INDICATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301342 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie)
1343 - 1), tmp_hs20 + 1)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1345 goto fail;
1346 }
1347
1348 return cfg80211_vendor_cmd_reply(skb);
1349fail:
1350 if (skb)
1351 kfree_skb(skb);
1352 return -EINVAL;
1353}
1354
1355/**
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301356 * hdd_add_survey_info_sap_get_len - get data length used in
1357 * hdd_add_survey_info_sap()
1358 *
1359 * This function calculates the data length used in hdd_add_survey_info_sap()
1360 *
1361 * Return: total data length used in hdd_add_survey_info_sap()
1362 */
1363static uint32_t hdd_add_survey_info_sap_get_len(void)
1364{
1365 return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
1366}
1367
1368/**
1369 * hdd_add_survey_info - add survey info attribute
1370 * @skb: pointer to response skb buffer
1371 * @stainfo: station information
1372 * @idx: attribute type index for nla_next_start()
1373 *
1374 * This function adds survey info attribute to response skb buffer
1375 *
1376 * Return : 0 on success and errno on failure
1377 */
1378static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
1379 struct hdd_cache_sta_info *stainfo,
1380 int idx)
1381{
1382 struct nlattr *nla_attr;
1383
1384 nla_attr = nla_nest_start(skb, idx);
1385 if (!nla_attr)
1386 goto fail;
1387 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1388 stainfo->freq)) {
1389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1390 FL("put fail"));
1391 goto fail;
1392 }
1393 nla_nest_end(skb, nla_attr);
1394 return 0;
1395fail:
1396 return -EINVAL;
1397}
1398
1399/**
1400 * hdd_add_tx_bitrate_sap_get_len - get data length used in
1401 * hdd_add_tx_bitrate_sap()
1402 *
1403 * This function calculates the data length used in hdd_add_tx_bitrate_sap()
1404 *
1405 * Return: total data length used in hdd_add_tx_bitrate_sap()
1406 */
1407static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
1408{
1409 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
1410}
1411
1412/**
1413 * hdd_add_tx_bitrate_sap - add vht nss info attribute
1414 * @skb: pointer to response skb buffer
1415 * @stainfo: station information
1416 * @idx: attribute type index for nla_next_start()
1417 *
1418 * This function adds vht nss attribute to response skb buffer
1419 *
1420 * Return : 0 on success and errno on failure
1421 */
1422static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
1423 struct hdd_cache_sta_info *stainfo,
1424 int idx)
1425{
1426 struct nlattr *nla_attr;
1427
1428 nla_attr = nla_nest_start(skb, idx);
1429 if (!nla_attr)
1430 goto fail;
1431
1432 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1433 stainfo->nss)) {
1434 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1435 FL("put fail"));
1436 goto fail;
1437 }
1438 nla_nest_end(skb, nla_attr);
1439 return 0;
1440fail:
1441 return -EINVAL;
1442}
1443
1444/**
1445 * hdd_add_sta_info_sap_get_len - get data length used in
1446 * hdd_add_sta_info_sap()
1447 *
1448 * This function calculates the data length used in hdd_add_sta_info_sap()
1449 *
1450 * Return: total data length used in hdd_add_sta_info_sap()
1451 */
1452static uint32_t hdd_add_sta_info_sap_get_len(void)
1453{
1454 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
1455 hdd_add_tx_bitrate_sap_get_len());
1456}
1457
1458/**
1459 * hdd_add_sta_info_sap - add sta signal info attribute
1460 * @skb: pointer to response skb buffer
1461 * @rssi: peer rssi value
1462 * @stainfo: station information
1463 * @idx: attribute type index for nla_next_start()
1464 *
1465 * This function adds sta signal attribute to response skb buffer
1466 *
1467 * Return : 0 on success and errno on failure
1468 */
1469static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
1470 struct hdd_cache_sta_info *stainfo, int idx)
1471{
1472 struct nlattr *nla_attr;
1473
1474 nla_attr = nla_nest_start(skb, idx);
1475 if (!nla_attr)
1476 goto fail;
1477
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05301478 /* upperlayer expects positive rssi value */
1479 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, (rssi + 96))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1481 FL("put fail"));
1482 goto fail;
1483 }
1484 if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE)) {
1485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1486 FL("put fail"));
1487 goto fail;
1488 }
1489
1490 nla_nest_end(skb, nla_attr);
1491 return 0;
1492fail:
1493 return -EINVAL;
1494}
1495
1496/**
1497 * hdd_add_link_standard_info_sap_get_len - get data length used in
1498 * hdd_add_link_standard_info_sap()
1499 *
1500 * This function calculates the data length used in
1501 * hdd_add_link_standard_info_sap()
1502 *
1503 * Return: total data length used in hdd_add_link_standard_info_sap()
1504 */
1505static uint32_t hdd_add_link_standard_info_sap_get_len(void)
1506{
1507 return ((NLA_HDRLEN) +
1508 hdd_add_survey_info_sap_get_len() +
1509 hdd_add_sta_info_sap_get_len() +
1510 (sizeof(uint32_t) + NLA_HDRLEN));
1511}
1512
1513/**
1514 * hdd_add_link_standard_info_sap - add add link info attribut
1515 * @skb: pointer to response skb buffer
1516 * @stainfo: station information
1517 * @idx: attribute type index for nla_next_start()
1518 *
1519 * This function adds link info attribut to response skb buffer
1520 *
1521 * Return : 0 on success and errno on failure
1522 */
1523static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
1524 struct hdd_cache_sta_info *stainfo,
1525 int idx)
1526{
1527 struct nlattr *nla_attr;
1528
1529 nla_attr = nla_nest_start(skb, idx);
1530 if (!nla_attr)
1531 goto fail;
1532 if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
1533 goto fail;
1534 if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
1535 goto fail;
1536
1537 if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
1538 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1539 FL("put fail"));
1540 goto fail;
1541 }
1542
1543 nla_nest_end(skb, nla_attr);
1544 return 0;
1545fail:
1546 return -EINVAL;
1547}
1548
1549/**
1550 * hdd_add_ap_standard_info_sap_get_len - get data length used in
1551 * hdd_add_ap_standard_info_sap()
1552 * @stainfo: station information
1553 *
1554 * This function calculates the data length used in
1555 * hdd_add_ap_standard_info_sap()
1556 *
1557 * Return: total data length used in hdd_add_ap_standard_info_sap()
1558 */
1559static uint32_t hdd_add_ap_standard_info_sap_get_len(
1560 struct hdd_cache_sta_info *stainfo)
1561{
1562 uint32_t len;
1563
1564 len = NLA_HDRLEN;
1565 if (stainfo->vht_present)
1566 len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
1567 if (stainfo->ht_present)
1568 len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
1569
1570 return len;
1571}
1572
1573/**
1574 * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
1575 * @skb: pointer to response skb buffer
1576 * @stainfo: station information
1577 * @idx: attribute type index for nla_next_start()
1578 *
1579 * This function adds HT and VHT info attributes to response skb buffer
1580 *
1581 * Return : 0 on success and errno on failure
1582 */
1583static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
1584 struct hdd_cache_sta_info *stainfo,
1585 int idx)
1586{
1587 struct nlattr *nla_attr;
1588
1589 nla_attr = nla_nest_start(skb, idx);
1590 if (!nla_attr)
1591 goto fail;
1592
1593 if (stainfo->vht_present) {
1594 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1595 sizeof(stainfo->vht_caps),
1596 &stainfo->vht_caps)) {
1597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1598 FL("put fail"));
1599 goto fail;
1600 }
1601 }
1602 if (stainfo->ht_present) {
1603 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1604 sizeof(stainfo->ht_caps),
1605 &stainfo->ht_caps)) {
1606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1607 FL("put fail"));
1608 goto fail;
1609 }
1610 }
1611 nla_nest_end(skb, nla_attr);
1612 return 0;
1613fail:
1614 return -EINVAL;
1615}
1616
1617/**
1618 * hdd_decode_ch_width - decode channel band width based
1619 * @ch_width: encoded enum value holding channel band width
1620 *
1621 * This function decodes channel band width from the given encoded enum value.
1622 *
1623 * Returns: decoded channel band width.
1624 */
1625static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
1626{
1627 switch (ch_width) {
1628 case 0:
1629 return 20;
1630 case 1:
1631 return 40;
1632 case 2:
1633 return 80;
1634 default:
1635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1636 "invalid enum: %d", ch_width);
1637 return 20;
1638 }
1639}
1640
1641/**
1642 * hdd_get_cached_station_remote() - get cached(deleted) peer's info
1643 * @hdd_ctx: hdd context
1644 * @adapter: hostapd interface
1645 * @mac_addr: mac address of requested peer
1646 *
1647 * This function collect and indicate the cached(deleted) peer's info
1648 *
1649 * Return: 0 on success, otherwise error value
1650 */
1651static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx,
1652 hdd_adapter_t *adapter,
1653 v_MACADDR_t mac_addr)
1654{
1655 struct hdd_cache_sta_info *stainfo;
1656 struct sk_buff *skb = NULL;
1657 uint32_t nl_buf_len;
1658 uint8_t cw;
1659 ptSapContext sap_ctx;
1660 v_CONTEXT_t vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
1661
1662 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
1663 if(sap_ctx == NULL){
1664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1665 FL("psapCtx is NULL"));
1666 return -ENOENT;
1667 }
1668
1669 stainfo = hdd_get_cache_stainfo(sap_ctx->cache_sta_info,
1670 mac_addr.bytes);
1671 if (!stainfo) {
1672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1673 "peer " MAC_ADDRESS_STR " not found",
1674 MAC_ADDR_ARRAY(mac_addr.bytes));
1675 return -EINVAL;
1676 }
1677 if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE) {
1678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1679 "peer " MAC_ADDRESS_STR " is in connected state",
1680 MAC_ADDR_ARRAY(mac_addr.bytes));
1681 return -EINVAL;
1682 }
1683
1684
1685 nl_buf_len = NLMSG_HDRLEN + hdd_add_link_standard_info_sap_get_len() +
1686 hdd_add_ap_standard_info_sap_get_len(stainfo) +
1687 (sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
1688 (sizeof(cw) + NLA_HDRLEN) +
1689 (sizeof(stainfo->rx_rate) + NLA_HDRLEN);
1690
1691 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1692 if (!skb) {
1693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "cfg80211_vendor_cmd_alloc_reply_skb failed");
1694 return -ENOMEM;
1695 }
1696
1697 if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
1698 LINK_INFO_STANDARD_NL80211_ATTR)) {
1699 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "link standard put fail");
1700 goto fail;
1701 }
1702
1703 if (hdd_add_ap_standard_info_sap(skb, stainfo,
1704 AP_INFO_STANDARD_NL80211_ATTR)) {
1705 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ap standard put fail");
1706 goto fail;
1707 }
1708
1709 /* upper layer expects decoded channel BW */
1710 cw = hdd_decode_ch_width(stainfo->ch_width);
1711 if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE, stainfo->dot11_mode) ||
1712 nla_put_u8(skb, REMOTE_CH_WIDTH, cw)) {
1713 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "remote ch put fail");
1714 goto fail;
1715 }
Hanumanth Reddy Pothula504fe152018-01-02 20:41:03 +05301716 if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, (stainfo->rx_rate * 100))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "rx rate put fail");
1718 goto fail;
1719 }
1720
1721 vos_mem_zero(stainfo, sizeof(*stainfo));
1722
1723 return cfg80211_vendor_cmd_reply(skb);
1724fail:
1725 if (skb)
1726 kfree_skb(skb);
1727
1728 return -EINVAL;
1729}
1730
1731/**
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301732 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1733 * @wiphy: corestack handler
1734 * @wdev: wireless device
1735 * @data: data
1736 * @data_len: data length
1737 *
1738 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1739 * Validate cmd attributes and send the station info to upper layers.
1740 *
1741 * Return: Success(0) or reason code for failure
1742 */
1743static int32_t
1744__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1745 struct wireless_dev *wdev,
1746 const void *data,
1747 int data_len)
1748{
1749 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1750 struct net_device *dev = wdev->netdev;
1751 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1752 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1753 int32_t status;
1754
1755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1756 if (VOS_FTM_MODE == hdd_get_conparam()) {
1757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1758 status = -EPERM;
1759 goto out;
1760 }
1761
1762 status = wlan_hdd_validate_context(hdd_ctx);
1763 if (0 != status)
1764 goto out;
1765
1766
1767 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1768 data, data_len, NULL);
1769 if (status) {
1770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1771 goto out;
1772 }
1773
1774 /* Parse and fetch Command Type*/
1775 if (tb[STATION_INFO]) {
1776 status = hdd_get_station_info(hdd_ctx, adapter);
1777 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1778 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301779 } else if (tb[STATION_REMOTE]) {
1780 v_MACADDR_t mac_addr;
1781
1782 if (adapter->device_mode != WLAN_HDD_SOFTAP &&
1783 adapter->device_mode != WLAN_HDD_P2P_GO) {
1784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"invalid device_mode:%d",
1785 adapter->device_mode);
1786 status = -EINVAL;
1787 goto out;
1788 }
1789
1790 nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
1791 VOS_MAC_ADDRESS_LEN);
1792
1793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "STATION_REMOTE "MAC_ADDRESS_STR"",
1794 MAC_ADDR_ARRAY(mac_addr.bytes));
1795
1796 status = hdd_get_cached_station_remote(hdd_ctx, adapter,
1797 mac_addr);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301798 } else {
1799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1800 status = -EINVAL;
1801 goto out;
1802 }
1803 EXIT();
1804out:
1805 return status;
1806}
1807
1808/**
1809 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1810 * @wiphy: corestack handler
1811 * @wdev: wireless device
1812 * @data: data
1813 * @data_len: data length
1814 *
1815 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1816 * Validate cmd attributes and send the station info to upper layers.
1817 *
1818 * Return: Success(0) or reason code for failure
1819 */
1820static int32_t
1821hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1822 struct wireless_dev *wdev,
1823 const void *data,
1824 int data_len)
1825{
1826 int ret;
1827
1828 vos_ssr_protect(__func__);
1829 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1830 vos_ssr_unprotect(__func__);
1831
1832 return ret;
1833}
1834
1835/*
1836 * undef short names defined for get station command
1837 * used by __wlan_hdd_cfg80211_get_station_cmd()
1838 */
1839#undef STATION_INVALID
1840#undef STATION_INFO
1841#undef STATION_ASSOC_FAIL_REASON
1842#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301843
Sunil Duttc69bccb2014-05-26 21:30:20 +05301844#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1845
1846static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1847 struct sk_buff *vendor_event)
1848{
1849 if (nla_put_u8(vendor_event,
1850 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1851 stats->rate.preamble) ||
1852 nla_put_u8(vendor_event,
1853 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1854 stats->rate.nss) ||
1855 nla_put_u8(vendor_event,
1856 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1857 stats->rate.bw) ||
1858 nla_put_u8(vendor_event,
1859 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1860 stats->rate.rateMcsIdx) ||
1861 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1862 stats->rate.bitrate ) ||
1863 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1864 stats->txMpdu ) ||
1865 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1866 stats->rxMpdu ) ||
1867 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1868 stats->mpduLost ) ||
1869 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1870 stats->retries) ||
1871 nla_put_u32(vendor_event,
1872 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1873 stats->retriesShort ) ||
1874 nla_put_u32(vendor_event,
1875 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1876 stats->retriesLong))
1877 {
1878 hddLog(VOS_TRACE_LEVEL_ERROR,
1879 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1880 return FALSE;
1881 }
1882 return TRUE;
1883}
1884
1885static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1886 struct sk_buff *vendor_event)
1887{
1888 u32 i = 0;
1889 struct nlattr *rateInfo;
1890 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1891 stats->type) ||
1892 nla_put(vendor_event,
1893 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1894 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1895 nla_put_u32(vendor_event,
1896 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1897 stats->capabilities) ||
1898 nla_put_u32(vendor_event,
1899 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1900 stats->numRate))
1901 {
1902 hddLog(VOS_TRACE_LEVEL_ERROR,
1903 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1904 goto error;
1905 }
1906
1907 rateInfo = nla_nest_start(vendor_event,
1908 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301909 if(!rateInfo)
1910 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301911 for (i = 0; i < stats->numRate; i++)
1912 {
1913 struct nlattr *rates;
1914 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1915 stats->rateStats +
1916 (i * sizeof(tSirWifiRateStat)));
1917 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301918 if(!rates)
1919 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301920
1921 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1922 {
1923 hddLog(VOS_TRACE_LEVEL_ERROR,
1924 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1925 return FALSE;
1926 }
1927 nla_nest_end(vendor_event, rates);
1928 }
1929 nla_nest_end(vendor_event, rateInfo);
1930
1931 return TRUE;
1932error:
1933 return FALSE;
1934}
1935
1936static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1937 struct sk_buff *vendor_event)
1938{
1939 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1940 stats->ac ) ||
1941 nla_put_u32(vendor_event,
1942 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1943 stats->txMpdu ) ||
1944 nla_put_u32(vendor_event,
1945 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1946 stats->rxMpdu ) ||
1947 nla_put_u32(vendor_event,
1948 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1949 stats->txMcast ) ||
1950 nla_put_u32(vendor_event,
1951 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1952 stats->rxMcast ) ||
1953 nla_put_u32(vendor_event,
1954 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1955 stats->rxAmpdu ) ||
1956 nla_put_u32(vendor_event,
1957 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1958 stats->txAmpdu ) ||
1959 nla_put_u32(vendor_event,
1960 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1961 stats->mpduLost )||
1962 nla_put_u32(vendor_event,
1963 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1964 stats->retries ) ||
1965 nla_put_u32(vendor_event,
1966 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1967 stats->retriesShort ) ||
1968 nla_put_u32(vendor_event,
1969 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1970 stats->retriesLong ) ||
1971 nla_put_u32(vendor_event,
1972 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1973 stats->contentionTimeMin ) ||
1974 nla_put_u32(vendor_event,
1975 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1976 stats->contentionTimeMax ) ||
1977 nla_put_u32(vendor_event,
1978 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1979 stats->contentionTimeAvg ) ||
1980 nla_put_u32(vendor_event,
1981 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1982 stats->contentionNumSamples ))
1983 {
1984 hddLog(VOS_TRACE_LEVEL_ERROR,
1985 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1986 return FALSE;
1987 }
1988 return TRUE;
1989}
1990
1991static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1992 struct sk_buff *vendor_event)
1993{
Dino Myclec8f3f332014-07-21 16:48:27 +05301994 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301995 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1996 nla_put(vendor_event,
1997 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
1998 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
1999 nla_put_u32(vendor_event,
2000 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
2001 stats->state ) ||
2002 nla_put_u32(vendor_event,
2003 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
2004 stats->roaming ) ||
2005 nla_put_u32(vendor_event,
2006 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
2007 stats->capabilities ) ||
2008 nla_put(vendor_event,
2009 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
2010 strlen(stats->ssid), stats->ssid) ||
2011 nla_put(vendor_event,
2012 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
2013 WNI_CFG_BSSID_LEN, stats->bssid) ||
2014 nla_put(vendor_event,
2015 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
2016 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
2017 nla_put(vendor_event,
2018 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
2019 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
2020 )
2021 {
2022 hddLog(VOS_TRACE_LEVEL_ERROR,
2023 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2024 return FALSE;
2025 }
2026 return TRUE;
2027}
2028
Dino Mycle3b9536d2014-07-09 22:05:24 +05302029static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
2030 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302031 struct sk_buff *vendor_event)
2032{
2033 int i = 0;
2034 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302035 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2036 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302037 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302038
Sunil Duttc69bccb2014-05-26 21:30:20 +05302039 if (FALSE == put_wifi_interface_info(
2040 &pWifiIfaceStat->info,
2041 vendor_event))
2042 {
2043 hddLog(VOS_TRACE_LEVEL_ERROR,
2044 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2045 return FALSE;
2046
2047 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05302048 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
2049 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
2050 if (NULL == pWifiIfaceStatTL)
2051 {
2052 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2053 return FALSE;
2054 }
2055
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302056 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
2057 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
2058 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
2059 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
2060
2061 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
2062 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
2063 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
2064 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302065
2066 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
2067 {
2068 if (VOS_STATUS_SUCCESS ==
2069 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2070 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
2071 {
2072 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
2073 * obtained from TL structure
2074 */
2075
2076 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
2077 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302078 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
2079
Srinivas Dasari98947432014-11-07 19:41:24 +05302080 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
2081 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
2082 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
2083 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
2084 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
2085 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
2086 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
2087 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302088
Srinivas Dasari98947432014-11-07 19:41:24 +05302089 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
2090 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
2091 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
2092 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
2093 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
2094 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
2095 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
2096 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302097
Srinivas Dasari98947432014-11-07 19:41:24 +05302098 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
2099 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
2100 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
2101 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
2102 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
2103 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
2104 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
2105 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302106 }
2107 else
2108 {
2109 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
2110 }
2111
Dino Mycle3b9536d2014-07-09 22:05:24 +05302112 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
2113 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
2114 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
2115 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
2116 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
2117 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
2118 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
2119 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
2120 }
2121 else
2122 {
2123 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
2124 }
2125
2126
Sunil Duttc69bccb2014-05-26 21:30:20 +05302127
2128 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302129 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2130 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
2131 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302132 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
2133 pWifiIfaceStat->beaconRx) ||
2134 nla_put_u32(vendor_event,
2135 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
2136 pWifiIfaceStat->mgmtRx) ||
2137 nla_put_u32(vendor_event,
2138 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
2139 pWifiIfaceStat->mgmtActionRx) ||
2140 nla_put_u32(vendor_event,
2141 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
2142 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302143 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302144 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
2145 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302146 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302147 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
2148 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302149 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302150 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
2151 pWifiIfaceStat->rssiAck))
2152 {
2153 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302154 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2155 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302156 return FALSE;
2157 }
2158
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302159#ifdef FEATURE_EXT_LL_STAT
2160 /*
2161 * Ensure when EXT_LL_STAT is supported by both host and fwr,
2162 * then host should send Leaky AP stats to upper layer,
2163 * otherwise no need to send these stats.
2164 */
2165 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
2166 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
2167 )
2168 {
2169 hddLog(VOS_TRACE_LEVEL_INFO,
2170 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
2171 pWifiIfaceStat->leakyApStat.is_leaky_ap,
2172 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
2173 pWifiIfaceStat->leakyApStat.rx_leak_window,
2174 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
2175 if (nla_put_u32(vendor_event,
2176 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
2177 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
2178 nla_put_u32(vendor_event,
2179 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
2180 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
2181 nla_put_u32(vendor_event,
2182 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
2183 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05302184 hdd_wlan_nla_put_u64(vendor_event,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302185 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
2186 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
2187 {
2188 hddLog(VOS_TRACE_LEVEL_ERROR,
2189 FL("EXT_LL_STAT put fail"));
2190 vos_mem_free(pWifiIfaceStatTL);
2191 return FALSE;
2192 }
2193 }
2194#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05302195 wmmInfo = nla_nest_start(vendor_event,
2196 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302197 if(!wmmInfo)
2198 {
2199 vos_mem_free(pWifiIfaceStatTL);
2200 return FALSE;
2201 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302202 for (i = 0; i < WIFI_AC_MAX; i++)
2203 {
2204 struct nlattr *wmmStats;
2205 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302206 if(!wmmStats)
2207 {
2208 vos_mem_free(pWifiIfaceStatTL);
2209 return FALSE;
2210 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302211 if (FALSE == put_wifi_wmm_ac_stat(
2212 &pWifiIfaceStat->AccessclassStats[i],
2213 vendor_event))
2214 {
2215 hddLog(VOS_TRACE_LEVEL_ERROR,
2216 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05302217 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302218 return FALSE;
2219 }
2220
2221 nla_nest_end(vendor_event, wmmStats);
2222 }
2223 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05302224 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302225 return TRUE;
2226}
2227
2228static tSirWifiInterfaceMode
2229 hdd_map_device_to_ll_iface_mode ( int deviceMode )
2230{
2231 switch (deviceMode)
2232 {
2233 case WLAN_HDD_INFRA_STATION:
2234 return WIFI_INTERFACE_STA;
2235 case WLAN_HDD_SOFTAP:
2236 return WIFI_INTERFACE_SOFTAP;
2237 case WLAN_HDD_P2P_CLIENT:
2238 return WIFI_INTERFACE_P2P_CLIENT;
2239 case WLAN_HDD_P2P_GO:
2240 return WIFI_INTERFACE_P2P_GO;
2241 case WLAN_HDD_IBSS:
2242 return WIFI_INTERFACE_IBSS;
2243 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05302244 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302245 }
2246}
2247
2248static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
2249 tpSirWifiInterfaceInfo pInfo)
2250{
2251 v_U8_t *staMac = NULL;
2252 hdd_station_ctx_t *pHddStaCtx;
2253 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2254 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
2255
2256 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
2257
2258 vos_mem_copy(pInfo->macAddr,
2259 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
2260
2261 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2262 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
2263 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
2264 {
2265 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2266 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
2267 {
2268 pInfo->state = WIFI_DISCONNECTED;
2269 }
2270 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
2271 {
2272 hddLog(VOS_TRACE_LEVEL_ERROR,
2273 "%s: Session ID %d, Connection is in progress", __func__,
2274 pAdapter->sessionId);
2275 pInfo->state = WIFI_ASSOCIATING;
2276 }
2277 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
2278 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
2279 {
2280 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
2281 hddLog(VOS_TRACE_LEVEL_ERROR,
2282 "%s: client " MAC_ADDRESS_STR
2283 " is in the middle of WPS/EAPOL exchange.", __func__,
2284 MAC_ADDR_ARRAY(staMac));
2285 pInfo->state = WIFI_AUTHENTICATING;
2286 }
2287 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
2288 {
2289 pInfo->state = WIFI_ASSOCIATED;
2290 vos_mem_copy(pInfo->bssid,
2291 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
2292 vos_mem_copy(pInfo->ssid,
2293 pHddStaCtx->conn_info.SSID.SSID.ssId,
2294 pHddStaCtx->conn_info.SSID.SSID.length);
2295 //NULL Terminate the string.
2296 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
2297 }
2298 }
2299 vos_mem_copy(pInfo->countryStr,
2300 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2301
2302 vos_mem_copy(pInfo->apCountryStr,
2303 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2304
2305 return TRUE;
2306}
2307
2308/*
2309 * hdd_link_layer_process_peer_stats () - This function is called after
2310 * receiving Link Layer Peer statistics from FW.This function converts
2311 * the firmware data to the NL data and sends the same to the kernel/upper
2312 * layers.
2313 */
2314static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
2315 v_VOID_t *pData)
2316{
2317 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302318 tpSirWifiPeerStat pWifiPeerStat;
2319 tpSirWifiPeerInfo pWifiPeerInfo;
2320 struct nlattr *peerInfo;
2321 struct sk_buff *vendor_event;
2322 int status, i;
2323
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302324 ENTER();
2325
Sunil Duttc69bccb2014-05-26 21:30:20 +05302326 status = wlan_hdd_validate_context(pHddCtx);
2327 if (0 != status)
2328 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302329 return;
2330 }
2331
2332 pWifiPeerStat = (tpSirWifiPeerStat) pData;
2333
2334 hddLog(VOS_TRACE_LEVEL_INFO,
2335 "LL_STATS_PEER_ALL : numPeers %u",
2336 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302337 /*
2338 * Allocate a size of 4096 for the peer stats comprising
2339 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
2340 * sizeof (tSirWifiRateStat).Each field is put with an
2341 * NL attribute.The size of 4096 is considered assuming
2342 * that number of rates shall not exceed beyond 50 with
2343 * the sizeof (tSirWifiRateStat) being 32.
2344 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302345 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2346 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302347 if (!vendor_event)
2348 {
2349 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302350 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05302351 __func__);
2352 return;
2353 }
2354 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302355 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2356 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
2357 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302358 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
2359 pWifiPeerStat->numPeers))
2360 {
2361 hddLog(VOS_TRACE_LEVEL_ERROR,
2362 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
2363 kfree_skb(vendor_event);
2364 return;
2365 }
2366
2367 peerInfo = nla_nest_start(vendor_event,
2368 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302369 if(!peerInfo)
2370 {
2371 hddLog(VOS_TRACE_LEVEL_ERROR,
2372 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
2373 __func__);
2374 kfree_skb(vendor_event);
2375 return;
2376 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302377
2378 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2379 pWifiPeerStat->peerInfo);
2380
2381 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
2382 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302383 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302384 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302385
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302386 if(!peers)
2387 {
2388 hddLog(VOS_TRACE_LEVEL_ERROR,
2389 "%s: peer stats put fail",
2390 __func__);
2391 kfree_skb(vendor_event);
2392 return;
2393 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302394 if (FALSE == put_wifi_peer_info(
2395 pWifiPeerInfo, vendor_event))
2396 {
2397 hddLog(VOS_TRACE_LEVEL_ERROR,
2398 "%s: put_wifi_peer_info put fail", __func__);
2399 kfree_skb(vendor_event);
2400 return;
2401 }
2402
2403 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2404 pWifiPeerStat->peerInfo +
2405 (i * sizeof(tSirWifiPeerInfo)) +
2406 (numRate * sizeof (tSirWifiRateStat)));
2407 nla_nest_end(vendor_event, peers);
2408 }
2409 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302410 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302411 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302412}
2413
2414/*
2415 * hdd_link_layer_process_iface_stats () - This function is called after
2416 * receiving Link Layer Interface statistics from FW.This function converts
2417 * the firmware data to the NL data and sends the same to the kernel/upper
2418 * layers.
2419 */
2420static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
2421 v_VOID_t *pData)
2422{
2423 tpSirWifiIfaceStat pWifiIfaceStat;
2424 struct sk_buff *vendor_event;
2425 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2426 int status;
2427
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302428 ENTER();
2429
Sunil Duttc69bccb2014-05-26 21:30:20 +05302430 status = wlan_hdd_validate_context(pHddCtx);
2431 if (0 != status)
2432 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302433 return;
2434 }
2435 /*
2436 * Allocate a size of 4096 for the interface stats comprising
2437 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
2438 * assuming that all these fit with in the limit.Please take
2439 * a call on the limit based on the data requirements on
2440 * interface statistics.
2441 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302442 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2443 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302444 if (!vendor_event)
2445 {
2446 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302447 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302448 return;
2449 }
2450
2451 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
2452
Dino Mycle3b9536d2014-07-09 22:05:24 +05302453
2454 if (FALSE == hdd_get_interface_info( pAdapter,
2455 &pWifiIfaceStat->info))
2456 {
2457 hddLog(VOS_TRACE_LEVEL_ERROR,
2458 FL("hdd_get_interface_info get fail") );
2459 kfree_skb(vendor_event);
2460 return;
2461 }
2462
2463 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
2464 vendor_event))
2465 {
2466 hddLog(VOS_TRACE_LEVEL_ERROR,
2467 FL("put_wifi_iface_stats fail") );
2468 kfree_skb(vendor_event);
2469 return;
2470 }
2471
Sunil Duttc69bccb2014-05-26 21:30:20 +05302472 hddLog(VOS_TRACE_LEVEL_INFO,
2473 "WMI_LINK_STATS_IFACE Data");
2474
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302475 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302476
2477 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302478}
2479
2480/*
2481 * hdd_link_layer_process_radio_stats () - This function is called after
2482 * receiving Link Layer Radio statistics from FW.This function converts
2483 * the firmware data to the NL data and sends the same to the kernel/upper
2484 * layers.
2485 */
2486static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
2487 v_VOID_t *pData)
2488{
2489 int status, i;
2490 tpSirWifiRadioStat pWifiRadioStat;
2491 tpSirWifiChannelStats pWifiChannelStats;
2492 struct sk_buff *vendor_event;
2493 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2494 struct nlattr *chList;
2495
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302496 ENTER();
2497
Sunil Duttc69bccb2014-05-26 21:30:20 +05302498 status = wlan_hdd_validate_context(pHddCtx);
2499 if (0 != status)
2500 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302501 return;
2502 }
2503 pWifiRadioStat = (tpSirWifiRadioStat) pData;
2504
2505 hddLog(VOS_TRACE_LEVEL_INFO,
2506 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302507 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05302508 " radio is %d onTime is %u "
2509 " txTime is %u rxTime is %u "
2510 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05302511 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05302512 " onTimePnoScan is %u onTimeHs20 is %u "
2513 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302514 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302515 pWifiRadioStat->radio, pWifiRadioStat->onTime,
2516 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
2517 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302518 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302519 pWifiRadioStat->onTimeRoamScan,
2520 pWifiRadioStat->onTimePnoScan,
2521 pWifiRadioStat->onTimeHs20,
2522 pWifiRadioStat->numChannels);
2523 /*
2524 * Allocate a size of 4096 for the Radio stats comprising
2525 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
2526 * (tSirWifiChannelStats).Each channel data is put with an
2527 * NL attribute.The size of 4096 is considered assuming that
2528 * number of channels shall not exceed beyond 60 with the
2529 * sizeof (tSirWifiChannelStats) being 24 bytes.
2530 */
2531
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302532 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2533 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302534 if (!vendor_event)
2535 {
2536 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302537 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302538 return;
2539 }
2540
2541 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302542 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2543 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2544 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302545 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2546 pWifiRadioStat->radio) ||
2547 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302548 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2549 NUM_RADIOS) ||
2550 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302551 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2552 pWifiRadioStat->onTime) ||
2553 nla_put_u32(vendor_event,
2554 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2555 pWifiRadioStat->txTime) ||
2556 nla_put_u32(vendor_event,
2557 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2558 pWifiRadioStat->rxTime) ||
2559 nla_put_u32(vendor_event,
2560 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2561 pWifiRadioStat->onTimeScan) ||
2562 nla_put_u32(vendor_event,
2563 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2564 pWifiRadioStat->onTimeNbd) ||
2565 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302566 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2567 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302568 nla_put_u32(vendor_event,
2569 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2570 pWifiRadioStat->onTimeRoamScan) ||
2571 nla_put_u32(vendor_event,
2572 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2573 pWifiRadioStat->onTimePnoScan) ||
2574 nla_put_u32(vendor_event,
2575 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2576 pWifiRadioStat->onTimeHs20) ||
2577 nla_put_u32(vendor_event,
2578 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2579 pWifiRadioStat->numChannels))
2580 {
2581 hddLog(VOS_TRACE_LEVEL_ERROR,
2582 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2583 kfree_skb(vendor_event);
2584 return ;
2585 }
2586
2587 chList = nla_nest_start(vendor_event,
2588 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302589 if(!chList)
2590 {
2591 hddLog(VOS_TRACE_LEVEL_ERROR,
2592 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2593 __func__);
2594 kfree_skb(vendor_event);
2595 return;
2596 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302597 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2598 {
2599 struct nlattr *chInfo;
2600
2601 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2602 pWifiRadioStat->channels +
2603 (i * sizeof(tSirWifiChannelStats)));
2604
Sunil Duttc69bccb2014-05-26 21:30:20 +05302605 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302606 if(!chInfo)
2607 {
2608 hddLog(VOS_TRACE_LEVEL_ERROR,
2609 "%s: failed to put chInfo",
2610 __func__);
2611 kfree_skb(vendor_event);
2612 return;
2613 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302614
2615 if (nla_put_u32(vendor_event,
2616 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2617 pWifiChannelStats->channel.width) ||
2618 nla_put_u32(vendor_event,
2619 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2620 pWifiChannelStats->channel.centerFreq) ||
2621 nla_put_u32(vendor_event,
2622 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2623 pWifiChannelStats->channel.centerFreq0) ||
2624 nla_put_u32(vendor_event,
2625 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2626 pWifiChannelStats->channel.centerFreq1) ||
2627 nla_put_u32(vendor_event,
2628 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2629 pWifiChannelStats->onTime) ||
2630 nla_put_u32(vendor_event,
2631 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2632 pWifiChannelStats->ccaBusyTime))
2633 {
2634 hddLog(VOS_TRACE_LEVEL_ERROR,
2635 FL("cfg80211_vendor_event_alloc failed") );
2636 kfree_skb(vendor_event);
2637 return ;
2638 }
2639 nla_nest_end(vendor_event, chInfo);
2640 }
2641 nla_nest_end(vendor_event, chList);
2642
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302643 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302644
2645 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302646 return;
2647}
2648
2649/*
2650 * hdd_link_layer_stats_ind_callback () - This function is called after
2651 * receiving Link Layer indications from FW.This callback converts the firmware
2652 * data to the NL data and send the same to the kernel/upper layers.
2653 */
2654static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2655 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302656 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302657{
Dino Mycled3d50022014-07-07 12:58:25 +05302658 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2659 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302660 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302661 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302662 int status;
2663
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302664 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302665
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302666 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302667 if (0 != status)
2668 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302669 return;
2670 }
2671
Dino Mycled3d50022014-07-07 12:58:25 +05302672 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2673 if (NULL == pAdapter)
2674 {
2675 hddLog(VOS_TRACE_LEVEL_ERROR,
2676 FL(" MAC address %pM does not exist with host"),
2677 macAddr);
2678 return;
2679 }
2680
Sunil Duttc69bccb2014-05-26 21:30:20 +05302681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302682 "%s: Interface: %s LLStats indType: %d", __func__,
2683 pAdapter->dev->name, indType);
2684
Sunil Duttc69bccb2014-05-26 21:30:20 +05302685 switch (indType)
2686 {
2687 case SIR_HAL_LL_STATS_RESULTS_RSP:
2688 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302689 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302690 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2691 "respId = %u, moreResultToFollow = %u",
2692 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2693 macAddr, linkLayerStatsResults->respId,
2694 linkLayerStatsResults->moreResultToFollow);
2695
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302696 spin_lock(&hdd_context_lock);
2697 context = &pHddCtx->ll_stats_context;
2698 /* validate response received from target */
2699 if ((context->request_id != linkLayerStatsResults->respId) ||
2700 !(context->request_bitmap & linkLayerStatsResults->paramId))
2701 {
2702 spin_unlock(&hdd_context_lock);
2703 hddLog(LOGE,
2704 FL("Error : Request id %d response id %d request bitmap 0x%x"
2705 "response bitmap 0x%x"),
2706 context->request_id, linkLayerStatsResults->respId,
2707 context->request_bitmap, linkLayerStatsResults->paramId);
2708 return;
2709 }
2710 spin_unlock(&hdd_context_lock);
2711
Sunil Duttc69bccb2014-05-26 21:30:20 +05302712 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2713 {
2714 hdd_link_layer_process_radio_stats(pAdapter,
2715 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302716 spin_lock(&hdd_context_lock);
2717 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2718 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302719 }
2720 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2721 {
2722 hdd_link_layer_process_iface_stats(pAdapter,
2723 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302724 spin_lock(&hdd_context_lock);
2725 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2726 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302727 }
2728 else if ( linkLayerStatsResults->paramId &
2729 WMI_LINK_STATS_ALL_PEER )
2730 {
2731 hdd_link_layer_process_peer_stats(pAdapter,
2732 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302733 spin_lock(&hdd_context_lock);
2734 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2735 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302736 } /* WMI_LINK_STATS_ALL_PEER */
2737 else
2738 {
2739 hddLog(VOS_TRACE_LEVEL_ERROR,
2740 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2741 }
2742
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302743 spin_lock(&hdd_context_lock);
2744 /* complete response event if all requests are completed */
2745 if (0 == context->request_bitmap)
2746 complete(&context->response_event);
2747 spin_unlock(&hdd_context_lock);
2748
Sunil Duttc69bccb2014-05-26 21:30:20 +05302749 break;
2750 }
2751 default:
2752 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2753 break;
2754 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302755
2756 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302757 return;
2758}
2759
2760const struct
2761nla_policy
2762qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2763{
2764 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2765 { .type = NLA_U32 },
2766 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2767 { .type = NLA_U32 },
2768};
2769
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302770static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2771 struct wireless_dev *wdev,
2772 const void *data,
2773 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302774{
2775 int status;
2776 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302777 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302778 struct net_device *dev = wdev->netdev;
2779 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2780 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2781
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302782 ENTER();
2783
Sunil Duttc69bccb2014-05-26 21:30:20 +05302784 status = wlan_hdd_validate_context(pHddCtx);
2785 if (0 != status)
2786 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302787 return -EINVAL;
2788 }
2789
2790 if (NULL == pAdapter)
2791 {
2792 hddLog(VOS_TRACE_LEVEL_ERROR,
2793 FL("HDD adapter is Null"));
2794 return -ENODEV;
2795 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302796 /* check the LLStats Capability */
2797 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2798 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2799 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302800 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302801 FL("Link Layer Statistics not supported by Firmware"));
2802 return -EINVAL;
2803 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302804
2805 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2806 (struct nlattr *)data,
2807 data_len, qca_wlan_vendor_ll_set_policy))
2808 {
2809 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2810 return -EINVAL;
2811 }
2812 if (!tb_vendor
2813 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2814 {
2815 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2816 return -EINVAL;
2817 }
2818 if (!tb_vendor[
2819 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2820 {
2821 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2822 return -EINVAL;
2823 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302824 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302825 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302826
Dino Mycledf0a5d92014-07-04 09:41:55 +05302827 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302828 nla_get_u32(
2829 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2830
Dino Mycledf0a5d92014-07-04 09:41:55 +05302831 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302832 nla_get_u32(
2833 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2834
Dino Mycled3d50022014-07-07 12:58:25 +05302835 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2836 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302837
2838
2839 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302840 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2841 "Statistics Gathering = %d ",
2842 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2843 linkLayerStatsSetReq.mpduSizeThreshold,
2844 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302845
2846 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2847 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302848 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302849 {
2850 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2851 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302852 return -EINVAL;
2853
2854 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302855
Sunil Duttc69bccb2014-05-26 21:30:20 +05302856 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302857 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302858 {
2859 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2860 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302861 return -EINVAL;
2862 }
2863
2864 pAdapter->isLinkLayerStatsSet = 1;
2865
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302866 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302867 return 0;
2868}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302869static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2870 struct wireless_dev *wdev,
2871 const void *data,
2872 int data_len)
2873{
2874 int ret = 0;
2875
2876 vos_ssr_protect(__func__);
2877 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2878 vos_ssr_unprotect(__func__);
2879
2880 return ret;
2881}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302882
2883const struct
2884nla_policy
2885qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2886{
2887 /* Unsigned 32bit value provided by the caller issuing the GET stats
2888 * command. When reporting
2889 * the stats results, the driver uses the same value to indicate
2890 * which GET request the results
2891 * correspond to.
2892 */
2893 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2894
2895 /* Unsigned 32bit value . bit mask to identify what statistics are
2896 requested for retrieval */
2897 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2898};
2899
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302900static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2901 struct wireless_dev *wdev,
2902 const void *data,
2903 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302904{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302905 unsigned long rc;
2906 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302907 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2908 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302909 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302910 struct net_device *dev = wdev->netdev;
2911 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302912 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302913 int status;
2914
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302915 ENTER();
2916
Sunil Duttc69bccb2014-05-26 21:30:20 +05302917 status = wlan_hdd_validate_context(pHddCtx);
2918 if (0 != status)
2919 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302920 return -EINVAL ;
2921 }
2922
2923 if (NULL == pAdapter)
2924 {
2925 hddLog(VOS_TRACE_LEVEL_FATAL,
2926 "%s: HDD adapter is Null", __func__);
2927 return -ENODEV;
2928 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302929
2930 if (pHddStaCtx == NULL)
2931 {
2932 hddLog(VOS_TRACE_LEVEL_FATAL,
2933 "%s: HddStaCtx is Null", __func__);
2934 return -ENODEV;
2935 }
2936
Dino Mycledf0a5d92014-07-04 09:41:55 +05302937 /* check the LLStats Capability */
2938 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2939 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2940 {
2941 hddLog(VOS_TRACE_LEVEL_ERROR,
2942 FL("Link Layer Statistics not supported by Firmware"));
2943 return -EINVAL;
2944 }
2945
Sunil Duttc69bccb2014-05-26 21:30:20 +05302946
2947 if (!pAdapter->isLinkLayerStatsSet)
2948 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302949 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302950 "%s: isLinkLayerStatsSet : %d",
2951 __func__, pAdapter->isLinkLayerStatsSet);
2952 return -EINVAL;
2953 }
2954
Mukul Sharma10313ba2015-07-29 19:14:39 +05302955 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2956 {
2957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2958 "%s: Roaming in progress, so unable to proceed this request", __func__);
2959 return -EBUSY;
2960 }
2961
Sunil Duttc69bccb2014-05-26 21:30:20 +05302962 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2963 (struct nlattr *)data,
2964 data_len, qca_wlan_vendor_ll_get_policy))
2965 {
2966 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2967 return -EINVAL;
2968 }
2969
2970 if (!tb_vendor
2971 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2972 {
2973 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2974 return -EINVAL;
2975 }
2976
2977 if (!tb_vendor
2978 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2979 {
2980 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2981 return -EINVAL;
2982 }
2983
Sunil Duttc69bccb2014-05-26 21:30:20 +05302984
Dino Mycledf0a5d92014-07-04 09:41:55 +05302985 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302986 nla_get_u32( tb_vendor[
2987 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302988 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302989 nla_get_u32( tb_vendor[
2990 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2991
Dino Mycled3d50022014-07-07 12:58:25 +05302992 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2993 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302994
2995 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302996 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
2997 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302998 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302999
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303000 spin_lock(&hdd_context_lock);
3001 context = &pHddCtx->ll_stats_context;
3002 context->request_id = linkLayerStatsGetReq.reqId;
3003 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
3004 INIT_COMPLETION(context->response_event);
3005 spin_unlock(&hdd_context_lock);
3006
Sunil Duttc69bccb2014-05-26 21:30:20 +05303007 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303008 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303009 {
3010 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3011 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303012 return -EINVAL;
3013 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303014
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303015 rc = wait_for_completion_timeout(&context->response_event,
3016 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
3017 if (!rc)
3018 {
3019 hddLog(LOGE,
3020 FL("Target response timed out request id %d request bitmap 0x%x"),
3021 context->request_id, context->request_bitmap);
3022 return -ETIMEDOUT;
3023 }
3024
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303025 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303026 return 0;
3027}
3028
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303029static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
3030 struct wireless_dev *wdev,
3031 const void *data,
3032 int data_len)
3033{
3034 int ret = 0;
3035
3036 vos_ssr_protect(__func__);
3037 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
3038 vos_ssr_unprotect(__func__);
3039
3040 return ret;
3041}
3042
Sunil Duttc69bccb2014-05-26 21:30:20 +05303043const struct
3044nla_policy
3045qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
3046{
3047 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
3048 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
3049 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
3050 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
3051};
3052
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303053static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3054 struct wireless_dev *wdev,
3055 const void *data,
3056 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303057{
3058 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3059 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05303060 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303061 struct net_device *dev = wdev->netdev;
3062 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3063 u32 statsClearReqMask;
3064 u8 stopReq;
3065 int status;
3066
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303067 ENTER();
3068
Sunil Duttc69bccb2014-05-26 21:30:20 +05303069 status = wlan_hdd_validate_context(pHddCtx);
3070 if (0 != status)
3071 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303072 return -EINVAL;
3073 }
3074
3075 if (NULL == pAdapter)
3076 {
3077 hddLog(VOS_TRACE_LEVEL_FATAL,
3078 "%s: HDD adapter is Null", __func__);
3079 return -ENODEV;
3080 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05303081 /* check the LLStats Capability */
3082 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
3083 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
3084 {
3085 hddLog(VOS_TRACE_LEVEL_ERROR,
3086 FL("Enable LLStats Capability"));
3087 return -EINVAL;
3088 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05303089
3090 if (!pAdapter->isLinkLayerStatsSet)
3091 {
3092 hddLog(VOS_TRACE_LEVEL_FATAL,
3093 "%s: isLinkLayerStatsSet : %d",
3094 __func__, pAdapter->isLinkLayerStatsSet);
3095 return -EINVAL;
3096 }
3097
3098 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
3099 (struct nlattr *)data,
3100 data_len, qca_wlan_vendor_ll_clr_policy))
3101 {
3102 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
3103 return -EINVAL;
3104 }
3105
3106 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
3107
3108 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
3109 {
3110 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
3111 return -EINVAL;
3112
3113 }
3114
Sunil Duttc69bccb2014-05-26 21:30:20 +05303115
Dino Mycledf0a5d92014-07-04 09:41:55 +05303116 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303117 nla_get_u32(
3118 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
3119
Dino Mycledf0a5d92014-07-04 09:41:55 +05303120 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303121 nla_get_u8(
3122 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
3123
3124 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05303125 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303126
Dino Mycled3d50022014-07-07 12:58:25 +05303127 vos_mem_copy(linkLayerStatsClearReq.macAddr,
3128 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05303129
3130 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05303131 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
3132 "statsClearReqMask = 0x%X, stopReq = %d",
3133 linkLayerStatsClearReq.reqId,
3134 linkLayerStatsClearReq.macAddr,
3135 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303136 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303137
3138 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303139 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303140 {
3141 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05303142 hdd_station_ctx_t *pHddStaCtx;
3143
3144 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3145 if (VOS_STATUS_SUCCESS !=
3146 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
3147 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
3148 {
3149 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3150 "WLANTL_ClearInterfaceStats Failed", __func__);
3151 return -EINVAL;
3152 }
3153 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
3154 (statsClearReqMask & WIFI_STATS_IFACE)) {
3155 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
3156 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
3157 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
3158 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
3159 }
3160
Sunil Duttc69bccb2014-05-26 21:30:20 +05303161 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
3162 2 * sizeof(u32) +
3163 NLMSG_HDRLEN);
3164
3165 if (temp_skbuff != NULL)
3166 {
3167
3168 if (nla_put_u32(temp_skbuff,
3169 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
3170 statsClearReqMask) ||
3171 nla_put_u32(temp_skbuff,
3172 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
3173 stopReq))
3174 {
3175 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
3176 kfree_skb(temp_skbuff);
3177 return -EINVAL;
3178 }
3179 /* If the ask is to stop the stats collection as part of clear
3180 * (stopReq = 1) , ensure that no further requests of get
3181 * go to the firmware by having isLinkLayerStatsSet set to 0.
3182 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303183 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05303184 * case the firmware is just asked to clear the statistics.
3185 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05303186 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303187 pAdapter->isLinkLayerStatsSet = 0;
3188 return cfg80211_vendor_cmd_reply(temp_skbuff);
3189 }
3190 return -ENOMEM;
3191 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303192
3193 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303194 return -EINVAL;
3195}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303196static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3197 struct wireless_dev *wdev,
3198 const void *data,
3199 int data_len)
3200{
3201 int ret = 0;
3202
3203 vos_ssr_protect(__func__);
3204 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
3205 vos_ssr_unprotect(__func__);
3206
3207 return ret;
3208
3209
3210}
Sunil Duttc69bccb2014-05-26 21:30:20 +05303211#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
3212
Dino Mycle6fb96c12014-06-10 11:52:40 +05303213#ifdef WLAN_FEATURE_EXTSCAN
3214static const struct nla_policy
3215wlan_hdd_extscan_config_policy
3216 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
3217{
3218 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
3219 { .type = NLA_U32 },
3220 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
3221 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05303222 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
3223 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303224 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
3225 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
3226 { .type = NLA_U32 },
3227 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
3228 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
3229
3230 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
3231 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
3232 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
3233 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
3234 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303235 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
3236 { .type = NLA_U32 },
3237 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
3238 { .type = NLA_U32 },
3239 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
3240 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303241 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
3242 { .type = NLA_U32 },
3243 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
3244 { .type = NLA_U32 },
3245 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
3246 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303247 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
3248 { .type = NLA_U8 },
3249 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303250 { .type = NLA_U8 },
3251 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
3252 { .type = NLA_U8 },
3253 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
3254 { .type = NLA_U8 },
3255
3256 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
3257 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05303258 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
3259 .type = NLA_UNSPEC,
3260 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05303261 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
3262 { .type = NLA_S32 },
3263 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
3264 { .type = NLA_S32 },
3265 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
3266 { .type = NLA_U32 },
3267 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
3268 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303269 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
3270 { .type = NLA_U32 },
3271 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
3272 { .type = NLA_BINARY,
3273 .len = IEEE80211_MAX_SSID_LEN + 1 },
3274 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303275 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303276 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
3277 { .type = NLA_U32 },
3278 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
3279 { .type = NLA_U8 },
3280 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
3281 { .type = NLA_S32 },
3282 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
3283 { .type = NLA_S32 },
3284 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
3285 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303286};
3287
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303288/**
3289 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
3290 * @ctx: hdd global context
3291 * @data: capabilities data
3292 *
3293 * Return: none
3294 */
3295static void
3296wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303297{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303298 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303299 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303300 tSirEXTScanCapabilitiesEvent *data =
3301 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303302
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303303 ENTER();
3304
3305 if (wlan_hdd_validate_context(pHddCtx))
3306 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303307 return;
3308 }
3309
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303310 if (!pMsg)
3311 {
3312 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3313 return;
3314 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303315
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303316 vos_spin_lock_acquire(&hdd_context_lock);
3317
3318 context = &pHddCtx->ext_scan_context;
3319 /* validate response received from target*/
3320 if (context->request_id != data->requestId)
3321 {
3322 vos_spin_lock_release(&hdd_context_lock);
3323 hddLog(LOGE,
3324 FL("Target response id did not match: request_id %d resposne_id %d"),
3325 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303326 return;
3327 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303328 else
3329 {
3330 context->capability_response = *data;
3331 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303332 }
3333
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303334 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303335
Dino Mycle6fb96c12014-06-10 11:52:40 +05303336 return;
3337}
3338
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303339/*
3340 * define short names for the global vendor params
3341 * used by wlan_hdd_send_ext_scan_capability()
3342 */
3343#define PARAM_REQUEST_ID \
3344 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3345#define PARAM_STATUS \
3346 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
3347#define MAX_SCAN_CACHE_SIZE \
3348 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
3349#define MAX_SCAN_BUCKETS \
3350 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
3351#define MAX_AP_CACHE_PER_SCAN \
3352 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
3353#define MAX_RSSI_SAMPLE_SIZE \
3354 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
3355#define MAX_SCAN_RPT_THRHOLD \
3356 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
3357#define MAX_HOTLIST_BSSIDS \
3358 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
3359#define MAX_BSSID_HISTORY_ENTRIES \
3360 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
3361#define MAX_HOTLIST_SSIDS \
3362 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303363#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
3364 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303365
3366static int wlan_hdd_send_ext_scan_capability(void *ctx)
3367{
3368 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3369 struct sk_buff *skb = NULL;
3370 int ret;
3371 tSirEXTScanCapabilitiesEvent *data;
3372 tANI_U32 nl_buf_len;
3373
3374 ret = wlan_hdd_validate_context(pHddCtx);
3375 if (0 != ret)
3376 {
3377 return ret;
3378 }
3379
3380 data = &(pHddCtx->ext_scan_context.capability_response);
3381
3382 nl_buf_len = NLMSG_HDRLEN;
3383 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
3384 (sizeof(data->status) + NLA_HDRLEN) +
3385 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
3386 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
3387 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
3388 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
3389 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
3390 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
3391 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
3392 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
3393
3394 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
3395
3396 if (!skb)
3397 {
3398 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
3399 return -ENOMEM;
3400 }
3401
3402 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
3403 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
3404 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
3405 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
3406 data->maxRssiSampleSize, data->maxScanReportingThreshold);
3407 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
3408 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
3409 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
3410
3411 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
3412 nla_put_u32(skb, PARAM_STATUS, data->status) ||
3413 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
3414 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
3415 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
3416 data->maxApPerScan) ||
3417 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
3418 data->maxRssiSampleSize) ||
3419 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
3420 data->maxScanReportingThreshold) ||
3421 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
3422 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
3423 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303424 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
3425 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303426 {
3427 hddLog(LOGE, FL("nla put fail"));
3428 goto nla_put_failure;
3429 }
3430
3431 cfg80211_vendor_cmd_reply(skb);
3432 return 0;
3433
3434nla_put_failure:
3435 kfree_skb(skb);
3436 return -EINVAL;;
3437}
3438
3439/*
3440 * done with short names for the global vendor params
3441 * used by wlan_hdd_send_ext_scan_capability()
3442 */
3443#undef PARAM_REQUEST_ID
3444#undef PARAM_STATUS
3445#undef MAX_SCAN_CACHE_SIZE
3446#undef MAX_SCAN_BUCKETS
3447#undef MAX_AP_CACHE_PER_SCAN
3448#undef MAX_RSSI_SAMPLE_SIZE
3449#undef MAX_SCAN_RPT_THRHOLD
3450#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303451#undef MAX_BSSID_HISTORY_ENTRIES
3452#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05303453
3454static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
3455{
3456 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
3457 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303458 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303459 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303461 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303462
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303463 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303464 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303465
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303466 if (!pMsg)
3467 {
3468 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303469 return;
3470 }
3471
Dino Mycle6fb96c12014-06-10 11:52:40 +05303472 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3473 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
3474
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303475 context = &pHddCtx->ext_scan_context;
3476 spin_lock(&hdd_context_lock);
3477 if (context->request_id == pData->requestId) {
3478 context->response_status = pData->status ? -EINVAL : 0;
3479 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303480 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303481 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303482
3483 /*
3484 * Store the Request ID for comparing with the requestID obtained
3485 * in other requests.HDD shall return a failure is the extscan_stop
3486 * request is issued with a different requestId as that of the
3487 * extscan_start request. Also, This requestId shall be used while
3488 * indicating the full scan results to the upper layers.
3489 * The requestId is stored with the assumption that the firmware
3490 * shall return the ext scan start request's requestId in ext scan
3491 * start response.
3492 */
3493 if (pData->status == 0)
3494 pMac->sme.extScanStartReqId = pData->requestId;
3495
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303496 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303497 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303498}
3499
3500
3501static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
3502{
3503 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
3504 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303505 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303506
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303507 ENTER();
3508
3509 if (wlan_hdd_validate_context(pHddCtx)){
3510 return;
3511 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303512
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303513 if (!pMsg)
3514 {
3515 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303516 return;
3517 }
3518
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303519 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3520 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303521
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303522 context = &pHddCtx->ext_scan_context;
3523 spin_lock(&hdd_context_lock);
3524 if (context->request_id == pData->requestId) {
3525 context->response_status = pData->status ? -EINVAL : 0;
3526 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303527 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303528 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303529
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303530 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303531 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303532}
3533
Dino Mycle6fb96c12014-06-10 11:52:40 +05303534static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3535 void *pMsg)
3536{
3537 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303538 tpSirEXTScanSetBssidHotListRspParams pData =
3539 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303540 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303541
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303542 ENTER();
3543
3544 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303545 return;
3546 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303547
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303548 if (!pMsg)
3549 {
3550 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3551 return;
3552 }
3553
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303554 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3555 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303556
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303557 context = &pHddCtx->ext_scan_context;
3558 spin_lock(&hdd_context_lock);
3559 if (context->request_id == pData->requestId) {
3560 context->response_status = pData->status ? -EINVAL : 0;
3561 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303562 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303563 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303564
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303565 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303566 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303567}
3568
3569static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3570 void *pMsg)
3571{
3572 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303573 tpSirEXTScanResetBssidHotlistRspParams pData =
3574 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303575 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303576
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303577 ENTER();
3578
3579 if (wlan_hdd_validate_context(pHddCtx)) {
3580 return;
3581 }
3582 if (!pMsg)
3583 {
3584 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303585 return;
3586 }
3587
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303588 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3589 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303590
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303591 context = &pHddCtx->ext_scan_context;
3592 spin_lock(&hdd_context_lock);
3593 if (context->request_id == pData->requestId) {
3594 context->response_status = pData->status ? -EINVAL : 0;
3595 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303596 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303597 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303598
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303599 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303600 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303601}
3602
Dino Mycle6fb96c12014-06-10 11:52:40 +05303603static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3604 void *pMsg)
3605{
3606 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3607 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303608 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303609 tANI_S32 totalResults;
3610 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303611 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3612 struct hdd_ext_scan_context *context;
3613 bool ignore_cached_results = false;
3614 tExtscanCachedScanResult *result;
3615 struct nlattr *nla_results;
3616 tANI_U16 ieLength= 0;
3617 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303618
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303619 ENTER();
3620
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303621 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303622 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303623
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303624 if (!pMsg)
3625 {
3626 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3627 return;
3628 }
3629
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303630 spin_lock(&hdd_context_lock);
3631 context = &pHddCtx->ext_scan_context;
3632 ignore_cached_results = context->ignore_cached_results;
3633 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303634
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303635 if (ignore_cached_results) {
3636 hddLog(LOGE,
3637 FL("Ignore the cached results received after timeout"));
3638 return;
3639 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303640
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303641 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3642 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303643
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303644 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303645
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303646 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3647 scan_id_index++) {
3648 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303649
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303650 totalResults = result->num_results;
3651 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3652 result->scan_id, result->flags, totalResults);
3653 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303654
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303655 do{
3656 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3657 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3658 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303659
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303660 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3661 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3662
3663 if (!skb) {
3664 hddLog(VOS_TRACE_LEVEL_ERROR,
3665 FL("cfg80211_vendor_event_alloc failed"));
3666 return;
3667 }
3668
3669 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3670
3671 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3672 pData->requestId) ||
3673 nla_put_u32(skb,
3674 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3675 resultsPerEvent)) {
3676 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3677 goto fail;
3678 }
3679 if (nla_put_u8(skb,
3680 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3681 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303682 {
3683 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3684 goto fail;
3685 }
3686
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303687 if (nla_put_u32(skb,
3688 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3689 result->scan_id)) {
3690 hddLog(LOGE, FL("put fail"));
3691 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303692 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303693
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303694 nla_results = nla_nest_start(skb,
3695 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3696 if (!nla_results)
3697 goto fail;
3698
3699 if (resultsPerEvent) {
3700 struct nlattr *aps;
3701 struct nlattr *nla_result;
3702
3703 nla_result = nla_nest_start(skb, scan_id_index);
3704 if(!nla_result)
3705 goto fail;
3706
3707 if (nla_put_u32(skb,
3708 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3709 result->scan_id) ||
3710 nla_put_u32(skb,
3711 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3712 result->flags) ||
3713 nla_put_u32(skb,
3714 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3715 totalResults)) {
3716 hddLog(LOGE, FL("put fail"));
3717 goto fail;
3718 }
3719
3720 aps = nla_nest_start(skb,
3721 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3722 if (!aps)
3723 {
3724 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3725 goto fail;
3726 }
3727
3728 head_ptr = (tpSirWifiScanResult) &(result->ap);
3729
3730 for (j = 0; j < resultsPerEvent; j++, i++) {
3731 struct nlattr *ap;
3732 pSirWifiScanResult = head_ptr + i;
3733
3734 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303735 * Firmware returns timestamp from extscan_start till
3736 * BSSID was cached (in micro seconds). Add this with
3737 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303738 * to derive the time since boot when the
3739 * BSSID was cached.
3740 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303741 pSirWifiScanResult->ts +=
3742 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303743 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3744 "Ssid (%s)"
3745 "Bssid: %pM "
3746 "Channel (%u)"
3747 "Rssi (%d)"
3748 "RTT (%u)"
3749 "RTT_SD (%u)"
3750 "Beacon Period %u"
3751 "Capability 0x%x "
3752 "Ie length %d",
3753 i,
3754 pSirWifiScanResult->ts,
3755 pSirWifiScanResult->ssid,
3756 pSirWifiScanResult->bssid,
3757 pSirWifiScanResult->channel,
3758 pSirWifiScanResult->rssi,
3759 pSirWifiScanResult->rtt,
3760 pSirWifiScanResult->rtt_sd,
3761 pSirWifiScanResult->beaconPeriod,
3762 pSirWifiScanResult->capability,
3763 ieLength);
3764
3765 ap = nla_nest_start(skb, j + 1);
3766 if (!ap)
3767 {
3768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3769 goto fail;
3770 }
3771
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303772 if (hdd_wlan_nla_put_u64(skb,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303773 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3774 pSirWifiScanResult->ts) )
3775 {
3776 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3777 goto fail;
3778 }
3779 if (nla_put(skb,
3780 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3781 sizeof(pSirWifiScanResult->ssid),
3782 pSirWifiScanResult->ssid) )
3783 {
3784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3785 goto fail;
3786 }
3787 if (nla_put(skb,
3788 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3789 sizeof(pSirWifiScanResult->bssid),
3790 pSirWifiScanResult->bssid) )
3791 {
3792 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3793 goto fail;
3794 }
3795 if (nla_put_u32(skb,
3796 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3797 pSirWifiScanResult->channel) )
3798 {
3799 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3800 goto fail;
3801 }
3802 if (nla_put_s32(skb,
3803 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3804 pSirWifiScanResult->rssi) )
3805 {
3806 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3807 goto fail;
3808 }
3809 if (nla_put_u32(skb,
3810 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3811 pSirWifiScanResult->rtt) )
3812 {
3813 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3814 goto fail;
3815 }
3816 if (nla_put_u32(skb,
3817 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3818 pSirWifiScanResult->rtt_sd))
3819 {
3820 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3821 goto fail;
3822 }
3823 if (nla_put_u32(skb,
3824 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3825 pSirWifiScanResult->beaconPeriod))
3826 {
3827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3828 goto fail;
3829 }
3830 if (nla_put_u32(skb,
3831 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3832 pSirWifiScanResult->capability))
3833 {
3834 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3835 goto fail;
3836 }
3837 if (nla_put_u32(skb,
3838 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3839 ieLength))
3840 {
3841 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3842 goto fail;
3843 }
3844
3845 if (ieLength)
3846 if (nla_put(skb,
3847 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3848 ieLength, ie)) {
3849 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3850 goto fail;
3851 }
3852
3853 nla_nest_end(skb, ap);
3854 }
3855 nla_nest_end(skb, aps);
3856 nla_nest_end(skb, nla_result);
3857 }
3858
3859 nla_nest_end(skb, nla_results);
3860
3861 cfg80211_vendor_cmd_reply(skb);
3862
3863 } while (totalResults > 0);
3864 }
3865
3866 if (!pData->moreData) {
3867 spin_lock(&hdd_context_lock);
3868 context->response_status = 0;
3869 complete(&context->response_event);
3870 spin_unlock(&hdd_context_lock);
3871 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303872
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303873 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303874 return;
3875fail:
3876 kfree_skb(skb);
3877 return;
3878}
3879
3880static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3881 void *pMsg)
3882{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303883 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303884 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3885 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303886 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303887
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303888 ENTER();
3889
3890 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303891 hddLog(LOGE,
3892 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303893 return;
3894 }
3895 if (!pMsg)
3896 {
3897 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303898 return;
3899 }
3900
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303901 if (pData->bss_found)
3902 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3903 else
3904 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3905
Dino Mycle6fb96c12014-06-10 11:52:40 +05303906 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303907#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3908 NULL,
3909#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303910 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303911 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303912
3913 if (!skb) {
3914 hddLog(VOS_TRACE_LEVEL_ERROR,
3915 FL("cfg80211_vendor_event_alloc failed"));
3916 return;
3917 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303918
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303919 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3920 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3921 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3922 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3923
3924 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303925 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3926 "Ssid (%s) "
3927 "Bssid (" MAC_ADDRESS_STR ") "
3928 "Channel (%u) "
3929 "Rssi (%d) "
3930 "RTT (%u) "
3931 "RTT_SD (%u) ",
3932 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303933 pData->bssHotlist[i].ts,
3934 pData->bssHotlist[i].ssid,
3935 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3936 pData->bssHotlist[i].channel,
3937 pData->bssHotlist[i].rssi,
3938 pData->bssHotlist[i].rtt,
3939 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303940 }
3941
3942 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3943 pData->requestId) ||
3944 nla_put_u32(skb,
3945 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303946 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303947 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3948 goto fail;
3949 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303950 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303951 struct nlattr *aps;
3952
3953 aps = nla_nest_start(skb,
3954 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3955 if (!aps)
3956 goto fail;
3957
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303958 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303959 struct nlattr *ap;
3960
3961 ap = nla_nest_start(skb, i + 1);
3962 if (!ap)
3963 goto fail;
3964
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303965 if (hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303966 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303967 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303968 nla_put(skb,
3969 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303970 sizeof(pData->bssHotlist[i].ssid),
3971 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303972 nla_put(skb,
3973 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303974 sizeof(pData->bssHotlist[i].bssid),
3975 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303976 nla_put_u32(skb,
3977 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303978 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303979 nla_put_s32(skb,
3980 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303981 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303982 nla_put_u32(skb,
3983 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303984 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303985 nla_put_u32(skb,
3986 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303987 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303988 goto fail;
3989
3990 nla_nest_end(skb, ap);
3991 }
3992 nla_nest_end(skb, aps);
3993
3994 if (nla_put_u8(skb,
3995 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3996 pData->moreData))
3997 goto fail;
3998 }
3999
4000 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304001 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304002 return;
4003
4004fail:
4005 kfree_skb(skb);
4006 return;
4007
4008}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304009
4010static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
4011 void *pMsg)
4012{
4013 struct sk_buff *skb;
4014 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4015 tpSirWifiFullScanResultEvent pData =
4016 (tpSirWifiFullScanResultEvent) (pMsg);
4017
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304018 ENTER();
4019
4020 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304021 hddLog(LOGE,
4022 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304023 return;
4024 }
4025 if (!pMsg)
4026 {
4027 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304028 return;
4029 }
4030
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304031 /*
4032 * If the full scan result including IE data exceeds NL 4K size
4033 * limitation, drop that beacon/probe rsp frame.
4034 */
4035 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
4036 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
4037 return;
4038 }
4039
Dino Mycle6fb96c12014-06-10 11:52:40 +05304040 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304041#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4042 NULL,
4043#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304044 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4045 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
4046 GFP_KERNEL);
4047
4048 if (!skb) {
4049 hddLog(VOS_TRACE_LEVEL_ERROR,
4050 FL("cfg80211_vendor_event_alloc failed"));
4051 return;
4052 }
4053
Dino Mycle6fb96c12014-06-10 11:52:40 +05304054 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
4055 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
4056 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
4057 "Ssid (%s)"
4058 "Bssid (" MAC_ADDRESS_STR ")"
4059 "Channel (%u)"
4060 "Rssi (%d)"
4061 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304062 "RTT_SD (%u)"
4063 "Bcn Period %d"
4064 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05304065 pData->ap.ts,
4066 pData->ap.ssid,
4067 MAC_ADDR_ARRAY(pData->ap.bssid),
4068 pData->ap.channel,
4069 pData->ap.rssi,
4070 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304071 pData->ap.rtt_sd,
4072 pData->ap.beaconPeriod,
4073 pData->ap.capability);
4074
Dino Mycle6fb96c12014-06-10 11:52:40 +05304075 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
4076 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4077 pData->requestId) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304078 hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304079 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
4080 pData->ap.ts) ||
4081 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
4082 sizeof(pData->ap.ssid),
4083 pData->ap.ssid) ||
4084 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
4085 WNI_CFG_BSSID_LEN,
4086 pData->ap.bssid) ||
4087 nla_put_u32(skb,
4088 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
4089 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05304090 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304091 pData->ap.rssi) ||
4092 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
4093 pData->ap.rtt) ||
4094 nla_put_u32(skb,
4095 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
4096 pData->ap.rtt_sd) ||
4097 nla_put_u16(skb,
4098 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
4099 pData->ap.beaconPeriod) ||
4100 nla_put_u16(skb,
4101 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
4102 pData->ap.capability) ||
4103 nla_put_u32(skb,
4104 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304105 pData->ieLength) ||
4106 nla_put_u8(skb,
4107 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
4108 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304109 {
4110 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4111 goto nla_put_failure;
4112 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304113
4114 if (pData->ieLength) {
4115 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
4116 pData->ieLength,
4117 pData->ie))
4118 {
4119 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4120 goto nla_put_failure;
4121 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304122 }
4123
4124 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304125 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304126 return;
4127
4128nla_put_failure:
4129 kfree_skb(skb);
4130 return;
4131}
4132
4133static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
4134 void *pMsg)
4135{
4136 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4137 struct sk_buff *skb = NULL;
4138 tpSirEXTScanResultsAvailableIndParams pData =
4139 (tpSirEXTScanResultsAvailableIndParams) pMsg;
4140
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304141 ENTER();
4142
4143 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304144 hddLog(LOGE,
4145 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304146 return;
4147 }
4148 if (!pMsg)
4149 {
4150 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304151 return;
4152 }
4153
4154 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304155#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4156 NULL,
4157#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304158 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4159 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
4160 GFP_KERNEL);
4161
4162 if (!skb) {
4163 hddLog(VOS_TRACE_LEVEL_ERROR,
4164 FL("cfg80211_vendor_event_alloc failed"));
4165 return;
4166 }
4167
Dino Mycle6fb96c12014-06-10 11:52:40 +05304168 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
4169 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
4170 pData->numResultsAvailable);
4171 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4172 pData->requestId) ||
4173 nla_put_u32(skb,
4174 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
4175 pData->numResultsAvailable)) {
4176 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4177 goto nla_put_failure;
4178 }
4179
4180 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304181 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304182 return;
4183
4184nla_put_failure:
4185 kfree_skb(skb);
4186 return;
4187}
4188
4189static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
4190{
4191 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4192 struct sk_buff *skb = NULL;
4193 tpSirEXTScanProgressIndParams pData =
4194 (tpSirEXTScanProgressIndParams) pMsg;
4195
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304196 ENTER();
4197
4198 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304199 hddLog(LOGE,
4200 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304201 return;
4202 }
4203 if (!pMsg)
4204 {
4205 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304206 return;
4207 }
4208
4209 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304210#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4211 NULL,
4212#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304213 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4214 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
4215 GFP_KERNEL);
4216
4217 if (!skb) {
4218 hddLog(VOS_TRACE_LEVEL_ERROR,
4219 FL("cfg80211_vendor_event_alloc failed"));
4220 return;
4221 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304222 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304223 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
4224 pData->extScanEventType);
4225 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
4226 pData->status);
4227
4228 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
4229 pData->extScanEventType) ||
4230 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05304231 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4232 pData->requestId) ||
4233 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304234 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
4235 pData->status)) {
4236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4237 goto nla_put_failure;
4238 }
4239
4240 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304241 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304242 return;
4243
4244nla_put_failure:
4245 kfree_skb(skb);
4246 return;
4247}
4248
4249void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
4250 void *pMsg)
4251{
4252 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4253
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304254 ENTER();
4255
Dino Mycle6fb96c12014-06-10 11:52:40 +05304256 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304257 return;
4258 }
4259
4260 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
4261
4262
4263 switch(evType) {
4264 case SIR_HAL_EXTSCAN_START_RSP:
4265 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
4266 break;
4267
4268 case SIR_HAL_EXTSCAN_STOP_RSP:
4269 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
4270 break;
4271 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
4272 /* There is no need to send this response to upper layer
4273 Just log the message */
4274 hddLog(VOS_TRACE_LEVEL_INFO,
4275 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
4276 break;
4277 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
4278 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
4279 break;
4280
4281 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
4282 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
4283 break;
4284
Dino Mycle6fb96c12014-06-10 11:52:40 +05304285 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304286 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304287 break;
4288 case SIR_HAL_EXTSCAN_PROGRESS_IND:
4289 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
4290 break;
4291 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
4292 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
4293 break;
4294 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
4295 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
4296 break;
4297 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
4298 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
4299 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304300 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
4301 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
4302 break;
4303 default:
4304 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
4305 break;
4306 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304307 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304308}
4309
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304310static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4311 struct wireless_dev *wdev,
4312 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304313{
Dino Myclee8843b32014-07-04 14:21:45 +05304314 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304315 struct net_device *dev = wdev->netdev;
4316 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4317 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4318 struct nlattr
4319 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4320 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304321 struct hdd_ext_scan_context *context;
4322 unsigned long rc;
4323 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304324
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304325 ENTER();
4326
Dino Mycle6fb96c12014-06-10 11:52:40 +05304327 status = wlan_hdd_validate_context(pHddCtx);
4328 if (0 != status)
4329 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304330 return -EINVAL;
4331 }
Dino Myclee8843b32014-07-04 14:21:45 +05304332 /* check the EXTScan Capability */
4333 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304334 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4335 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304336 {
4337 hddLog(VOS_TRACE_LEVEL_ERROR,
4338 FL("EXTScan not enabled/supported by Firmware"));
4339 return -EINVAL;
4340 }
4341
Dino Mycle6fb96c12014-06-10 11:52:40 +05304342 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4343 data, dataLen,
4344 wlan_hdd_extscan_config_policy)) {
4345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4346 return -EINVAL;
4347 }
4348
4349 /* Parse and fetch request Id */
4350 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4352 return -EINVAL;
4353 }
4354
Dino Myclee8843b32014-07-04 14:21:45 +05304355 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304356 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304357 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304358
Dino Myclee8843b32014-07-04 14:21:45 +05304359 reqMsg.sessionId = pAdapter->sessionId;
4360 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304361
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304362 vos_spin_lock_acquire(&hdd_context_lock);
4363 context = &pHddCtx->ext_scan_context;
4364 context->request_id = reqMsg.requestId;
4365 INIT_COMPLETION(context->response_event);
4366 vos_spin_lock_release(&hdd_context_lock);
4367
Dino Myclee8843b32014-07-04 14:21:45 +05304368 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304369 if (!HAL_STATUS_SUCCESS(status)) {
4370 hddLog(VOS_TRACE_LEVEL_ERROR,
4371 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304372 return -EINVAL;
4373 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304374
4375 rc = wait_for_completion_timeout(&context->response_event,
4376 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4377 if (!rc) {
4378 hddLog(LOGE, FL("Target response timed out"));
4379 return -ETIMEDOUT;
4380 }
4381
4382 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
4383 if (ret)
4384 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
4385
4386 return ret;
4387
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304388 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304389 return 0;
4390}
4391
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304392static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4393 struct wireless_dev *wdev,
4394 const void *data, int dataLen)
4395{
4396 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304397
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304398 vos_ssr_protect(__func__);
4399 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
4400 vos_ssr_unprotect(__func__);
4401
4402 return ret;
4403}
4404
4405static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4406 struct wireless_dev *wdev,
4407 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304408{
Dino Myclee8843b32014-07-04 14:21:45 +05304409 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304410 struct net_device *dev = wdev->netdev;
4411 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4412 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4413 struct nlattr
4414 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4415 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304416 struct hdd_ext_scan_context *context;
4417 unsigned long rc;
4418 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304419
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304420 ENTER();
4421
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304422 if (VOS_FTM_MODE == hdd_get_conparam()) {
4423 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4424 return -EINVAL;
4425 }
4426
Dino Mycle6fb96c12014-06-10 11:52:40 +05304427 status = wlan_hdd_validate_context(pHddCtx);
4428 if (0 != status)
4429 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304430 return -EINVAL;
4431 }
Dino Myclee8843b32014-07-04 14:21:45 +05304432 /* check the EXTScan Capability */
4433 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304434 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4435 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304436 {
4437 hddLog(VOS_TRACE_LEVEL_ERROR,
4438 FL("EXTScan not enabled/supported by Firmware"));
4439 return -EINVAL;
4440 }
4441
Dino Mycle6fb96c12014-06-10 11:52:40 +05304442 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4443 data, dataLen,
4444 wlan_hdd_extscan_config_policy)) {
4445 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4446 return -EINVAL;
4447 }
4448 /* Parse and fetch request Id */
4449 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4450 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4451 return -EINVAL;
4452 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304453
Dino Myclee8843b32014-07-04 14:21:45 +05304454 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304455 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4456
Dino Myclee8843b32014-07-04 14:21:45 +05304457 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304458
Dino Myclee8843b32014-07-04 14:21:45 +05304459 reqMsg.sessionId = pAdapter->sessionId;
4460 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304461
4462 /* Parse and fetch flush parameter */
4463 if (!tb
4464 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
4465 {
4466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
4467 goto failed;
4468 }
Dino Myclee8843b32014-07-04 14:21:45 +05304469 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304470 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
4471
Dino Myclee8843b32014-07-04 14:21:45 +05304472 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304473
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304474 spin_lock(&hdd_context_lock);
4475 context = &pHddCtx->ext_scan_context;
4476 context->request_id = reqMsg.requestId;
4477 context->ignore_cached_results = false;
4478 INIT_COMPLETION(context->response_event);
4479 spin_unlock(&hdd_context_lock);
4480
Dino Myclee8843b32014-07-04 14:21:45 +05304481 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304482 if (!HAL_STATUS_SUCCESS(status)) {
4483 hddLog(VOS_TRACE_LEVEL_ERROR,
4484 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304485 return -EINVAL;
4486 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304487
4488 rc = wait_for_completion_timeout(&context->response_event,
4489 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4490 if (!rc) {
4491 hddLog(LOGE, FL("Target response timed out"));
4492 retval = -ETIMEDOUT;
4493 spin_lock(&hdd_context_lock);
4494 context->ignore_cached_results = true;
4495 spin_unlock(&hdd_context_lock);
4496 } else {
4497 spin_lock(&hdd_context_lock);
4498 retval = context->response_status;
4499 spin_unlock(&hdd_context_lock);
4500 }
4501
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304502 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304503 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304504
4505failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05304506 return -EINVAL;
4507}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304508static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4509 struct wireless_dev *wdev,
4510 const void *data, int dataLen)
4511{
4512 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304513
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304514 vos_ssr_protect(__func__);
4515 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
4516 vos_ssr_unprotect(__func__);
4517
4518 return ret;
4519}
4520
4521static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304522 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05304523 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304524{
4525 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
4526 struct net_device *dev = wdev->netdev;
4527 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4528 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4529 struct nlattr
4530 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4531 struct nlattr
4532 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4533 struct nlattr *apTh;
4534 eHalStatus status;
4535 tANI_U8 i = 0;
4536 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304537 struct hdd_ext_scan_context *context;
4538 tANI_U32 request_id;
4539 unsigned long rc;
4540 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304541
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304542 ENTER();
4543
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304544 if (VOS_FTM_MODE == hdd_get_conparam()) {
4545 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4546 return -EINVAL;
4547 }
4548
Dino Mycle6fb96c12014-06-10 11:52:40 +05304549 status = wlan_hdd_validate_context(pHddCtx);
4550 if (0 != status)
4551 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304552 return -EINVAL;
4553 }
Dino Myclee8843b32014-07-04 14:21:45 +05304554 /* check the EXTScan Capability */
4555 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304556 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4557 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304558 {
4559 hddLog(VOS_TRACE_LEVEL_ERROR,
4560 FL("EXTScan not enabled/supported by Firmware"));
4561 return -EINVAL;
4562 }
4563
Dino Mycle6fb96c12014-06-10 11:52:40 +05304564 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4565 data, dataLen,
4566 wlan_hdd_extscan_config_policy)) {
4567 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4568 return -EINVAL;
4569 }
4570
4571 /* Parse and fetch request Id */
4572 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4573 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4574 return -EINVAL;
4575 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304576 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4577 vos_mem_malloc(sizeof(*pReqMsg));
4578 if (!pReqMsg) {
4579 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4580 return -ENOMEM;
4581 }
4582
Dino Myclee8843b32014-07-04 14:21:45 +05304583
Dino Mycle6fb96c12014-06-10 11:52:40 +05304584 pReqMsg->requestId = nla_get_u32(
4585 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4586 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4587
4588 /* Parse and fetch number of APs */
4589 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4590 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4591 goto fail;
4592 }
4593
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304594 /* Parse and fetch lost ap sample size */
4595 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4596 hddLog(LOGE, FL("attr lost ap sample size failed"));
4597 goto fail;
4598 }
4599
4600 pReqMsg->lostBssidSampleSize = nla_get_u32(
4601 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4602 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4603
Dino Mycle6fb96c12014-06-10 11:52:40 +05304604 pReqMsg->sessionId = pAdapter->sessionId;
4605 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4606
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304607 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304608 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304609 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4610 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4611 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4612 goto fail;
4613 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304614 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304615
4616 nla_for_each_nested(apTh,
4617 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304618 if (i == pReqMsg->numBssid) {
4619 hddLog(LOGW, FL("Ignoring excess AP"));
4620 break;
4621 }
4622
Dino Mycle6fb96c12014-06-10 11:52:40 +05304623 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4624 nla_data(apTh), nla_len(apTh),
4625 NULL)) {
4626 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4627 goto fail;
4628 }
4629
4630 /* Parse and fetch MAC address */
4631 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4632 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4633 goto fail;
4634 }
4635 memcpy(pReqMsg->ap[i].bssid, nla_data(
4636 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4637 sizeof(tSirMacAddr));
4638 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4639
4640 /* Parse and fetch low RSSI */
4641 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4642 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4643 goto fail;
4644 }
4645 pReqMsg->ap[i].low = nla_get_s32(
4646 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4647 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4648
4649 /* Parse and fetch high RSSI */
4650 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4651 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4652 goto fail;
4653 }
4654 pReqMsg->ap[i].high = nla_get_s32(
4655 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4656 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4657 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304658 i++;
4659 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304660
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304661 if (i < pReqMsg->numBssid) {
4662 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4663 i, pReqMsg->numBssid);
4664 pReqMsg->numBssid = i;
4665 }
4666
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304667 context = &pHddCtx->ext_scan_context;
4668 spin_lock(&hdd_context_lock);
4669 INIT_COMPLETION(context->response_event);
4670 context->request_id = request_id = pReqMsg->requestId;
4671 spin_unlock(&hdd_context_lock);
4672
Dino Mycle6fb96c12014-06-10 11:52:40 +05304673 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4674 if (!HAL_STATUS_SUCCESS(status)) {
4675 hddLog(VOS_TRACE_LEVEL_ERROR,
4676 FL("sme_SetBssHotlist failed(err=%d)"), status);
4677 vos_mem_free(pReqMsg);
4678 return -EINVAL;
4679 }
4680
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304681 /* request was sent -- wait for the response */
4682 rc = wait_for_completion_timeout(&context->response_event,
4683 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4684
4685 if (!rc) {
4686 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4687 retval = -ETIMEDOUT;
4688 } else {
4689 spin_lock(&hdd_context_lock);
4690 if (context->request_id == request_id)
4691 retval = context->response_status;
4692 else
4693 retval = -EINVAL;
4694 spin_unlock(&hdd_context_lock);
4695 }
4696
Dino Myclee8843b32014-07-04 14:21:45 +05304697 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304698 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304699 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304700
4701fail:
4702 vos_mem_free(pReqMsg);
4703 return -EINVAL;
4704}
4705
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304706static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4707 struct wireless_dev *wdev,
4708 const void *data, int dataLen)
4709{
4710 int ret = 0;
4711
4712 vos_ssr_protect(__func__);
4713 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4714 dataLen);
4715 vos_ssr_unprotect(__func__);
4716
4717 return ret;
4718}
4719
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304720static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304721 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304722 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304723{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304724 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4725 struct net_device *dev = wdev->netdev;
4726 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4727 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4728 uint8_t num_channels = 0;
4729 uint8_t num_chan_new = 0;
4730 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304731 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304732 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304733 tWifiBand wifiBand;
4734 eHalStatus status;
4735 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304736 tANI_U8 i,j,k;
4737 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304738
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304739 ENTER();
4740
Dino Mycle6fb96c12014-06-10 11:52:40 +05304741 status = wlan_hdd_validate_context(pHddCtx);
4742 if (0 != status)
4743 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304744 return -EINVAL;
4745 }
Dino Myclee8843b32014-07-04 14:21:45 +05304746
Dino Mycle6fb96c12014-06-10 11:52:40 +05304747 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4748 data, dataLen,
4749 wlan_hdd_extscan_config_policy)) {
4750 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4751 return -EINVAL;
4752 }
4753
4754 /* Parse and fetch request Id */
4755 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4757 return -EINVAL;
4758 }
4759 requestId = nla_get_u32(
4760 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4761 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4762
4763 /* Parse and fetch wifi band */
4764 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4765 {
4766 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4767 return -EINVAL;
4768 }
4769 wifiBand = nla_get_u32(
4770 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4771 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4772
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304773 /* Parse and fetch max channels */
4774 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4775 {
4776 hddLog(LOGE, FL("attr max channels failed"));
4777 return -EINVAL;
4778 }
4779 maxChannels = nla_get_u32(
4780 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4781 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4782
Dino Mycle6fb96c12014-06-10 11:52:40 +05304783 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304784 wifiBand, chan_list,
4785 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304786 if (eHAL_STATUS_SUCCESS != status) {
4787 hddLog(VOS_TRACE_LEVEL_ERROR,
4788 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4789 return -EINVAL;
4790 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304791
Agrawal Ashish16abf782016-08-18 22:42:59 +05304792 num_channels = VOS_MIN(num_channels, maxChannels);
4793 num_chan_new = num_channels;
4794 /* remove the indoor only channels if iface is SAP */
4795 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4796 {
4797 num_chan_new = 0;
4798 for (i = 0; i < num_channels; i++)
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304799 for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) {
Agrawal Ashish16abf782016-08-18 22:42:59 +05304800 if (wiphy->bands[j] == NULL)
4801 continue;
4802 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4803 if ((chan_list[i] ==
4804 wiphy->bands[j]->channels[k].center_freq) &&
4805 (!(wiphy->bands[j]->channels[k].flags &
4806 IEEE80211_CHAN_INDOOR_ONLY))) {
4807 chan_list[num_chan_new] = chan_list[i];
4808 num_chan_new++;
4809 }
4810 }
4811 }
4812 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304813
Agrawal Ashish16abf782016-08-18 22:42:59 +05304814 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4815 for (i = 0; i < num_chan_new; i++)
4816 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4817 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304818
4819 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304820 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304821 NLMSG_HDRLEN);
4822
4823 if (!replySkb) {
4824 hddLog(VOS_TRACE_LEVEL_ERROR,
4825 FL("valid channels: buffer alloc fail"));
4826 return -EINVAL;
4827 }
4828 if (nla_put_u32(replySkb,
4829 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304830 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304831 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304832 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304833
4834 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4835 kfree_skb(replySkb);
4836 return -EINVAL;
4837 }
4838
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304839 ret = cfg80211_vendor_cmd_reply(replySkb);
4840
4841 EXIT();
4842 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304843}
4844
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304845static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4846 struct wireless_dev *wdev,
4847 const void *data, int dataLen)
4848{
4849 int ret = 0;
4850
4851 vos_ssr_protect(__func__);
4852 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4853 dataLen);
4854 vos_ssr_unprotect(__func__);
4855
4856 return ret;
4857}
4858
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304859static int hdd_extscan_start_fill_bucket_channel_spec(
4860 hdd_context_t *pHddCtx,
4861 tpSirEXTScanStartReqParams pReqMsg,
4862 struct nlattr **tb)
4863{
4864 struct nlattr *bucket[
4865 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4866 struct nlattr *channel[
4867 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4868 struct nlattr *buckets;
4869 struct nlattr *channels;
4870 int rem1, rem2;
4871 eHalStatus status;
4872 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304873 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304874 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4875 tANI_U32 passive_max_chn_time, active_max_chn_time;
4876
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304877 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304878 bktIndex = 0;
4879
4880 nla_for_each_nested(buckets,
4881 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304882 if (bktIndex >= expected_buckets) {
4883 hddLog(LOGW, FL("ignoring excess buckets"));
4884 break;
4885 }
4886
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304887 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304888 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4889 nla_data(buckets), nla_len(buckets),
4890 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304891 hddLog(LOGE, FL("nla_parse failed"));
4892 return -EINVAL;
4893 }
4894
4895 /* Parse and fetch bucket spec */
4896 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4897 hddLog(LOGE, FL("attr bucket index failed"));
4898 return -EINVAL;
4899 }
4900 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4901 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4902 hddLog(LOG1, FL("Bucket spec Index %d"),
4903 pReqMsg->buckets[bktIndex].bucket);
4904
4905 /* Parse and fetch wifi band */
4906 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4907 hddLog(LOGE, FL("attr wifi band failed"));
4908 return -EINVAL;
4909 }
4910 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4911 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4912 hddLog(LOG1, FL("Wifi band %d"),
4913 pReqMsg->buckets[bktIndex].band);
4914
4915 /* Parse and fetch period */
4916 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4917 hddLog(LOGE, FL("attr period failed"));
4918 return -EINVAL;
4919 }
4920 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4921 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4922 hddLog(LOG1, FL("period %d"),
4923 pReqMsg->buckets[bktIndex].period);
4924
4925 /* Parse and fetch report events */
4926 if (!bucket[
4927 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4928 hddLog(LOGE, FL("attr report events failed"));
4929 return -EINVAL;
4930 }
4931 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4932 bucket[
4933 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4934 hddLog(LOG1, FL("report events %d"),
4935 pReqMsg->buckets[bktIndex].reportEvents);
4936
4937 /* Parse and fetch max period */
4938 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4939 hddLog(LOGE, FL("attr max period failed"));
4940 return -EINVAL;
4941 }
4942 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4943 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4944 hddLog(LOG1, FL("max period %u"),
4945 pReqMsg->buckets[bktIndex].max_period);
4946
4947 /* Parse and fetch exponent */
4948 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4949 hddLog(LOGE, FL("attr exponent failed"));
4950 return -EINVAL;
4951 }
4952 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4953 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4954 hddLog(LOG1, FL("exponent %u"),
4955 pReqMsg->buckets[bktIndex].exponent);
4956
4957 /* Parse and fetch step count */
4958 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4959 hddLog(LOGE, FL("attr step count failed"));
4960 return -EINVAL;
4961 }
4962 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4963 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4964 hddLog(LOG1, FL("Step count %u"),
4965 pReqMsg->buckets[bktIndex].step_count);
4966
4967 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4968 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4969
4970 /* Framework shall pass the channel list if the input WiFi band is
4971 * WIFI_BAND_UNSPECIFIED.
4972 * If the input WiFi band is specified (any value other than
4973 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4974 */
4975 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4976 numChannels = 0;
4977 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4978 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4979 pReqMsg->buckets[bktIndex].band,
4980 chanList, &numChannels);
4981 if (!HAL_STATUS_SUCCESS(status)) {
4982 hddLog(LOGE,
4983 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4984 status);
4985 return -EINVAL;
4986 }
4987
4988 pReqMsg->buckets[bktIndex].numChannels =
4989 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4990 hddLog(LOG1, FL("Num channels %d"),
4991 pReqMsg->buckets[bktIndex].numChannels);
4992
4993 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4994 j++) {
4995 pReqMsg->buckets[bktIndex].channels[j].channel =
4996 chanList[j];
4997 pReqMsg->buckets[bktIndex].channels[j].
4998 chnlClass = 0;
4999 if (CSR_IS_CHANNEL_DFS(
5000 vos_freq_to_chan(chanList[j]))) {
5001 pReqMsg->buckets[bktIndex].channels[j].
5002 passive = 1;
5003 pReqMsg->buckets[bktIndex].channels[j].
5004 dwellTimeMs = passive_max_chn_time;
5005 } else {
5006 pReqMsg->buckets[bktIndex].channels[j].
5007 passive = 0;
5008 pReqMsg->buckets[bktIndex].channels[j].
5009 dwellTimeMs = active_max_chn_time;
5010 }
5011
5012 hddLog(LOG1,
5013 "Channel %u Passive %u Dwell time %u ms",
5014 pReqMsg->buckets[bktIndex].channels[j].channel,
5015 pReqMsg->buckets[bktIndex].channels[j].passive,
5016 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5017 }
5018
5019 bktIndex++;
5020 continue;
5021 }
5022
5023 /* Parse and fetch number of channels */
5024 if (!bucket[
5025 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
5026 hddLog(LOGE, FL("attr num channels failed"));
5027 return -EINVAL;
5028 }
5029
5030 pReqMsg->buckets[bktIndex].numChannels =
5031 nla_get_u32(bucket[
5032 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
5033 hddLog(LOG1, FL("num channels %d"),
5034 pReqMsg->buckets[bktIndex].numChannels);
5035
5036 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
5037 hddLog(LOGE, FL("attr channel spec failed"));
5038 return -EINVAL;
5039 }
5040
5041 j = 0;
5042 nla_for_each_nested(channels,
5043 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
5044 if (nla_parse(channel,
5045 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5046 nla_data(channels), nla_len(channels),
5047 wlan_hdd_extscan_config_policy)) {
5048 hddLog(LOGE, FL("nla_parse failed"));
5049 return -EINVAL;
5050 }
5051
5052 /* Parse and fetch channel */
5053 if (!channel[
5054 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
5055 hddLog(LOGE, FL("attr channel failed"));
5056 return -EINVAL;
5057 }
5058 pReqMsg->buckets[bktIndex].channels[j].channel =
5059 nla_get_u32(channel[
5060 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
5061 hddLog(LOG1, FL("channel %u"),
5062 pReqMsg->buckets[bktIndex].channels[j].channel);
5063
5064 /* Parse and fetch dwell time */
5065 if (!channel[
5066 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
5067 hddLog(LOGE, FL("attr dwelltime failed"));
5068 return -EINVAL;
5069 }
5070 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
5071 nla_get_u32(channel[
5072 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
5073
5074 hddLog(LOG1, FL("Dwell time (%u ms)"),
5075 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5076
5077
5078 /* Parse and fetch channel spec passive */
5079 if (!channel[
5080 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
5081 hddLog(LOGE,
5082 FL("attr channel spec passive failed"));
5083 return -EINVAL;
5084 }
5085 pReqMsg->buckets[bktIndex].channels[j].passive =
5086 nla_get_u8(channel[
5087 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
5088 hddLog(LOG1, FL("Chnl spec passive %u"),
5089 pReqMsg->buckets[bktIndex].channels[j].passive);
5090
5091 j++;
5092 }
5093
5094 bktIndex++;
5095 }
5096
5097 return 0;
5098}
5099
5100
5101/*
5102 * define short names for the global vendor params
5103 * used by wlan_hdd_cfg80211_extscan_start()
5104 */
5105#define PARAM_MAX \
5106QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
5107#define PARAM_REQUEST_ID \
5108QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
5109#define PARAM_BASE_PERIOD \
5110QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
5111#define PARAM_MAX_AP_PER_SCAN \
5112QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
5113#define PARAM_RPT_THRHLD_PERCENT \
5114QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
5115#define PARAM_RPT_THRHLD_NUM_SCANS \
5116QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
5117#define PARAM_NUM_BUCKETS \
5118QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
5119
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305120static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305121 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305122 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305123{
Dino Myclee8843b32014-07-04 14:21:45 +05305124 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305125 struct net_device *dev = wdev->netdev;
5126 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5127 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5128 struct nlattr *tb[PARAM_MAX + 1];
5129 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305130 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305131 tANI_U32 request_id;
5132 struct hdd_ext_scan_context *context;
5133 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305134
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305135 ENTER();
5136
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305137 if (VOS_FTM_MODE == hdd_get_conparam()) {
5138 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5139 return -EINVAL;
5140 }
5141
Dino Mycle6fb96c12014-06-10 11:52:40 +05305142 status = wlan_hdd_validate_context(pHddCtx);
5143 if (0 != status)
5144 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305145 return -EINVAL;
5146 }
Dino Myclee8843b32014-07-04 14:21:45 +05305147 /* check the EXTScan Capability */
5148 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305149 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5150 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305151 {
5152 hddLog(VOS_TRACE_LEVEL_ERROR,
5153 FL("EXTScan not enabled/supported by Firmware"));
5154 return -EINVAL;
5155 }
5156
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305157 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305158 data, dataLen,
5159 wlan_hdd_extscan_config_policy)) {
5160 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5161 return -EINVAL;
5162 }
5163
5164 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305165 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305166 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5167 return -EINVAL;
5168 }
5169
Dino Myclee8843b32014-07-04 14:21:45 +05305170 pReqMsg = (tpSirEXTScanStartReqParams)
5171 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305172 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305173 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5174 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305175 }
5176
5177 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305178 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305179 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5180
5181 pReqMsg->sessionId = pAdapter->sessionId;
5182 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5183
5184 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305185 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305186 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5187 goto fail;
5188 }
5189 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305190 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305191 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5192 pReqMsg->basePeriod);
5193
5194 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305195 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305196 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5197 goto fail;
5198 }
5199 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305200 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305201 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5202 pReqMsg->maxAPperScan);
5203
5204 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305205 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305206 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5207 goto fail;
5208 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305209 pReqMsg->reportThresholdPercent = nla_get_u8(
5210 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305211 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305212 pReqMsg->reportThresholdPercent);
5213
5214 /* Parse and fetch report threshold num scans */
5215 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5216 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5217 goto fail;
5218 }
5219 pReqMsg->reportThresholdNumScans = nla_get_u8(
5220 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5221 hddLog(LOG1, FL("Report Threshold num scans %d"),
5222 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305223
5224 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305225 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305226 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5227 goto fail;
5228 }
5229 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305230 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305231 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5232 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5233 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5234 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5235 }
5236 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5237 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305238
Dino Mycle6fb96c12014-06-10 11:52:40 +05305239 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5240 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5241 goto fail;
5242 }
5243
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305244 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305245
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305246 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5247 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305248
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305249 context = &pHddCtx->ext_scan_context;
5250 spin_lock(&hdd_context_lock);
5251 INIT_COMPLETION(context->response_event);
5252 context->request_id = request_id = pReqMsg->requestId;
5253 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305254
Dino Mycle6fb96c12014-06-10 11:52:40 +05305255 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5256 if (!HAL_STATUS_SUCCESS(status)) {
5257 hddLog(VOS_TRACE_LEVEL_ERROR,
5258 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305259 goto fail;
5260 }
5261
Srinivas Dasari91727c12016-03-23 17:59:06 +05305262 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5263
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305264 /* request was sent -- wait for the response */
5265 rc = wait_for_completion_timeout(&context->response_event,
5266 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5267
5268 if (!rc) {
5269 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5270 retval = -ETIMEDOUT;
5271 } else {
5272 spin_lock(&hdd_context_lock);
5273 if (context->request_id == request_id)
5274 retval = context->response_status;
5275 else
5276 retval = -EINVAL;
5277 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305278 }
5279
Dino Myclee8843b32014-07-04 14:21:45 +05305280 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305281 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305282 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305283
5284fail:
5285 vos_mem_free(pReqMsg);
5286 return -EINVAL;
5287}
5288
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305289/*
5290 * done with short names for the global vendor params
5291 * used by wlan_hdd_cfg80211_extscan_start()
5292 */
5293#undef PARAM_MAX
5294#undef PARAM_REQUEST_ID
5295#undef PARAM_BASE_PERIOD
5296#undef PARAMS_MAX_AP_PER_SCAN
5297#undef PARAMS_RPT_THRHLD_PERCENT
5298#undef PARAMS_RPT_THRHLD_NUM_SCANS
5299#undef PARAMS_NUM_BUCKETS
5300
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305301static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5302 struct wireless_dev *wdev,
5303 const void *data, int dataLen)
5304{
5305 int ret = 0;
5306
5307 vos_ssr_protect(__func__);
5308 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5309 vos_ssr_unprotect(__func__);
5310
5311 return ret;
5312}
5313
5314static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305315 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305316 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305317{
Dino Myclee8843b32014-07-04 14:21:45 +05305318 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305319 struct net_device *dev = wdev->netdev;
5320 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5321 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5322 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5323 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305324 int retval;
5325 unsigned long rc;
5326 struct hdd_ext_scan_context *context;
5327 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305328
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305329 ENTER();
5330
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305331 if (VOS_FTM_MODE == hdd_get_conparam()) {
5332 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5333 return -EINVAL;
5334 }
5335
Dino Mycle6fb96c12014-06-10 11:52:40 +05305336 status = wlan_hdd_validate_context(pHddCtx);
5337 if (0 != status)
5338 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305339 return -EINVAL;
5340 }
Dino Myclee8843b32014-07-04 14:21:45 +05305341 /* check the EXTScan Capability */
5342 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305343 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5344 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305345 {
5346 hddLog(VOS_TRACE_LEVEL_ERROR,
5347 FL("EXTScan not enabled/supported by Firmware"));
5348 return -EINVAL;
5349 }
5350
Dino Mycle6fb96c12014-06-10 11:52:40 +05305351 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5352 data, dataLen,
5353 wlan_hdd_extscan_config_policy)) {
5354 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5355 return -EINVAL;
5356 }
5357
5358 /* Parse and fetch request Id */
5359 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5360 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5361 return -EINVAL;
5362 }
5363
Dino Myclee8843b32014-07-04 14:21:45 +05305364 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305365 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305366 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305367
Dino Myclee8843b32014-07-04 14:21:45 +05305368 reqMsg.sessionId = pAdapter->sessionId;
5369 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305370
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305371 context = &pHddCtx->ext_scan_context;
5372 spin_lock(&hdd_context_lock);
5373 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305374 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305375 spin_unlock(&hdd_context_lock);
5376
Dino Myclee8843b32014-07-04 14:21:45 +05305377 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305378 if (!HAL_STATUS_SUCCESS(status)) {
5379 hddLog(VOS_TRACE_LEVEL_ERROR,
5380 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305381 return -EINVAL;
5382 }
5383
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305384 /* request was sent -- wait for the response */
5385 rc = wait_for_completion_timeout(&context->response_event,
5386 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5387
5388 if (!rc) {
5389 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5390 retval = -ETIMEDOUT;
5391 } else {
5392 spin_lock(&hdd_context_lock);
5393 if (context->request_id == request_id)
5394 retval = context->response_status;
5395 else
5396 retval = -EINVAL;
5397 spin_unlock(&hdd_context_lock);
5398 }
5399
5400 return retval;
5401
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305402 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305403 return 0;
5404}
5405
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305406static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5407 struct wireless_dev *wdev,
5408 const void *data, int dataLen)
5409{
5410 int ret = 0;
5411
5412 vos_ssr_protect(__func__);
5413 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5414 vos_ssr_unprotect(__func__);
5415
5416 return ret;
5417}
5418
5419static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305420 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305421 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305422{
Dino Myclee8843b32014-07-04 14:21:45 +05305423 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305424 struct net_device *dev = wdev->netdev;
5425 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5426 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5427 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5428 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305429 struct hdd_ext_scan_context *context;
5430 tANI_U32 request_id;
5431 unsigned long rc;
5432 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305433
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305434 ENTER();
5435
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305436 if (VOS_FTM_MODE == hdd_get_conparam()) {
5437 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5438 return -EINVAL;
5439 }
5440
Dino Mycle6fb96c12014-06-10 11:52:40 +05305441 status = wlan_hdd_validate_context(pHddCtx);
5442 if (0 != status)
5443 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305444 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305445 return -EINVAL;
5446 }
Dino Myclee8843b32014-07-04 14:21:45 +05305447 /* check the EXTScan Capability */
5448 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305449 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5450 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305451 {
5452 hddLog(VOS_TRACE_LEVEL_ERROR,
5453 FL("EXTScan not enabled/supported by Firmware"));
5454 return -EINVAL;
5455 }
5456
Dino Mycle6fb96c12014-06-10 11:52:40 +05305457 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5458 data, dataLen,
5459 wlan_hdd_extscan_config_policy)) {
5460 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5461 return -EINVAL;
5462 }
5463
5464 /* Parse and fetch request Id */
5465 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5467 return -EINVAL;
5468 }
5469
Dino Myclee8843b32014-07-04 14:21:45 +05305470 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305471 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305472 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305473
Dino Myclee8843b32014-07-04 14:21:45 +05305474 reqMsg.sessionId = pAdapter->sessionId;
5475 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305476
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305477 context = &pHddCtx->ext_scan_context;
5478 spin_lock(&hdd_context_lock);
5479 INIT_COMPLETION(context->response_event);
5480 context->request_id = request_id = reqMsg.requestId;
5481 spin_unlock(&hdd_context_lock);
5482
Dino Myclee8843b32014-07-04 14:21:45 +05305483 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305484 if (!HAL_STATUS_SUCCESS(status)) {
5485 hddLog(VOS_TRACE_LEVEL_ERROR,
5486 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305487 return -EINVAL;
5488 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305489
5490 /* request was sent -- wait for the response */
5491 rc = wait_for_completion_timeout(&context->response_event,
5492 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5493 if (!rc) {
5494 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5495 retval = -ETIMEDOUT;
5496 } else {
5497 spin_lock(&hdd_context_lock);
5498 if (context->request_id == request_id)
5499 retval = context->response_status;
5500 else
5501 retval = -EINVAL;
5502 spin_unlock(&hdd_context_lock);
5503 }
5504
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305505 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305506 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305507}
5508
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305509static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5510 struct wireless_dev *wdev,
5511 const void *data, int dataLen)
5512{
5513 int ret = 0;
5514
5515 vos_ssr_protect(__func__);
5516 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5517 vos_ssr_unprotect(__func__);
5518
5519 return ret;
5520}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305521#endif /* WLAN_FEATURE_EXTSCAN */
5522
Atul Mittal115287b2014-07-08 13:26:33 +05305523/*EXT TDLS*/
5524static const struct nla_policy
5525wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5526{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305527 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5528 .type = NLA_UNSPEC,
5529 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305530 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5531 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5532 {.type = NLA_S32 },
5533 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5534 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5535
5536};
5537
5538static const struct nla_policy
5539wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5540{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305541 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5542 .type = NLA_UNSPEC,
5543 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305544
5545};
5546
5547static const struct nla_policy
5548wlan_hdd_tdls_config_state_change_policy[
5549 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5550{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305551 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5552 .type = NLA_UNSPEC,
5553 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305554 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5555 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305556 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5557 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5558 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305559
5560};
5561
5562static const struct nla_policy
5563wlan_hdd_tdls_config_get_status_policy[
5564 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5565{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305566 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5567 .type = NLA_UNSPEC,
5568 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305569 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5570 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305571 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5572 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5573 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305574
5575};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305576
5577static const struct nla_policy
5578wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5579{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305580 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5581 .type = NLA_UNSPEC,
5582 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305583};
5584
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305585static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305586 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305587 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305588 int data_len)
5589{
5590
5591 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5592 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5593
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305594 ENTER();
5595
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305596 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305597 return -EINVAL;
5598 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305599 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305600 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305601 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305602 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305603 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305604 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305605 return -ENOTSUPP;
5606 }
5607
5608 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5609 data, data_len, wlan_hdd_mac_config)) {
5610 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5611 return -EINVAL;
5612 }
5613
5614 /* Parse and fetch mac address */
5615 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5616 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5617 return -EINVAL;
5618 }
5619
5620 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5621 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5622 VOS_MAC_ADDR_LAST_3_BYTES);
5623
Siddharth Bhal76972212014-10-15 16:22:51 +05305624 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5625
5626 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305627 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5628 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305629 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5630 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5631 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5632 {
5633 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5634 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5635 VOS_MAC_ADDRESS_LEN);
5636 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305637 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305638
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305639 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5640 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305641
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305642 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305643 return 0;
5644}
5645
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305646static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5647 struct wireless_dev *wdev,
5648 const void *data,
5649 int data_len)
5650{
5651 int ret = 0;
5652
5653 vos_ssr_protect(__func__);
5654 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5655 vos_ssr_unprotect(__func__);
5656
5657 return ret;
5658}
5659
5660static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305661 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305662 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305663 int data_len)
5664{
5665 u8 peer[6] = {0};
5666 struct net_device *dev = wdev->netdev;
5667 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5668 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5669 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5670 eHalStatus ret;
5671 tANI_S32 state;
5672 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305673 tANI_S32 global_operating_class = 0;
5674 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305675 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305676 int retVal;
5677
5678 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305679
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305680 if (!pAdapter) {
5681 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5682 return -EINVAL;
5683 }
5684
Atul Mittal115287b2014-07-08 13:26:33 +05305685 ret = wlan_hdd_validate_context(pHddCtx);
5686 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305687 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305688 return -EINVAL;
5689 }
5690 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305691 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305692 return -ENOTSUPP;
5693 }
5694 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5695 data, data_len,
5696 wlan_hdd_tdls_config_get_status_policy)) {
5697 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5698 return -EINVAL;
5699 }
5700
5701 /* Parse and fetch mac address */
5702 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5703 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5704 return -EINVAL;
5705 }
5706
5707 memcpy(peer, nla_data(
5708 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5709 sizeof(peer));
5710 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5711
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305712 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305713
Atul Mittal115287b2014-07-08 13:26:33 +05305714 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305715 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305716 NLMSG_HDRLEN);
5717
5718 if (!skb) {
5719 hddLog(VOS_TRACE_LEVEL_ERROR,
5720 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5721 return -EINVAL;
5722 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305723 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05305724 reason,
5725 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305726 global_operating_class,
5727 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305728 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305729 if (nla_put_s32(skb,
5730 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5731 state) ||
5732 nla_put_s32(skb,
5733 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5734 reason) ||
5735 nla_put_s32(skb,
5736 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5737 global_operating_class) ||
5738 nla_put_s32(skb,
5739 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5740 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305741
5742 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5743 goto nla_put_failure;
5744 }
5745
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305746 retVal = cfg80211_vendor_cmd_reply(skb);
5747 EXIT();
5748 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305749
5750nla_put_failure:
5751 kfree_skb(skb);
5752 return -EINVAL;
5753}
5754
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305755static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5756 struct wireless_dev *wdev,
5757 const void *data,
5758 int data_len)
5759{
5760 int ret = 0;
5761
5762 vos_ssr_protect(__func__);
5763 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5764 vos_ssr_unprotect(__func__);
5765
5766 return ret;
5767}
5768
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305769static int wlan_hdd_cfg80211_exttdls_callback(
5770#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5771 const tANI_U8* mac,
5772#else
5773 tANI_U8* mac,
5774#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305775 tANI_S32 state,
5776 tANI_S32 reason,
5777 void *ctx)
5778{
5779 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305780 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305781 tANI_S32 global_operating_class = 0;
5782 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305783 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305784
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305785 ENTER();
5786
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305787 if (!pAdapter) {
5788 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5789 return -EINVAL;
5790 }
5791
5792 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305793 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305795 return -EINVAL;
5796 }
5797
5798 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305799 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305800 return -ENOTSUPP;
5801 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305802 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5803#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5804 NULL,
5805#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305806 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5807 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5808 GFP_KERNEL);
5809
5810 if (!skb) {
5811 hddLog(VOS_TRACE_LEVEL_ERROR,
5812 FL("cfg80211_vendor_event_alloc failed"));
5813 return -EINVAL;
5814 }
5815 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305816 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5817 reason,
5818 state,
5819 global_operating_class,
5820 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305821 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5822 MAC_ADDR_ARRAY(mac));
5823
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305824 if (nla_put(skb,
5825 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5826 VOS_MAC_ADDR_SIZE, mac) ||
5827 nla_put_s32(skb,
5828 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5829 state) ||
5830 nla_put_s32(skb,
5831 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5832 reason) ||
5833 nla_put_s32(skb,
5834 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5835 channel) ||
5836 nla_put_s32(skb,
5837 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5838 global_operating_class)
5839 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305840 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5841 goto nla_put_failure;
5842 }
5843
5844 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305845 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305846 return (0);
5847
5848nla_put_failure:
5849 kfree_skb(skb);
5850 return -EINVAL;
5851}
5852
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305853static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305854 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305855 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305856 int data_len)
5857{
5858 u8 peer[6] = {0};
5859 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305860 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5861 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5862 eHalStatus status;
5863 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305864 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305865 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305866
5867 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305868
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305869 if (!dev) {
5870 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5871 return -EINVAL;
5872 }
5873
5874 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5875 if (!pAdapter) {
5876 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5877 return -EINVAL;
5878 }
5879
Atul Mittal115287b2014-07-08 13:26:33 +05305880 status = wlan_hdd_validate_context(pHddCtx);
5881 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305882 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305883 return -EINVAL;
5884 }
5885 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305886 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305887 return -ENOTSUPP;
5888 }
5889 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5890 data, data_len,
5891 wlan_hdd_tdls_config_enable_policy)) {
5892 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5893 return -EINVAL;
5894 }
5895
5896 /* Parse and fetch mac address */
5897 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5898 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5899 return -EINVAL;
5900 }
5901
5902 memcpy(peer, nla_data(
5903 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5904 sizeof(peer));
5905 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5906
5907 /* Parse and fetch channel */
5908 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5909 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5910 return -EINVAL;
5911 }
5912 pReqMsg.channel = nla_get_s32(
5913 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5914 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5915
5916 /* Parse and fetch global operating class */
5917 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5918 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5919 return -EINVAL;
5920 }
5921 pReqMsg.global_operating_class = nla_get_s32(
5922 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5923 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5924 pReqMsg.global_operating_class);
5925
5926 /* Parse and fetch latency ms */
5927 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5928 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5929 return -EINVAL;
5930 }
5931 pReqMsg.max_latency_ms = nla_get_s32(
5932 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5933 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5934 pReqMsg.max_latency_ms);
5935
5936 /* Parse and fetch required bandwidth kbps */
5937 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5939 return -EINVAL;
5940 }
5941
5942 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5943 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5944 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5945 pReqMsg.min_bandwidth_kbps);
5946
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305947 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305948 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305949 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305950 wlan_hdd_cfg80211_exttdls_callback);
5951
5952 EXIT();
5953 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305954}
5955
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305956static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5957 struct wireless_dev *wdev,
5958 const void *data,
5959 int data_len)
5960{
5961 int ret = 0;
5962
5963 vos_ssr_protect(__func__);
5964 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5965 vos_ssr_unprotect(__func__);
5966
5967 return ret;
5968}
5969
5970static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305971 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305972 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305973 int data_len)
5974{
5975 u8 peer[6] = {0};
5976 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305977 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5978 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5979 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305980 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305981 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305982
5983 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305984
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305985 if (!dev) {
5986 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5987 return -EINVAL;
5988 }
5989
5990 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5991 if (!pAdapter) {
5992 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5993 return -EINVAL;
5994 }
5995
Atul Mittal115287b2014-07-08 13:26:33 +05305996 status = wlan_hdd_validate_context(pHddCtx);
5997 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305998 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305999 return -EINVAL;
6000 }
6001 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05306002 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05306003 return -ENOTSUPP;
6004 }
6005 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
6006 data, data_len,
6007 wlan_hdd_tdls_config_disable_policy)) {
6008 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6009 return -EINVAL;
6010 }
6011 /* Parse and fetch mac address */
6012 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
6013 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
6014 return -EINVAL;
6015 }
6016
6017 memcpy(peer, nla_data(
6018 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
6019 sizeof(peer));
6020 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
6021
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306022 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
6023
6024 EXIT();
6025 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05306026}
6027
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306028static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
6029 struct wireless_dev *wdev,
6030 const void *data,
6031 int data_len)
6032{
6033 int ret = 0;
6034
6035 vos_ssr_protect(__func__);
6036 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
6037 vos_ssr_unprotect(__func__);
6038
6039 return ret;
6040}
6041
Dasari Srinivas7875a302014-09-26 17:50:57 +05306042static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306043__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05306044 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306045 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05306046{
6047 struct net_device *dev = wdev->netdev;
6048 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6049 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6050 struct sk_buff *skb = NULL;
6051 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306052 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306053
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306054 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306055
6056 ret = wlan_hdd_validate_context(pHddCtx);
6057 if (0 != ret)
6058 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306059 return ret;
6060 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306061 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
6062 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
6063 fset |= WIFI_FEATURE_INFRA;
6064 }
6065
6066 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
6067 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
6068 fset |= WIFI_FEATURE_INFRA_5G;
6069 }
6070
6071#ifdef WLAN_FEATURE_P2P
6072 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
6073 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
6074 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
6075 fset |= WIFI_FEATURE_P2P;
6076 }
6077#endif
6078
6079 /* Soft-AP is supported currently by default */
6080 fset |= WIFI_FEATURE_SOFT_AP;
6081
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05306082 /* HOTSPOT is a supplicant feature, enable it by default */
6083 fset |= WIFI_FEATURE_HOTSPOT;
6084
Dasari Srinivas7875a302014-09-26 17:50:57 +05306085#ifdef WLAN_FEATURE_EXTSCAN
6086 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05306087 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
6088 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
6089 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306090 fset |= WIFI_FEATURE_EXTSCAN;
6091 }
6092#endif
6093
Dasari Srinivas7875a302014-09-26 17:50:57 +05306094 if (sme_IsFeatureSupportedByFW(NAN)) {
6095 hddLog(LOG1, FL("NAN is supported by firmware"));
6096 fset |= WIFI_FEATURE_NAN;
6097 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306098
6099 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05306100 if (sme_IsFeatureSupportedByFW(RTT) &&
6101 pHddCtx->cfg_ini->enable_rtt_support) {
6102 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306103 fset |= WIFI_FEATURE_D2AP_RTT;
6104 }
6105
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05306106 if (sme_IsFeatureSupportedByFW(RTT3)) {
6107 hddLog(LOG1, FL("RTT3 is supported by firmware"));
6108 fset |= WIFI_FEATURE_RTT3;
6109 }
6110
Dasari Srinivas7875a302014-09-26 17:50:57 +05306111#ifdef FEATURE_WLAN_BATCH_SCAN
6112 if (fset & WIFI_FEATURE_EXTSCAN) {
6113 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
6114 fset &= ~WIFI_FEATURE_BATCH_SCAN;
6115 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
6116 hddLog(LOG1, FL("Batch scan is supported by firmware"));
6117 fset |= WIFI_FEATURE_BATCH_SCAN;
6118 }
6119#endif
6120
6121#ifdef FEATURE_WLAN_SCAN_PNO
6122 if (pHddCtx->cfg_ini->configPNOScanSupport &&
6123 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
6124 hddLog(LOG1, FL("PNO is supported by firmware"));
6125 fset |= WIFI_FEATURE_PNO;
6126 }
6127#endif
6128
6129 /* STA+STA is supported currently by default */
6130 fset |= WIFI_FEATURE_ADDITIONAL_STA;
6131
6132#ifdef FEATURE_WLAN_TDLS
6133 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6134 sme_IsFeatureSupportedByFW(TDLS)) {
6135 hddLog(LOG1, FL("TDLS is supported by firmware"));
6136 fset |= WIFI_FEATURE_TDLS;
6137 }
6138
6139 /* TDLS_OFFCHANNEL is not supported currently by default */
6140#endif
6141
6142#ifdef WLAN_AP_STA_CONCURRENCY
6143 /* AP+STA concurrency is supported currently by default */
6144 fset |= WIFI_FEATURE_AP_STA;
6145#endif
6146
Mukul Sharma5add0532015-08-17 15:57:47 +05306147#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306148 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6149 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306150 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6151 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306152 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306153#endif
6154
Dasari Srinivas7875a302014-09-26 17:50:57 +05306155 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6156 NLMSG_HDRLEN);
6157
6158 if (!skb) {
6159 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6160 return -EINVAL;
6161 }
6162 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6163
6164 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6165 hddLog(LOGE, FL("nla put fail"));
6166 goto nla_put_failure;
6167 }
6168
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306169 ret = cfg80211_vendor_cmd_reply(skb);
6170 EXIT();
6171 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306172
6173nla_put_failure:
6174 kfree_skb(skb);
6175 return -EINVAL;
6176}
6177
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306178static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306179wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6180 struct wireless_dev *wdev,
6181 const void *data, int data_len)
6182{
6183 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306184 vos_ssr_protect(__func__);
6185 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6186 vos_ssr_unprotect(__func__);
6187
6188 return ret;
6189}
6190
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306191
6192static const struct
6193nla_policy
6194qca_wlan_vendor_wifi_logger_get_ring_data_policy
6195[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6196 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6197 = {.type = NLA_U32 },
6198};
6199
6200static int
6201 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6202 struct wireless_dev *wdev,
6203 const void *data,
6204 int data_len)
6205{
6206 int ret;
6207 VOS_STATUS status;
6208 uint32_t ring_id;
6209 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6210 struct nlattr *tb
6211 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6212
6213 ENTER();
6214
6215 ret = wlan_hdd_validate_context(hdd_ctx);
6216 if (0 != ret) {
6217 return ret;
6218 }
6219
6220 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6221 data, data_len,
6222 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6223 hddLog(LOGE, FL("Invalid attribute"));
6224 return -EINVAL;
6225 }
6226
6227 /* Parse and fetch ring id */
6228 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6229 hddLog(LOGE, FL("attr ATTR failed"));
6230 return -EINVAL;
6231 }
6232
6233 ring_id = nla_get_u32(
6234 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6235
6236 hddLog(LOG1, FL("Bug report triggered by framework"));
6237
6238 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6239 WLAN_LOG_INDICATOR_FRAMEWORK,
6240 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306241 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306242 );
6243 if (VOS_STATUS_SUCCESS != status) {
6244 hddLog(LOGE, FL("Failed to trigger bug report"));
6245
6246 return -EINVAL;
6247 }
6248
6249 return 0;
6250
6251
6252}
6253
6254
6255static int
6256 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6257 struct wireless_dev *wdev,
6258 const void *data,
6259 int data_len)
6260{
6261 int ret = 0;
6262
6263 vos_ssr_protect(__func__);
6264 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6265 wdev, data, data_len);
6266 vos_ssr_unprotect(__func__);
6267
6268 return ret;
6269
6270}
6271
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306272#define MAX_CONCURRENT_MATRIX \
6273 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6274#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6275 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6276static const struct nla_policy
6277wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6278 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6279};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306280
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306281static int
6282__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306283 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306284 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306285{
6286 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6287 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306288 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306289 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306290 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6291 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306292
6293 ENTER();
6294
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306295 ret = wlan_hdd_validate_context(pHddCtx);
6296 if (0 != ret)
6297 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306298 return ret;
6299 }
6300
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306301 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6302 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306303 hddLog(LOGE, FL("Invalid ATTR"));
6304 return -EINVAL;
6305 }
6306
6307 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306308 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306309 hddLog(LOGE, FL("Attr max feature set size failed"));
6310 return -EINVAL;
6311 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306312 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306313 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6314
6315 /* Fill feature combination matrix */
6316 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306317 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6318 WIFI_FEATURE_P2P;
6319
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306320 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6321 WIFI_FEATURE_SOFT_AP;
6322
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306323 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6324 WIFI_FEATURE_SOFT_AP;
6325
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306326 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6327 WIFI_FEATURE_SOFT_AP |
6328 WIFI_FEATURE_P2P;
6329
6330 /* Add more feature combinations here */
6331
6332 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6333 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6334 hddLog(LOG1, "Feature set matrix");
6335 for (i = 0; i < feature_sets; i++)
6336 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6337
6338 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6339 sizeof(u32) * feature_sets +
6340 NLMSG_HDRLEN);
6341
6342 if (reply_skb) {
6343 if (nla_put_u32(reply_skb,
6344 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6345 feature_sets) ||
6346 nla_put(reply_skb,
6347 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6348 sizeof(u32) * feature_sets, feature_set_matrix)) {
6349 hddLog(LOGE, FL("nla put fail"));
6350 kfree_skb(reply_skb);
6351 return -EINVAL;
6352 }
6353
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306354 ret = cfg80211_vendor_cmd_reply(reply_skb);
6355 EXIT();
6356 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306357 }
6358 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6359 return -ENOMEM;
6360
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306361}
6362
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306363#undef MAX_CONCURRENT_MATRIX
6364#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6365
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306366static int
6367wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6368 struct wireless_dev *wdev,
6369 const void *data, int data_len)
6370{
6371 int ret = 0;
6372
6373 vos_ssr_protect(__func__);
6374 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6375 data_len);
6376 vos_ssr_unprotect(__func__);
6377
6378 return ret;
6379}
6380
c_manjeecfd1efb2015-09-25 19:32:34 +05306381
6382static int
6383__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6384 struct wireless_dev *wdev,
6385 const void *data, int data_len)
6386{
6387 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6388 int ret;
6389 ENTER();
6390
6391 ret = wlan_hdd_validate_context(pHddCtx);
6392 if (0 != ret)
6393 {
6394 return ret;
6395 }
6396
6397 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6398 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6399 {
6400 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306401 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306402 }
6403 /*call common API for FW mem dump req*/
6404 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6405
Abhishek Singhc783fa72015-12-09 18:07:34 +05306406 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306407 {
6408 /*indicate to userspace the status of fw mem dump */
6409 wlan_indicate_mem_dump_complete(true);
6410 }
6411 else
6412 {
6413 /*else send failure to userspace */
6414 wlan_indicate_mem_dump_complete(false);
6415 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306416 EXIT();
6417 return ret;
6418}
6419
6420/**
6421 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6422 * @wiphy: pointer to wireless wiphy structure.
6423 * @wdev: pointer to wireless_dev structure.
6424 * @data: Pointer to the NL data.
6425 * @data_len:Length of @data
6426 *
6427 * This is called when wlan driver needs to get the firmware memory dump
6428 * via vendor specific command.
6429 *
6430 * Return: 0 on success, error number otherwise.
6431 */
6432
6433static int
6434wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6435 struct wireless_dev *wdev,
6436 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306437{
6438 int ret = 0;
6439 vos_ssr_protect(__func__);
6440 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6441 data_len);
6442 vos_ssr_unprotect(__func__);
6443 return ret;
6444}
c_manjeecfd1efb2015-09-25 19:32:34 +05306445
Sushant Kaushik8e644982015-09-23 12:18:54 +05306446static const struct
6447nla_policy
6448qca_wlan_vendor_wifi_logger_start_policy
6449[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6450 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6451 = {.type = NLA_U32 },
6452 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6453 = {.type = NLA_U32 },
6454 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6455 = {.type = NLA_U32 },
6456};
6457
6458/**
6459 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6460 * or disable the collection of packet statistics from the firmware
6461 * @wiphy: WIPHY structure pointer
6462 * @wdev: Wireless device structure pointer
6463 * @data: Pointer to the data received
6464 * @data_len: Length of the data received
6465 *
6466 * This function is used to enable or disable the collection of packet
6467 * statistics from the firmware
6468 *
6469 * Return: 0 on success and errno on failure
6470 */
6471static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6472 struct wireless_dev *wdev,
6473 const void *data,
6474 int data_len)
6475{
6476 eHalStatus status;
6477 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6478 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6479 tAniWifiStartLog start_log;
6480
6481 status = wlan_hdd_validate_context(hdd_ctx);
6482 if (0 != status) {
6483 return -EINVAL;
6484 }
6485
6486 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6487 data, data_len,
6488 qca_wlan_vendor_wifi_logger_start_policy)) {
6489 hddLog(LOGE, FL("Invalid attribute"));
6490 return -EINVAL;
6491 }
6492
6493 /* Parse and fetch ring id */
6494 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6495 hddLog(LOGE, FL("attr ATTR failed"));
6496 return -EINVAL;
6497 }
6498 start_log.ringId = nla_get_u32(
6499 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6500 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6501
6502 /* Parse and fetch verbose level */
6503 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6504 hddLog(LOGE, FL("attr verbose_level failed"));
6505 return -EINVAL;
6506 }
6507 start_log.verboseLevel = nla_get_u32(
6508 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6509 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6510
6511 /* Parse and fetch flag */
6512 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6513 hddLog(LOGE, FL("attr flag failed"));
6514 return -EINVAL;
6515 }
6516 start_log.flag = nla_get_u32(
6517 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6518 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6519
6520 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306521 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6522 !vos_isPktStatsEnabled()))
6523
Sushant Kaushik8e644982015-09-23 12:18:54 +05306524 {
6525 hddLog(LOGE, FL("per pkt stats not enabled"));
6526 return -EINVAL;
6527 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306528
Sushant Kaushik33200572015-08-05 16:46:20 +05306529 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306530 return 0;
6531}
6532
6533/**
6534 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6535 * or disable the collection of packet statistics from the firmware
6536 * @wiphy: WIPHY structure pointer
6537 * @wdev: Wireless device structure pointer
6538 * @data: Pointer to the data received
6539 * @data_len: Length of the data received
6540 *
6541 * This function is used to enable or disable the collection of packet
6542 * statistics from the firmware
6543 *
6544 * Return: 0 on success and errno on failure
6545 */
6546static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6547 struct wireless_dev *wdev,
6548 const void *data,
6549 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306550{
6551 int ret = 0;
6552
6553 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306554
6555 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6556 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306557 vos_ssr_unprotect(__func__);
6558
6559 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306560}
6561
6562
Agarwal Ashish738843c2014-09-25 12:27:56 +05306563static const struct nla_policy
6564wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6565 +1] =
6566{
6567 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6568};
6569
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306570static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306571 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306572 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306573 int data_len)
6574{
6575 struct net_device *dev = wdev->netdev;
6576 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6577 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6578 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6579 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6580 eHalStatus status;
6581 u32 dfsFlag = 0;
6582
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306583 ENTER();
6584
Agarwal Ashish738843c2014-09-25 12:27:56 +05306585 status = wlan_hdd_validate_context(pHddCtx);
6586 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306587 return -EINVAL;
6588 }
6589 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6590 data, data_len,
6591 wlan_hdd_set_no_dfs_flag_config_policy)) {
6592 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6593 return -EINVAL;
6594 }
6595
6596 /* Parse and fetch required bandwidth kbps */
6597 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6598 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6599 return -EINVAL;
6600 }
6601
6602 dfsFlag = nla_get_u32(
6603 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6604 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6605 dfsFlag);
6606
6607 pHddCtx->disable_dfs_flag = dfsFlag;
6608
6609 sme_disable_dfs_channel(hHal, dfsFlag);
6610 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306611
6612 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306613 return 0;
6614}
Atul Mittal115287b2014-07-08 13:26:33 +05306615
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306616static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6617 struct wireless_dev *wdev,
6618 const void *data,
6619 int data_len)
6620{
6621 int ret = 0;
6622
6623 vos_ssr_protect(__func__);
6624 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6625 vos_ssr_unprotect(__func__);
6626
6627 return ret;
6628
6629}
6630
Mukul Sharma2a271632014-10-13 14:59:01 +05306631const struct
6632nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6633{
6634 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306635 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6636 .type = NLA_UNSPEC,
6637 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306638};
6639
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306640static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306641 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306642{
6643
6644 u8 bssid[6] = {0};
6645 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6646 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6647 eHalStatus status = eHAL_STATUS_SUCCESS;
6648 v_U32_t isFwrRoamEnabled = FALSE;
6649 int ret;
6650
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306651 ENTER();
6652
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306653 ret = wlan_hdd_validate_context(pHddCtx);
6654 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306655 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306656 }
6657
6658 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6659 data, data_len,
6660 qca_wlan_vendor_attr);
6661 if (ret){
6662 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6663 return -EINVAL;
6664 }
6665
6666 /* Parse and fetch Enable flag */
6667 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6668 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6669 return -EINVAL;
6670 }
6671
6672 isFwrRoamEnabled = nla_get_u32(
6673 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6674
6675 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6676
6677 /* Parse and fetch bssid */
6678 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6680 return -EINVAL;
6681 }
6682
6683 memcpy(bssid, nla_data(
6684 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6685 sizeof(bssid));
6686 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6687
6688 //Update roaming
6689 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306690 if (!HAL_STATUS_SUCCESS(status)) {
6691 hddLog(LOGE,
6692 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6693 return -EINVAL;
6694 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306695 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306696 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306697}
6698
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306699static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6700 struct wireless_dev *wdev, const void *data, int data_len)
6701{
6702 int ret = 0;
6703
6704 vos_ssr_protect(__func__);
6705 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6706 vos_ssr_unprotect(__func__);
6707
6708 return ret;
6709}
6710
Sushant Kaushik847890c2015-09-28 16:05:17 +05306711static const struct
6712nla_policy
6713qca_wlan_vendor_get_wifi_info_policy[
6714 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6715 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6716 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6717};
6718
6719
6720/**
6721 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6722 * @wiphy: pointer to wireless wiphy structure.
6723 * @wdev: pointer to wireless_dev structure.
6724 * @data: Pointer to the data to be passed via vendor interface
6725 * @data_len:Length of the data to be passed
6726 *
6727 * This is called when wlan driver needs to send wifi driver related info
6728 * (driver/fw version) to the user space application upon request.
6729 *
6730 * Return: Return the Success or Failure code.
6731 */
6732static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6733 struct wireless_dev *wdev,
6734 const void *data, int data_len)
6735{
6736 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6737 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6738 tSirVersionString version;
6739 uint32 version_len;
6740 uint8 attr;
6741 int status;
6742 struct sk_buff *reply_skb = NULL;
6743
6744 if (VOS_FTM_MODE == hdd_get_conparam()) {
6745 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6746 return -EINVAL;
6747 }
6748
6749 status = wlan_hdd_validate_context(hdd_ctx);
6750 if (0 != status) {
6751 hddLog(LOGE, FL("HDD context is not valid"));
6752 return -EINVAL;
6753 }
6754
6755 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6756 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6757 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6758 return -EINVAL;
6759 }
6760
6761 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6762 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6763 QWLAN_VERSIONSTR);
6764 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6765 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6766 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6767 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6768 hdd_ctx->fw_Version);
6769 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6770 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6771 } else {
6772 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6773 return -EINVAL;
6774 }
6775
6776 version_len = strlen(version);
6777 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6778 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6779 if (!reply_skb) {
6780 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6781 return -ENOMEM;
6782 }
6783
6784 if (nla_put(reply_skb, attr, version_len, version)) {
6785 hddLog(LOGE, FL("nla put fail"));
6786 kfree_skb(reply_skb);
6787 return -EINVAL;
6788 }
6789
6790 return cfg80211_vendor_cmd_reply(reply_skb);
6791}
6792
6793/**
6794 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6795 * @wiphy: pointer to wireless wiphy structure.
6796 * @wdev: pointer to wireless_dev structure.
6797 * @data: Pointer to the data to be passed via vendor interface
6798 * @data_len:Length of the data to be passed
6799 * @data_len: Length of the data received
6800 *
6801 * This function is used to enable or disable the collection of packet
6802 * statistics from the firmware
6803 *
6804 * Return: 0 on success and errno on failure
6805 */
6806
6807static int
6808wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6809 struct wireless_dev *wdev,
6810 const void *data, int data_len)
6811
6812
6813{
6814 int ret = 0;
6815
6816 vos_ssr_protect(__func__);
6817 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6818 wdev, data, data_len);
6819 vos_ssr_unprotect(__func__);
6820
6821 return ret;
6822}
6823
6824
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306825/*
6826 * define short names for the global vendor params
6827 * used by __wlan_hdd_cfg80211_monitor_rssi()
6828 */
6829#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6830#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6831#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6832#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6833#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6834
6835/**---------------------------------------------------------------------------
6836
6837 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6838 monitor start is completed successfully.
6839
6840 \return - None
6841
6842 --------------------------------------------------------------------------*/
6843void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6844{
6845 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6846
6847 if (NULL == pHddCtx)
6848 {
6849 hddLog(VOS_TRACE_LEVEL_ERROR,
6850 "%s: HDD context is NULL",__func__);
6851 return;
6852 }
6853
6854 if (VOS_STATUS_SUCCESS == status)
6855 {
6856 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6857 }
6858 else
6859 {
6860 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6861 }
6862
6863 return;
6864}
6865
6866/**---------------------------------------------------------------------------
6867
6868 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6869 stop is completed successfully.
6870
6871 \return - None
6872
6873 --------------------------------------------------------------------------*/
6874void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6875{
6876 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6877
6878 if (NULL == pHddCtx)
6879 {
6880 hddLog(VOS_TRACE_LEVEL_ERROR,
6881 "%s: HDD context is NULL",__func__);
6882 return;
6883 }
6884
6885 if (VOS_STATUS_SUCCESS == status)
6886 {
6887 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6888 }
6889 else
6890 {
6891 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6892 }
6893
6894 return;
6895}
6896
6897/**
6898 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6899 * @wiphy: Pointer to wireless phy
6900 * @wdev: Pointer to wireless device
6901 * @data: Pointer to data
6902 * @data_len: Data length
6903 *
6904 * Return: 0 on success, negative errno on failure
6905 */
6906
6907static int
6908__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6909 struct wireless_dev *wdev,
6910 const void *data,
6911 int data_len)
6912{
6913 struct net_device *dev = wdev->netdev;
6914 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6915 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6916 hdd_station_ctx_t *pHddStaCtx;
6917 struct nlattr *tb[PARAM_MAX + 1];
6918 tpSirRssiMonitorReq pReq;
6919 eHalStatus status;
6920 int ret;
6921 uint32_t control;
6922 static const struct nla_policy policy[PARAM_MAX + 1] = {
6923 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6924 [PARAM_CONTROL] = { .type = NLA_U32 },
6925 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6926 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6927 };
6928
6929 ENTER();
6930
6931 ret = wlan_hdd_validate_context(hdd_ctx);
6932 if (0 != ret) {
6933 return -EINVAL;
6934 }
6935
6936 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6937 hddLog(LOGE, FL("Not in Connected state!"));
6938 return -ENOTSUPP;
6939 }
6940
6941 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6942 hddLog(LOGE, FL("Invalid ATTR"));
6943 return -EINVAL;
6944 }
6945
6946 if (!tb[PARAM_REQUEST_ID]) {
6947 hddLog(LOGE, FL("attr request id failed"));
6948 return -EINVAL;
6949 }
6950
6951 if (!tb[PARAM_CONTROL]) {
6952 hddLog(LOGE, FL("attr control failed"));
6953 return -EINVAL;
6954 }
6955
6956 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6957
6958 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6959 if(NULL == pReq)
6960 {
6961 hddLog(LOGE,
6962 FL("vos_mem_alloc failed "));
6963 return eHAL_STATUS_FAILED_ALLOC;
6964 }
6965 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6966
6967 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6968 pReq->sessionId = pAdapter->sessionId;
6969 pReq->rssiMonitorCbContext = hdd_ctx;
6970 control = nla_get_u32(tb[PARAM_CONTROL]);
6971 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6972
6973 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6974 pReq->requestId, pReq->sessionId, control);
6975
6976 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6977 if (!tb[PARAM_MIN_RSSI]) {
6978 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306979 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306980 }
6981
6982 if (!tb[PARAM_MAX_RSSI]) {
6983 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306984 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306985 }
6986
6987 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6988 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6989 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6990
6991 if (!(pReq->minRssi < pReq->maxRssi)) {
6992 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6993 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306994 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306995 }
6996 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6997 pReq->minRssi, pReq->maxRssi);
6998 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6999
7000 }
7001 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
7002 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
7003 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
7004 }
7005 else {
7006 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307007 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307008 }
7009
7010 if (!HAL_STATUS_SUCCESS(status)) {
7011 hddLog(LOGE,
7012 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307013 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307014 }
7015
7016 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307017fail:
7018 vos_mem_free(pReq);
7019 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307020}
7021
7022/*
7023 * done with short names for the global vendor params
7024 * used by __wlan_hdd_cfg80211_monitor_rssi()
7025 */
7026#undef PARAM_MAX
7027#undef PARAM_CONTROL
7028#undef PARAM_REQUEST_ID
7029#undef PARAM_MAX_RSSI
7030#undef PARAM_MIN_RSSI
7031
7032/**
7033 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
7034 * @wiphy: wiphy structure pointer
7035 * @wdev: Wireless device structure pointer
7036 * @data: Pointer to the data received
7037 * @data_len: Length of @data
7038 *
7039 * Return: 0 on success; errno on failure
7040 */
7041static int
7042wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
7043 const void *data, int data_len)
7044{
7045 int ret;
7046
7047 vos_ssr_protect(__func__);
7048 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
7049 vos_ssr_unprotect(__func__);
7050
7051 return ret;
7052}
7053
7054/**
7055 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
7056 * @hddctx: HDD context
7057 * @data: rssi breached event data
7058 *
7059 * This function reads the rssi breached event %data and fill in the skb with
7060 * NL attributes and send up the NL event.
7061 * This callback execute in atomic context and must not invoke any
7062 * blocking calls.
7063 *
7064 * Return: none
7065 */
7066void hdd_rssi_threshold_breached_cb(void *hddctx,
7067 struct rssi_breach_event *data)
7068{
7069 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
7070 int status;
7071 struct sk_buff *skb;
7072
7073 ENTER();
7074 status = wlan_hdd_validate_context(pHddCtx);
7075
7076 if (0 != status) {
7077 return;
7078 }
7079
7080 if (!data) {
7081 hddLog(LOGE, FL("data is null"));
7082 return;
7083 }
7084
7085 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
7086#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7087 NULL,
7088#endif
7089 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
7090 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
7091 GFP_KERNEL);
7092
7093 if (!skb) {
7094 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
7095 return;
7096 }
7097
7098 hddLog(LOG1, "Req Id: %u Current rssi: %d",
7099 data->request_id, data->curr_rssi);
7100 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
7101 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
7102
7103 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
7104 data->request_id) ||
7105 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
7106 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
7107 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
7108 data->curr_rssi)) {
7109 hddLog(LOGE, FL("nla put fail"));
7110 goto fail;
7111 }
7112
7113 cfg80211_vendor_event(skb, GFP_KERNEL);
7114 return;
7115
7116fail:
7117 kfree_skb(skb);
7118 return;
7119}
7120
7121
7122
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307123/**
7124 * __wlan_hdd_cfg80211_setband() - set band
7125 * @wiphy: Pointer to wireless phy
7126 * @wdev: Pointer to wireless device
7127 * @data: Pointer to data
7128 * @data_len: Data length
7129 *
7130 * Return: 0 on success, negative errno on failure
7131 */
7132static int
7133__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7134 struct wireless_dev *wdev,
7135 const void *data,
7136 int data_len)
7137{
7138 struct net_device *dev = wdev->netdev;
7139 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7140 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7141 int ret;
7142 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7143 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7144
7145 ENTER();
7146
7147 ret = wlan_hdd_validate_context(hdd_ctx);
7148 if (0 != ret) {
7149 hddLog(LOGE, FL("HDD context is not valid"));
7150 return ret;
7151 }
7152
7153 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7154 policy)) {
7155 hddLog(LOGE, FL("Invalid ATTR"));
7156 return -EINVAL;
7157 }
7158
7159 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7160 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7161 return -EINVAL;
7162 }
7163
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307164 hdd_ctx->isSetBandByNL = TRUE;
7165 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307166 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307167 hdd_ctx->isSetBandByNL = FALSE;
7168
7169 EXIT();
7170 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307171}
7172
7173/**
7174 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7175 * @wiphy: wiphy structure pointer
7176 * @wdev: Wireless device structure pointer
7177 * @data: Pointer to the data received
7178 * @data_len: Length of @data
7179 *
7180 * Return: 0 on success; errno on failure
7181 */
7182static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7183 struct wireless_dev *wdev,
7184 const void *data,
7185 int data_len)
7186{
7187 int ret = 0;
7188
7189 vos_ssr_protect(__func__);
7190 ret = __wlan_hdd_cfg80211_setband(wiphy,
7191 wdev, data, data_len);
7192 vos_ssr_unprotect(__func__);
7193
7194 return ret;
7195}
7196
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307197#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7198/**
7199 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7200 * @hdd_ctx: HDD context
7201 * @request_id: [input] request id
7202 * @pattern_id: [output] pattern id
7203 *
7204 * This function loops through request id to pattern id array
7205 * if the slot is available, store the request id and return pattern id
7206 * if entry exists, return the pattern id
7207 *
7208 * Return: 0 on success and errno on failure
7209 */
7210static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7211 uint32_t request_id,
7212 uint8_t *pattern_id)
7213{
7214 uint32_t i;
7215
7216 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7217 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7218 {
7219 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7220 {
7221 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7222 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7223 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7224 return 0;
7225 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7226 request_id) {
7227 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7228 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7229 return 0;
7230 }
7231 }
7232 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7233 return -EINVAL;
7234}
7235
7236/**
7237 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7238 * @hdd_ctx: HDD context
7239 * @request_id: [input] request id
7240 * @pattern_id: [output] pattern id
7241 *
7242 * This function loops through request id to pattern id array
7243 * reset request id to 0 (slot available again) and
7244 * return pattern id
7245 *
7246 * Return: 0 on success and errno on failure
7247 */
7248static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7249 uint32_t request_id,
7250 uint8_t *pattern_id)
7251{
7252 uint32_t i;
7253
7254 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7255 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7256 {
7257 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7258 {
7259 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7260 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7261 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7262 return 0;
7263 }
7264 }
7265 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7266 return -EINVAL;
7267}
7268
7269
7270/*
7271 * define short names for the global vendor params
7272 * used by __wlan_hdd_cfg80211_offloaded_packets()
7273 */
7274#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7275#define PARAM_REQUEST_ID \
7276 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7277#define PARAM_CONTROL \
7278 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7279#define PARAM_IP_PACKET \
7280 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7281#define PARAM_SRC_MAC_ADDR \
7282 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7283#define PARAM_DST_MAC_ADDR \
7284 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7285#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7286
7287/**
7288 * wlan_hdd_add_tx_ptrn() - add tx pattern
7289 * @adapter: adapter pointer
7290 * @hdd_ctx: hdd context
7291 * @tb: nl attributes
7292 *
7293 * This function reads the NL attributes and forms a AddTxPtrn message
7294 * posts it to SME.
7295 *
7296 */
7297static int
7298wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7299 struct nlattr **tb)
7300{
7301 struct sSirAddPeriodicTxPtrn *add_req;
7302 eHalStatus status;
7303 uint32_t request_id, ret, len;
7304 uint8_t pattern_id = 0;
7305 v_MACADDR_t dst_addr;
7306 uint16_t eth_type = htons(ETH_P_IP);
7307
7308 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7309 {
7310 hddLog(LOGE, FL("Not in Connected state!"));
7311 return -ENOTSUPP;
7312 }
7313
7314 add_req = vos_mem_malloc(sizeof(*add_req));
7315 if (!add_req)
7316 {
7317 hddLog(LOGE, FL("memory allocation failed"));
7318 return -ENOMEM;
7319 }
7320
7321 /* Parse and fetch request Id */
7322 if (!tb[PARAM_REQUEST_ID])
7323 {
7324 hddLog(LOGE, FL("attr request id failed"));
7325 goto fail;
7326 }
7327
7328 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7329 hddLog(LOG1, FL("Request Id: %u"), request_id);
7330 if (request_id == 0)
7331 {
7332 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307333 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307334 }
7335
7336 if (!tb[PARAM_PERIOD])
7337 {
7338 hddLog(LOGE, FL("attr period failed"));
7339 goto fail;
7340 }
7341 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7342 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7343 if (add_req->usPtrnIntervalMs == 0)
7344 {
7345 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7346 goto fail;
7347 }
7348
7349 if (!tb[PARAM_SRC_MAC_ADDR])
7350 {
7351 hddLog(LOGE, FL("attr source mac address failed"));
7352 goto fail;
7353 }
7354 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7355 VOS_MAC_ADDR_SIZE);
7356 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7357 MAC_ADDR_ARRAY(add_req->macAddress));
7358
7359 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7360 VOS_MAC_ADDR_SIZE))
7361 {
7362 hddLog(LOGE,
7363 FL("input src mac address and connected ap bssid are different"));
7364 goto fail;
7365 }
7366
7367 if (!tb[PARAM_DST_MAC_ADDR])
7368 {
7369 hddLog(LOGE, FL("attr dst mac address failed"));
7370 goto fail;
7371 }
7372 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7373 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7374 MAC_ADDR_ARRAY(dst_addr.bytes));
7375
7376 if (!tb[PARAM_IP_PACKET])
7377 {
7378 hddLog(LOGE, FL("attr ip packet failed"));
7379 goto fail;
7380 }
7381 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7382 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7383
7384 if (add_req->ucPtrnSize < 0 ||
7385 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7386 HDD_ETH_HEADER_LEN))
7387 {
7388 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7389 add_req->ucPtrnSize);
7390 goto fail;
7391 }
7392
7393 len = 0;
7394 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7395 len += VOS_MAC_ADDR_SIZE;
7396 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7397 VOS_MAC_ADDR_SIZE);
7398 len += VOS_MAC_ADDR_SIZE;
7399 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7400 len += 2;
7401
7402 /*
7403 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7404 * ------------------------------------------------------------
7405 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7406 * ------------------------------------------------------------
7407 */
7408 vos_mem_copy(&add_req->ucPattern[len],
7409 nla_data(tb[PARAM_IP_PACKET]),
7410 add_req->ucPtrnSize);
7411 add_req->ucPtrnSize += len;
7412
7413 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7414 add_req->ucPattern, add_req->ucPtrnSize);
7415
7416 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7417 if (ret)
7418 {
7419 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7420 goto fail;
7421 }
7422 add_req->ucPtrnId = pattern_id;
7423 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7424
7425 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7426 if (!HAL_STATUS_SUCCESS(status))
7427 {
7428 hddLog(LOGE,
7429 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7430 goto fail;
7431 }
7432
7433 EXIT();
7434 vos_mem_free(add_req);
7435 return 0;
7436
7437fail:
7438 vos_mem_free(add_req);
7439 return -EINVAL;
7440}
7441
7442/**
7443 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7444 * @adapter: adapter pointer
7445 * @hdd_ctx: hdd context
7446 * @tb: nl attributes
7447 *
7448 * This function reads the NL attributes and forms a DelTxPtrn message
7449 * posts it to SME.
7450 *
7451 */
7452static int
7453wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7454 struct nlattr **tb)
7455{
7456 struct sSirDelPeriodicTxPtrn *del_req;
7457 eHalStatus status;
7458 uint32_t request_id, ret;
7459 uint8_t pattern_id = 0;
7460
7461 /* Parse and fetch request Id */
7462 if (!tb[PARAM_REQUEST_ID])
7463 {
7464 hddLog(LOGE, FL("attr request id failed"));
7465 return -EINVAL;
7466 }
7467 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7468 if (request_id == 0)
7469 {
7470 hddLog(LOGE, FL("request_id cannot be zero"));
7471 return -EINVAL;
7472 }
7473
7474 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7475 if (ret)
7476 {
7477 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7478 return -EINVAL;
7479 }
7480
7481 del_req = vos_mem_malloc(sizeof(*del_req));
7482 if (!del_req)
7483 {
7484 hddLog(LOGE, FL("memory allocation failed"));
7485 return -ENOMEM;
7486 }
7487
7488 vos_mem_set(del_req, sizeof(*del_req), 0);
7489 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7490 VOS_MAC_ADDR_SIZE);
7491 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7492 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7493 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7494 request_id, pattern_id, del_req->ucPatternIdBitmap);
7495
7496 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7497 if (!HAL_STATUS_SUCCESS(status))
7498 {
7499 hddLog(LOGE,
7500 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7501 goto fail;
7502 }
7503
7504 EXIT();
7505 vos_mem_free(del_req);
7506 return 0;
7507
7508fail:
7509 vos_mem_free(del_req);
7510 return -EINVAL;
7511}
7512
7513
7514/**
7515 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7516 * @wiphy: Pointer to wireless phy
7517 * @wdev: Pointer to wireless device
7518 * @data: Pointer to data
7519 * @data_len: Data length
7520 *
7521 * Return: 0 on success, negative errno on failure
7522 */
7523static int
7524__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7525 struct wireless_dev *wdev,
7526 const void *data,
7527 int data_len)
7528{
7529 struct net_device *dev = wdev->netdev;
7530 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7531 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7532 struct nlattr *tb[PARAM_MAX + 1];
7533 uint8_t control;
7534 int ret;
7535 static const struct nla_policy policy[PARAM_MAX + 1] =
7536 {
7537 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7538 [PARAM_CONTROL] = { .type = NLA_U32 },
7539 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7540 .len = VOS_MAC_ADDR_SIZE },
7541 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7542 .len = VOS_MAC_ADDR_SIZE },
7543 [PARAM_PERIOD] = { .type = NLA_U32 },
7544 };
7545
7546 ENTER();
7547
7548 ret = wlan_hdd_validate_context(hdd_ctx);
7549 if (0 != ret)
7550 {
7551 hddLog(LOGE, FL("HDD context is not valid"));
7552 return ret;
7553 }
7554
7555 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7556 {
7557 hddLog(LOGE,
7558 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7559 return -ENOTSUPP;
7560 }
7561
7562 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7563 {
7564 hddLog(LOGE, FL("Invalid ATTR"));
7565 return -EINVAL;
7566 }
7567
7568 if (!tb[PARAM_CONTROL])
7569 {
7570 hddLog(LOGE, FL("attr control failed"));
7571 return -EINVAL;
7572 }
7573 control = nla_get_u32(tb[PARAM_CONTROL]);
7574 hddLog(LOG1, FL("Control: %d"), control);
7575
7576 if (control == WLAN_START_OFFLOADED_PACKETS)
7577 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7578 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7579 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7580 else
7581 {
7582 hddLog(LOGE, FL("Invalid control: %d"), control);
7583 return -EINVAL;
7584 }
7585}
7586
7587/*
7588 * done with short names for the global vendor params
7589 * used by __wlan_hdd_cfg80211_offloaded_packets()
7590 */
7591#undef PARAM_MAX
7592#undef PARAM_REQUEST_ID
7593#undef PARAM_CONTROL
7594#undef PARAM_IP_PACKET
7595#undef PARAM_SRC_MAC_ADDR
7596#undef PARAM_DST_MAC_ADDR
7597#undef PARAM_PERIOD
7598
7599/**
7600 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7601 * @wiphy: wiphy structure pointer
7602 * @wdev: Wireless device structure pointer
7603 * @data: Pointer to the data received
7604 * @data_len: Length of @data
7605 *
7606 * Return: 0 on success; errno on failure
7607 */
7608static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7609 struct wireless_dev *wdev,
7610 const void *data,
7611 int data_len)
7612{
7613 int ret = 0;
7614
7615 vos_ssr_protect(__func__);
7616 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7617 wdev, data, data_len);
7618 vos_ssr_unprotect(__func__);
7619
7620 return ret;
7621}
7622#endif
7623
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307624static const struct
7625nla_policy
7626qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307627 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7628 .type = NLA_BINARY,
7629 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307630};
7631
7632/**
7633 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7634 * get link properties like nss, rate flags and operating frequency for
7635 * the connection with the given peer.
7636 * @wiphy: WIPHY structure pointer
7637 * @wdev: Wireless device structure pointer
7638 * @data: Pointer to the data received
7639 * @data_len: Length of the data received
7640 *
7641 * This function return the above link properties on success.
7642 *
7643 * Return: 0 on success and errno on failure
7644 */
7645static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7646 struct wireless_dev *wdev,
7647 const void *data,
7648 int data_len)
7649{
7650 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7651 struct net_device *dev = wdev->netdev;
7652 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7653 hdd_station_ctx_t *hdd_sta_ctx;
7654 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7655 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7656 uint32_t sta_id;
7657 struct sk_buff *reply_skb;
7658 uint32_t rate_flags = 0;
7659 uint8_t nss;
7660 uint8_t final_rate_flags = 0;
7661 uint32_t freq;
7662 v_CONTEXT_t pVosContext = NULL;
7663 ptSapContext pSapCtx = NULL;
7664
7665 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7666 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7667 return -EINVAL;
7668 }
7669
7670 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7671 qca_wlan_vendor_attr_policy)) {
7672 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7673 return -EINVAL;
7674 }
7675
7676 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7677 hddLog(VOS_TRACE_LEVEL_ERROR,
7678 FL("Attribute peerMac not provided for mode=%d"),
7679 adapter->device_mode);
7680 return -EINVAL;
7681 }
7682
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307683 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7684 hddLog(VOS_TRACE_LEVEL_ERROR,
7685 FL("Attribute peerMac is invalid=%d"),
7686 adapter->device_mode);
7687 return -EINVAL;
7688 }
7689
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307690 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7691 sizeof(peer_mac));
7692 hddLog(VOS_TRACE_LEVEL_INFO,
7693 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7694 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7695
7696 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7697 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7698 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7699 if ((hdd_sta_ctx->conn_info.connState !=
7700 eConnectionState_Associated) ||
7701 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7702 VOS_MAC_ADDRESS_LEN)) {
7703 hddLog(VOS_TRACE_LEVEL_ERROR,
7704 FL("Not Associated to mac "MAC_ADDRESS_STR),
7705 MAC_ADDR_ARRAY(peer_mac));
7706 return -EINVAL;
7707 }
7708
7709 nss = 1; //pronto supports only one spatial stream
7710 freq = vos_chan_to_freq(
7711 hdd_sta_ctx->conn_info.operationChannel);
7712 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7713
7714 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7715 adapter->device_mode == WLAN_HDD_SOFTAP) {
7716
7717 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7718 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7719 if(pSapCtx == NULL){
7720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7721 FL("psapCtx is NULL"));
7722 return -ENOENT;
7723 }
7724
7725
7726 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7727 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7728 !vos_is_macaddr_broadcast(
7729 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7730 vos_mem_compare(
7731 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7732 peer_mac, VOS_MAC_ADDRESS_LEN))
7733 break;
7734 }
7735
7736 if (WLAN_MAX_STA_COUNT == sta_id) {
7737 hddLog(VOS_TRACE_LEVEL_ERROR,
7738 FL("No active peer with mac="MAC_ADDRESS_STR),
7739 MAC_ADDR_ARRAY(peer_mac));
7740 return -EINVAL;
7741 }
7742
7743 nss = 1; //pronto supports only one spatial stream
7744 freq = vos_chan_to_freq(
7745 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7746 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7747 } else {
7748 hddLog(VOS_TRACE_LEVEL_ERROR,
7749 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7750 MAC_ADDR_ARRAY(peer_mac));
7751 return -EINVAL;
7752 }
7753
7754 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7755 if (rate_flags & eHAL_TX_RATE_VHT80) {
7756 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307757#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7758 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307759 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307760#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307761 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7762 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307763#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7764 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307765 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307766#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307767 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7768 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7769 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7770 final_rate_flags |= RATE_INFO_FLAGS_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307771#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7772 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307773 if (rate_flags & eHAL_TX_RATE_HT40)
7774 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307775#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307776 }
7777
7778 if (rate_flags & eHAL_TX_RATE_SGI) {
7779 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7780 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7781 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7782 }
7783 }
7784
7785 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7786 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7787
7788 if (NULL == reply_skb) {
7789 hddLog(VOS_TRACE_LEVEL_ERROR,
7790 FL("getLinkProperties: skb alloc failed"));
7791 return -EINVAL;
7792 }
7793
7794 if (nla_put_u8(reply_skb,
7795 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7796 nss) ||
7797 nla_put_u8(reply_skb,
7798 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7799 final_rate_flags) ||
7800 nla_put_u32(reply_skb,
7801 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7802 freq)) {
7803 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7804 kfree_skb(reply_skb);
7805 return -EINVAL;
7806 }
7807
7808 return cfg80211_vendor_cmd_reply(reply_skb);
7809}
7810
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307811#define BEACON_MISS_THRESH_2_4 \
7812 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7813#define BEACON_MISS_THRESH_5_0 \
7814 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307815#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7816#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7817#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7818#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307819#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7820 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307821
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307822/*
7823 * hdd_set_qpower() - Process the qpower command and invoke the SME api
7824 * @hdd_ctx: hdd context
7825 * @enable: Value received in the command, 1 for disable and 2 for enable
7826 *
7827 * Return: void
7828 */
7829static void hdd_set_qpower(hdd_context_t *hdd_ctx, uint8_t enable)
7830{
7831 if (!hdd_ctx) {
7832 hddLog(LOGE, "hdd_ctx NULL");
7833 return;
7834 }
7835
7836 sme_set_qpower(hdd_ctx->hHal, enable);
7837}
7838
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307839/**
7840 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7841 * vendor command
7842 *
7843 * @wiphy: wiphy device pointer
7844 * @wdev: wireless device pointer
7845 * @data: Vendor command data buffer
7846 * @data_len: Buffer length
7847 *
7848 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7849 *
7850 * Return: EOK or other error codes.
7851 */
7852
7853static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7854 struct wireless_dev *wdev,
7855 const void *data,
7856 int data_len)
7857{
7858 struct net_device *dev = wdev->netdev;
7859 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7860 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7861 hdd_station_ctx_t *pHddStaCtx;
7862 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7863 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307864 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307865 eHalStatus status;
7866 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307867 uint8_t hb_thresh_val;
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307868 uint8_t qpower;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307869
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307870 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7871 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7872 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307873 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7874 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7875 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307876 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7877 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307878 };
7879
7880 ENTER();
7881
7882 if (VOS_FTM_MODE == hdd_get_conparam()) {
7883 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7884 return -EINVAL;
7885 }
7886
7887 ret_val = wlan_hdd_validate_context(pHddCtx);
7888 if (ret_val) {
7889 return ret_val;
7890 }
7891
7892 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7893
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307894 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7895 hddLog(LOGE, FL("Invalid ATTR"));
7896 return -EINVAL;
7897 }
7898
7899 /* check the Wifi Capability */
7900 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7901 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7902 {
7903 hddLog(VOS_TRACE_LEVEL_ERROR,
7904 FL("WIFICONFIG not supported by Firmware"));
7905 return -EINVAL;
7906 }
7907
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307908 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7909 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7910 modifyRoamParamsReq.value =
7911 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7912
7913 if (eHAL_STATUS_SUCCESS !=
7914 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7915 {
7916 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7917 ret_val = -EINVAL;
7918 }
7919 return ret_val;
7920 }
7921
7922 /* Moved this down in order to provide provision to set beacon
7923 * miss penalty count irrespective of connection state.
7924 */
7925 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7926 hddLog(LOGE, FL("Not in Connected state!"));
7927 return -ENOTSUPP;
7928 }
7929
7930 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307931
7932 if (!pReq) {
7933 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7934 "%s: Not able to allocate memory for tSetWifiConfigParams",
7935 __func__);
7936 return eHAL_STATUS_E_MALLOC_FAILED;
7937 }
7938
7939 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7940
7941 pReq->sessionId = pAdapter->sessionId;
7942 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7943
7944 if (tb[PARAM_MODULATED_DTIM]) {
7945 pReq->paramValue = nla_get_u32(
7946 tb[PARAM_MODULATED_DTIM]);
7947 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7948 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307949 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307950 hdd_set_pwrparams(pHddCtx);
7951 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7952 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7953
7954 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7955 iw_full_power_cbfn, pAdapter,
7956 eSME_FULL_PWR_NEEDED_BY_HDD);
7957 }
7958 else
7959 {
7960 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7961 }
7962 }
7963
7964 if (tb[PARAM_STATS_AVG_FACTOR]) {
7965 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7966 pReq->paramValue = nla_get_u16(
7967 tb[PARAM_STATS_AVG_FACTOR]);
7968 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7969 pReq->paramType, pReq->paramValue);
7970 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7971
7972 if (eHAL_STATUS_SUCCESS != status)
7973 {
7974 vos_mem_free(pReq);
7975 pReq = NULL;
7976 ret_val = -EPERM;
7977 return ret_val;
7978 }
7979 }
7980
7981
7982 if (tb[PARAM_GUARD_TIME]) {
7983 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7984 pReq->paramValue = nla_get_u32(
7985 tb[PARAM_GUARD_TIME]);
7986 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7987 pReq->paramType, pReq->paramValue);
7988 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7989
7990 if (eHAL_STATUS_SUCCESS != status)
7991 {
7992 vos_mem_free(pReq);
7993 pReq = NULL;
7994 ret_val = -EPERM;
7995 return ret_val;
7996 }
7997
7998 }
7999
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05308000 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
8001 hb_thresh_val = nla_get_u8(
8002 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
8003
8004 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
8005 hb_thresh_val);
8006 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
8007 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
8008 NULL, eANI_BOOLEAN_FALSE);
8009
8010 status = sme_update_hb_threshold(
8011 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
8012 WNI_CFG_HEART_BEAT_THRESHOLD,
8013 hb_thresh_val, eCSR_BAND_24);
8014 if (eHAL_STATUS_SUCCESS != status) {
8015 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
8016 vos_mem_free(pReq);
8017 pReq = NULL;
8018 return -EPERM;
8019 }
8020 }
8021
8022 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
8023 hb_thresh_val = nla_get_u8(
8024 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
8025
8026 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
8027 hb_thresh_val);
8028 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
8029 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
8030 NULL, eANI_BOOLEAN_FALSE);
8031
8032 status = sme_update_hb_threshold(
8033 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
8034 WNI_CFG_HEART_BEAT_THRESHOLD,
8035 hb_thresh_val, eCSR_BAND_5G);
8036 if (eHAL_STATUS_SUCCESS != status) {
8037 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
8038 vos_mem_free(pReq);
8039 pReq = NULL;
8040 return -EPERM;
8041 }
8042 }
8043
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05308044 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]) {
8045 qpower = nla_get_u8(
8046 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]);
8047
8048 if(qpower > 1) {
8049 hddLog(LOGE, "Invalid QPOWER value %d", qpower);
8050 vos_mem_free(pReq);
8051 pReq = NULL;
8052 return -EINVAL;
8053 }
8054 /* FW is expacting qpower as 1 for Disable and 2 for enable */
8055 qpower++;
8056 hdd_set_qpower(pHddCtx, qpower);
8057 }
8058
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308059 EXIT();
8060 return ret_val;
8061}
8062
8063/**
8064 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
8065 * vendor command
8066 *
8067 * @wiphy: wiphy device pointer
8068 * @wdev: wireless device pointer
8069 * @data: Vendor command data buffer
8070 * @data_len: Buffer length
8071 *
8072 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
8073 *
8074 * Return: EOK or other error codes.
8075 */
8076static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
8077 struct wireless_dev *wdev,
8078 const void *data,
8079 int data_len)
8080{
8081 int ret;
8082
8083 vos_ssr_protect(__func__);
8084 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
8085 data, data_len);
8086 vos_ssr_unprotect(__func__);
8087
8088 return ret;
8089}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308090
8091/*
8092 * define short names for the global vendor params
8093 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8094 */
8095#define STATS_SET_INVALID \
8096 QCA_ATTR_NUD_STATS_SET_INVALID
8097#define STATS_SET_START \
8098 QCA_ATTR_NUD_STATS_SET_START
8099#define STATS_GW_IPV4 \
8100 QCA_ATTR_NUD_STATS_GW_IPV4
8101#define STATS_SET_MAX \
8102 QCA_ATTR_NUD_STATS_SET_MAX
8103
8104const struct nla_policy
8105qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
8106{
8107 [STATS_SET_START] = {.type = NLA_FLAG },
8108 [STATS_GW_IPV4] = {.type = NLA_U32 },
8109};
8110
8111/**
8112 * hdd_set_nud_stats_cb() - hdd callback api to get status
8113 * @data: pointer to adapter
8114 * @rsp: status
8115 *
8116 * Return: None
8117 */
8118static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
8119{
8120
8121 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8122
8123 if (NULL == adapter)
8124 return;
8125
8126 if (VOS_STATUS_SUCCESS == rsp) {
8127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8128 "%s success received STATS_SET_START", __func__);
8129 } else {
8130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8131 "%s STATS_SET_START Failed!!", __func__);
8132 }
8133 return;
8134}
8135
8136/**
8137 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8138 * @wiphy: pointer to wireless wiphy structure.
8139 * @wdev: pointer to wireless_dev structure.
8140 * @data: pointer to apfind configuration data.
8141 * @data_len: the length in byte of apfind data.
8142 *
8143 * This is called when wlan driver needs to send arp stats to
8144 * firmware.
8145 *
8146 * Return: An error code or 0 on success.
8147 */
8148static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8149 struct wireless_dev *wdev,
8150 const void *data, int data_len)
8151{
8152 struct nlattr *tb[STATS_SET_MAX + 1];
8153 struct net_device *dev = wdev->netdev;
8154 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8155 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308156 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308157 setArpStatsParams arp_stats_params;
8158 int err = 0;
8159
8160 ENTER();
8161
8162 err = wlan_hdd_validate_context(hdd_ctx);
8163 if (0 != err)
8164 return err;
8165
8166 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8168 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8169 return -EINVAL;
8170 }
8171
8172 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8173 qca_wlan_vendor_set_nud_stats);
8174 if (err)
8175 {
8176 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8177 "%s STATS_SET_START ATTR", __func__);
8178 return err;
8179 }
8180
8181 if (tb[STATS_SET_START])
8182 {
8183 if (!tb[STATS_GW_IPV4]) {
8184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8185 "%s STATS_SET_START CMD", __func__);
8186 return -EINVAL;
8187 }
8188 arp_stats_params.flag = true;
8189 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8190 } else {
8191 arp_stats_params.flag = false;
8192 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308193 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8195 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308196 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8197 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308198
8199 arp_stats_params.pkt_type = 1; // ARP packet type
8200
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308201 if (arp_stats_params.flag) {
8202 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8203 WLANTL_SetARPFWDatapath(pVosContext, true);
8204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8205 "%s Set FW in data path for ARP with tgt IP :%d",
8206 __func__, hdd_ctx->track_arp_ip);
8207 }
8208 else {
8209 WLANTL_SetARPFWDatapath(pVosContext, false);
8210 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8211 "%s Remove FW from data path", __func__);
8212 }
8213
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308214 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8215 arp_stats_params.data_ctx = adapter;
8216
8217 if (eHAL_STATUS_SUCCESS !=
8218 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8220 "%s STATS_SET_START CMD Failed!!", __func__);
8221 return -EINVAL;
8222 }
8223
8224 EXIT();
8225
8226 return err;
8227}
8228
8229/**
8230 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8231 * @wiphy: pointer to wireless wiphy structure.
8232 * @wdev: pointer to wireless_dev structure.
8233 * @data: pointer to apfind configuration data.
8234 * @data_len: the length in byte of apfind data.
8235 *
8236 * This is called when wlan driver needs to send arp stats to
8237 * firmware.
8238 *
8239 * Return: An error code or 0 on success.
8240 */
8241static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8242 struct wireless_dev *wdev,
8243 const void *data, int data_len)
8244{
8245 int ret;
8246
8247 vos_ssr_protect(__func__);
8248 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8249 vos_ssr_unprotect(__func__);
8250
8251 return ret;
8252}
8253#undef STATS_SET_INVALID
8254#undef STATS_SET_START
8255#undef STATS_GW_IPV4
8256#undef STATS_SET_MAX
8257
8258/*
8259 * define short names for the global vendor params
8260 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8261 */
8262#define STATS_GET_INVALID \
8263 QCA_ATTR_NUD_STATS_SET_INVALID
8264#define COUNT_FROM_NETDEV \
8265 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8266#define COUNT_TO_LOWER_MAC \
8267 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8268#define RX_COUNT_BY_LOWER_MAC \
8269 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8270#define COUNT_TX_SUCCESS \
8271 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8272#define RSP_RX_COUNT_BY_LOWER_MAC \
8273 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8274#define RSP_RX_COUNT_BY_UPPER_MAC \
8275 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8276#define RSP_COUNT_TO_NETDEV \
8277 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8278#define RSP_COUNT_OUT_OF_ORDER_DROP \
8279 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8280#define AP_LINK_ACTIVE \
8281 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8282#define AP_LINK_DAD \
8283 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8284#define STATS_GET_MAX \
8285 QCA_ATTR_NUD_STATS_GET_MAX
8286
8287const struct nla_policy
8288qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8289{
8290 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8291 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8292 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8293 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8294 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8295 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8296 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8297 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8298 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8299 [AP_LINK_DAD] = {.type = NLA_FLAG },
8300};
8301
8302static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8303{
8304
8305 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308306 hdd_context_t *hdd_ctx;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308307 struct hdd_nud_stats_context *context;
8308 int status;
8309
8310 ENTER();
8311
8312 if (NULL == adapter)
8313 return;
8314
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308315 if (!rsp) {
8316 hddLog(LOGE, FL("data is null"));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308317 return;
8318 }
8319
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308320 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8321 status = wlan_hdd_validate_context(hdd_ctx);
8322 if (0 != status) {
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308323 return;
8324 }
8325
8326 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8327 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8328 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8329 adapter->dad |= rsp->dad;
8330
8331 spin_lock(&hdd_context_lock);
8332 context = &hdd_ctx->nud_stats_context;
8333 complete(&context->response_event);
8334 spin_unlock(&hdd_context_lock);
8335
8336 return;
8337}
8338static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8339 struct wireless_dev *wdev,
8340 const void *data, int data_len)
8341{
8342 int err = 0;
8343 unsigned long rc;
8344 struct hdd_nud_stats_context *context;
8345 struct net_device *dev = wdev->netdev;
8346 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8347 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8348 getArpStatsParams arp_stats_params;
8349 struct sk_buff *skb;
8350
8351 ENTER();
8352
8353 err = wlan_hdd_validate_context(hdd_ctx);
8354 if (0 != err)
8355 return err;
8356
8357 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8358 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8359 arp_stats_params.data_ctx = adapter;
8360
8361 spin_lock(&hdd_context_lock);
8362 context = &hdd_ctx->nud_stats_context;
8363 INIT_COMPLETION(context->response_event);
8364 spin_unlock(&hdd_context_lock);
8365
8366 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8368 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8369 return -EINVAL;
8370 }
8371
8372 if (eHAL_STATUS_SUCCESS !=
8373 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8375 "%s STATS_SET_START CMD Failed!!", __func__);
8376 return -EINVAL;
8377 }
8378
8379 rc = wait_for_completion_timeout(&context->response_event,
8380 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8381 if (!rc)
8382 {
8383 hddLog(LOGE,
8384 FL("Target response timed out request "));
8385 return -ETIMEDOUT;
8386 }
8387
8388 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8389 WLAN_NUD_STATS_LEN);
8390 if (!skb)
8391 {
8392 hddLog(VOS_TRACE_LEVEL_ERROR,
8393 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8394 __func__);
8395 return -ENOMEM;
8396 }
8397
8398 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8399 adapter->hdd_stats.hddArpStats.txCount) ||
8400 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8401 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8402 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8403 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8404 nla_put_u16(skb, COUNT_TX_SUCCESS,
8405 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8406 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8407 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8408 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8409 adapter->hdd_stats.hddArpStats.rxCount) ||
8410 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8411 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8412 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8413 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8414 hddLog(LOGE, FL("nla put fail"));
8415 kfree_skb(skb);
8416 return -EINVAL;
8417 }
8418 if (adapter->con_status)
8419 nla_put_flag(skb, AP_LINK_ACTIVE);
8420 if (adapter->dad)
8421 nla_put_flag(skb, AP_LINK_DAD);
8422
8423 cfg80211_vendor_cmd_reply(skb);
8424 return err;
8425}
8426
8427static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8428 struct wireless_dev *wdev,
8429 const void *data, int data_len)
8430{
8431 int ret;
8432
8433 vos_ssr_protect(__func__);
8434 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8435 vos_ssr_unprotect(__func__);
8436
8437 return ret;
8438}
8439
8440#undef QCA_ATTR_NUD_STATS_SET_INVALID
8441#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8442#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8443#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8444#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8445#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8446#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8447#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8448#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8449#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8450#undef QCA_ATTR_NUD_STATS_GET_MAX
8451
8452
8453
Kapil Guptaee33bf12016-12-20 18:27:37 +05308454#ifdef WLAN_FEATURE_APFIND
8455/**
8456 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8457 * @wiphy: pointer to wireless wiphy structure.
8458 * @wdev: pointer to wireless_dev structure.
8459 * @data: pointer to apfind configuration data.
8460 * @data_len: the length in byte of apfind data.
8461 *
8462 * This is called when wlan driver needs to send APFIND configurations to
8463 * firmware.
8464 *
8465 * Return: An error code or 0 on success.
8466 */
8467static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8468 struct wireless_dev *wdev,
8469 const void *data, int data_len)
8470{
8471 struct sme_ap_find_request_req apfind_req;
8472 VOS_STATUS status;
8473 int ret_val;
8474 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8475
8476 ENTER();
8477
8478 ret_val = wlan_hdd_validate_context(hdd_ctx);
8479 if (ret_val)
8480 return ret_val;
8481
8482 if (VOS_FTM_MODE == hdd_get_conparam()) {
8483 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8484 return -EPERM;
8485 }
8486
8487 apfind_req.request_data_len = data_len;
8488 apfind_req.request_data = data;
8489
8490 status = sme_apfind_set_cmd(&apfind_req);
8491 if (VOS_STATUS_SUCCESS != status) {
8492 ret_val = -EIO;
8493 }
8494 return ret_val;
8495}
8496
8497/**
8498 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8499 * @wiphy: pointer to wireless wiphy structure.
8500 * @wdev: pointer to wireless_dev structure.
8501 * @data: pointer to apfind configuration data.
8502 * @data_len: the length in byte of apfind data.
8503 *
8504 * This is called when wlan driver needs to send APFIND configurations to
8505 * firmware.
8506 *
8507 * Return: An error code or 0 on success.
8508 */
8509static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8510 struct wireless_dev *wdev,
8511 const void *data, int data_len)
8512{
8513 int ret;
8514
8515 vos_ssr_protect(__func__);
8516 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8517 vos_ssr_unprotect(__func__);
8518
8519 return ret;
8520}
8521#endif /* WLAN_FEATURE_APFIND */
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308522
8523/**
8524 * __wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8525 * @wiphy: pointer to wireless wiphy structure.
8526 * @wdev: pointer to wireless_dev structure.
8527 * @data: Pointer to the data to be passed via vendor interface
8528 * @data_len:Length of the data to be passed
8529 *
8530 * This is called by userspace to know the supported logger features
8531 *
8532 * Return: Return the Success or Failure code.
8533 */
8534static int
8535__wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8536 struct wireless_dev *wdev,
8537 const void *data, int data_len)
8538{
8539 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8540 int status;
8541 uint32_t features;
8542 struct sk_buff *reply_skb = NULL;
8543
8544 if (VOS_FTM_MODE == hdd_get_conparam()) {
8545 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8546 return -EINVAL;
8547 }
8548
8549 status = wlan_hdd_validate_context(hdd_ctx);
8550 if (0 != status)
8551 return -EINVAL;
8552
8553 features = 0;
8554
8555 if (hdd_is_memdump_supported())
8556 features |= WIFI_LOGGER_MEMORY_DUMP_SUPPORTED;
8557
8558 if (hdd_ctx->cfg_ini->wlanLoggingEnable &&
8559 hdd_ctx->cfg_ini->enableFatalEvent &&
8560 hdd_ctx->is_fatal_event_log_sup) {
8561 features |= WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED;
8562 features |= WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
8563 }
8564
8565 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8566 sizeof(uint32_t) + NLA_HDRLEN + NLMSG_HDRLEN);
8567 if (!reply_skb) {
8568 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
8569 return -ENOMEM;
8570 }
8571
8572 hddLog(LOG1, FL("Supported logger features: 0x%0x"), features);
8573 if (nla_put_u32(reply_skb, QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED,
8574 features)) {
8575 hddLog(LOGE, FL("nla put fail"));
8576 kfree_skb(reply_skb);
8577 return -EINVAL;
8578 }
8579
8580 return cfg80211_vendor_cmd_reply(reply_skb);
8581}
8582
8583/**
8584 * wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8585 * @wiphy: pointer to wireless wiphy structure.
8586 * @wdev: pointer to wireless_dev structure.
8587 * @data: Pointer to the data to be passed via vendor interface
8588 * @data_len:Length of the data to be passed
8589 *
8590 * This is called by userspace to know the supported logger features
8591 *
8592 * Return: Return the Success or Failure code.
8593 */
8594static int
8595wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8596 struct wireless_dev *wdev,
8597 const void *data, int data_len)
8598{
8599 int ret;
8600
8601 vos_ssr_protect(__func__);
8602 ret = __wlan_hdd_cfg80211_get_logger_supp_feature(wiphy, wdev,
8603 data, data_len);
8604 vos_ssr_unprotect(__func__);
8605
8606 return ret;
8607}
8608
Sunil Duttc69bccb2014-05-26 21:30:20 +05308609const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8610{
Mukul Sharma2a271632014-10-13 14:59:01 +05308611 {
8612 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8613 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8614 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8615 WIPHY_VENDOR_CMD_NEED_NETDEV |
8616 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308617 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308618 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308619
8620 {
8621 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8622 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8623 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8624 WIPHY_VENDOR_CMD_NEED_NETDEV |
8625 WIPHY_VENDOR_CMD_NEED_RUNNING,
8626 .doit = wlan_hdd_cfg80211_nan_request
8627 },
8628
Sunil Duttc69bccb2014-05-26 21:30:20 +05308629#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8630 {
8631 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8632 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8633 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8634 WIPHY_VENDOR_CMD_NEED_NETDEV |
8635 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308636 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308637 },
8638
8639 {
8640 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8641 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8642 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8643 WIPHY_VENDOR_CMD_NEED_NETDEV |
8644 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308645 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308646 },
8647
8648 {
8649 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8650 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8651 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8652 WIPHY_VENDOR_CMD_NEED_NETDEV |
8653 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308654 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308655 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308656#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308657#ifdef WLAN_FEATURE_EXTSCAN
8658 {
8659 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8660 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8661 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8662 WIPHY_VENDOR_CMD_NEED_NETDEV |
8663 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308664 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308665 },
8666 {
8667 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8668 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8669 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8670 WIPHY_VENDOR_CMD_NEED_NETDEV |
8671 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308672 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308673 },
8674 {
8675 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8676 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8677 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8678 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308679 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308680 },
8681 {
8682 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8683 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8684 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8685 WIPHY_VENDOR_CMD_NEED_NETDEV |
8686 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308687 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308688 },
8689 {
8690 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8691 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8692 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8693 WIPHY_VENDOR_CMD_NEED_NETDEV |
8694 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308695 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308696 },
8697 {
8698 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8699 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8700 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8701 WIPHY_VENDOR_CMD_NEED_NETDEV |
8702 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308703 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308704 },
8705 {
8706 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8707 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8708 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8709 WIPHY_VENDOR_CMD_NEED_NETDEV |
8710 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308711 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308712 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308713#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308714/*EXT TDLS*/
8715 {
8716 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8717 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8718 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8719 WIPHY_VENDOR_CMD_NEED_NETDEV |
8720 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308721 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308722 },
8723 {
8724 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8725 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8726 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8727 WIPHY_VENDOR_CMD_NEED_NETDEV |
8728 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308729 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308730 },
8731 {
8732 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8733 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8734 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8735 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308736 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308737 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308738 {
8739 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8740 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8741 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8742 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308743 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308744 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308745 {
8746 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8747 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8748 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8749 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308750 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308751 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308752 {
8753 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8754 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8755 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8756 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308757 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308758 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308759 {
8760 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8761 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8762 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8763 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308764 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308765 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308766 {
8767 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308768 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8769 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8770 WIPHY_VENDOR_CMD_NEED_NETDEV |
8771 WIPHY_VENDOR_CMD_NEED_RUNNING,
8772 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8773 },
8774 {
8775 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308776 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8777 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8778 WIPHY_VENDOR_CMD_NEED_NETDEV |
8779 WIPHY_VENDOR_CMD_NEED_RUNNING,
8780 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308781 },
8782 {
8783 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8784 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8785 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8786 WIPHY_VENDOR_CMD_NEED_NETDEV,
8787 .doit = wlan_hdd_cfg80211_wifi_logger_start
8788 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308789 {
8790 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8791 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8792 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8793 WIPHY_VENDOR_CMD_NEED_NETDEV|
8794 WIPHY_VENDOR_CMD_NEED_RUNNING,
8795 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308796 },
8797 {
8798 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8799 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8800 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8801 WIPHY_VENDOR_CMD_NEED_NETDEV |
8802 WIPHY_VENDOR_CMD_NEED_RUNNING,
8803 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308804 },
8805 {
8806 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8807 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8808 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8809 WIPHY_VENDOR_CMD_NEED_NETDEV |
8810 WIPHY_VENDOR_CMD_NEED_RUNNING,
8811 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308812 },
8813#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8814 {
8815 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8816 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8817 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8818 WIPHY_VENDOR_CMD_NEED_NETDEV |
8819 WIPHY_VENDOR_CMD_NEED_RUNNING,
8820 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308821 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308822#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308823 {
8824 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8825 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8826 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8827 WIPHY_VENDOR_CMD_NEED_NETDEV |
8828 WIPHY_VENDOR_CMD_NEED_RUNNING,
8829 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308830 },
8831 {
8832 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8833 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8834 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8835 WIPHY_VENDOR_CMD_NEED_NETDEV |
8836 WIPHY_VENDOR_CMD_NEED_RUNNING,
8837 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308838 },
8839#ifdef WLAN_FEATURE_APFIND
8840 {
8841 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8842 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8843 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8844 WIPHY_VENDOR_CMD_NEED_NETDEV,
8845 .doit = wlan_hdd_cfg80211_apfind_cmd
8846 },
8847#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308848 {
8849 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8850 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8851 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8852 WIPHY_VENDOR_CMD_NEED_NETDEV |
8853 WIPHY_VENDOR_CMD_NEED_RUNNING,
8854 .doit = wlan_hdd_cfg80211_set_nud_stats
8855 },
8856 {
8857 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8858 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8859 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8860 WIPHY_VENDOR_CMD_NEED_NETDEV |
8861 WIPHY_VENDOR_CMD_NEED_RUNNING,
8862 .doit = wlan_hdd_cfg80211_get_nud_stats
8863 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308864 {
8865 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8866 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8867 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8868 WIPHY_VENDOR_CMD_NEED_NETDEV |
8869 WIPHY_VENDOR_CMD_NEED_RUNNING,
8870 .doit = hdd_cfg80211_get_station_cmd
8871 },
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308872 {
8873 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8874 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET,
8875 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8876 WIPHY_VENDOR_CMD_NEED_NETDEV |
8877 WIPHY_VENDOR_CMD_NEED_RUNNING,
8878 .doit = wlan_hdd_cfg80211_get_logger_supp_feature
8879 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308880};
8881
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008882/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308883static const
8884struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008885{
8886#ifdef FEATURE_WLAN_CH_AVOID
8887 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308888 .vendor_id = QCA_NL80211_VENDOR_ID,
8889 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008890 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308891#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8892#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8893 {
8894 /* Index = 1*/
8895 .vendor_id = QCA_NL80211_VENDOR_ID,
8896 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8897 },
8898 {
8899 /* Index = 2*/
8900 .vendor_id = QCA_NL80211_VENDOR_ID,
8901 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8902 },
8903 {
8904 /* Index = 3*/
8905 .vendor_id = QCA_NL80211_VENDOR_ID,
8906 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8907 },
8908 {
8909 /* Index = 4*/
8910 .vendor_id = QCA_NL80211_VENDOR_ID,
8911 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8912 },
8913 {
8914 /* Index = 5*/
8915 .vendor_id = QCA_NL80211_VENDOR_ID,
8916 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8917 },
8918 {
8919 /* Index = 6*/
8920 .vendor_id = QCA_NL80211_VENDOR_ID,
8921 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8922 },
8923#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308924#ifdef WLAN_FEATURE_EXTSCAN
8925 {
8926 .vendor_id = QCA_NL80211_VENDOR_ID,
8927 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8928 },
8929 {
8930 .vendor_id = QCA_NL80211_VENDOR_ID,
8931 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8932 },
8933 {
8934 .vendor_id = QCA_NL80211_VENDOR_ID,
8935 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8936 },
8937 {
8938 .vendor_id = QCA_NL80211_VENDOR_ID,
8939 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8940 },
8941 {
8942 .vendor_id = QCA_NL80211_VENDOR_ID,
8943 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8944 },
8945 {
8946 .vendor_id = QCA_NL80211_VENDOR_ID,
8947 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8948 },
8949 {
8950 .vendor_id = QCA_NL80211_VENDOR_ID,
8951 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8952 },
8953 {
8954 .vendor_id = QCA_NL80211_VENDOR_ID,
8955 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8956 },
8957 {
8958 .vendor_id = QCA_NL80211_VENDOR_ID,
8959 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8960 },
8961 {
8962 .vendor_id = QCA_NL80211_VENDOR_ID,
8963 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8964 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308965#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308966/*EXT TDLS*/
8967 {
8968 .vendor_id = QCA_NL80211_VENDOR_ID,
8969 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8970 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308971 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8972 .vendor_id = QCA_NL80211_VENDOR_ID,
8973 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8974 },
8975
Srinivas Dasari030bad32015-02-18 23:23:54 +05308976
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308977 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308978 .vendor_id = QCA_NL80211_VENDOR_ID,
8979 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8980 },
8981
Sushant Kaushik084f6592015-09-10 13:11:56 +05308982 {
8983 .vendor_id = QCA_NL80211_VENDOR_ID,
8984 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308985 },
8986 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8987 .vendor_id = QCA_NL80211_VENDOR_ID,
8988 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8989 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308990 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8991 .vendor_id = QCA_NL80211_VENDOR_ID,
8992 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8993 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308994 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8995 .vendor_id = QCA_NL80211_VENDOR_ID,
8996 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8997 },
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05308998 [QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
8999 .vendor_id = QCA_NL80211_VENDOR_ID,
9000 .subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
9001 },
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +05309002 [QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX] = {
9003 .vendor_id = QCA_NL80211_VENDOR_ID,
9004 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
9005 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009006};
9007
Jeff Johnson295189b2012-06-20 16:38:30 -07009008/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309009 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309010 * This function is called by hdd_wlan_startup()
9011 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309012 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07009013 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309014struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07009015{
9016 struct wiphy *wiphy;
9017 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309018 /*
9019 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07009020 */
9021 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
9022
9023 if (!wiphy)
9024 {
9025 /* Print error and jump into err label and free the memory */
9026 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
9027 return NULL;
9028 }
9029
Sunil Duttc69bccb2014-05-26 21:30:20 +05309030
Jeff Johnson295189b2012-06-20 16:38:30 -07009031 return wiphy;
9032}
9033
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309034#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
9035 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
9036/**
9037 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
9038 * @wiphy: pointer to wiphy
9039 * @config: pointer to config
9040 *
9041 * Return: None
9042 */
9043static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
9044 hdd_config_t *config)
9045{
9046 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
9047 if (config->max_sched_scan_plan_interval)
9048 wiphy->max_sched_scan_plan_interval =
9049 config->max_sched_scan_plan_interval;
9050 if (config->max_sched_scan_plan_iterations)
9051 wiphy->max_sched_scan_plan_iterations =
9052 config->max_sched_scan_plan_iterations;
9053}
9054#else
9055static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
9056 hdd_config_t *config)
9057{
9058}
9059#endif
9060
Jeff Johnson295189b2012-06-20 16:38:30 -07009061/*
9062 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309063 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07009064 * private ioctl to change the band value
9065 */
9066int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
9067{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309068 int i, j;
9069 eNVChannelEnabledType channelEnabledState;
9070
Jeff Johnsone7245742012-09-05 17:12:55 -07009071 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309072
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309073 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009074 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309075
9076 if (NULL == wiphy->bands[i])
9077 {
9078 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
9079 __func__, i);
9080 continue;
9081 }
9082
9083 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9084 {
9085 struct ieee80211_supported_band *band = wiphy->bands[i];
9086
9087 channelEnabledState = vos_nv_getChannelEnabledState(
9088 band->channels[j].hw_value);
9089
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309090 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309091 {
Abhishek Singh678227a2014-11-04 10:52:38 +05309092 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309093 continue;
9094 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309095 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309096 {
9097 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9098 continue;
9099 }
9100
9101 if (NV_CHANNEL_DISABLE == channelEnabledState ||
9102 NV_CHANNEL_INVALID == channelEnabledState)
9103 {
9104 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9105 }
9106 else if (NV_CHANNEL_DFS == channelEnabledState)
9107 {
9108 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9109 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
9110 }
9111 else
9112 {
9113 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
9114 |IEEE80211_CHAN_RADAR);
9115 }
9116 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009117 }
9118 return 0;
9119}
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309120
9121/**
9122 * hdd_add_channel_switch_support()- Adds Channel Switch flag if supported
9123 * @wiphy: Pointer to the wiphy.
9124 *
9125 * This Function adds Channel Switch support flag, if channel switch is
9126 * supported by kernel.
9127 * Return: void.
9128 */
9129#ifdef CHANNEL_SWITCH_SUPPORTED
9130static inline
9131void hdd_add_channel_switch_support(struct wiphy *wiphy)
9132{
9133 wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
9134 wiphy->max_num_csa_counters = WLAN_HDD_MAX_NUM_CSA_COUNTERS;
9135}
9136#else
9137static inline
9138void hdd_add_channel_switch_support(struct wiphy *wiphy)
9139{
9140}
9141#endif
9142
Jeff Johnson295189b2012-06-20 16:38:30 -07009143/*
9144 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309145 * This function is called by hdd_wlan_startup()
9146 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07009147 * This function is used to initialize and register wiphy structure.
9148 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309149int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009150 struct wiphy *wiphy,
9151 hdd_config_t *pCfg
9152 )
9153{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309154 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309155 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9156
Jeff Johnsone7245742012-09-05 17:12:55 -07009157 ENTER();
9158
Jeff Johnson295189b2012-06-20 16:38:30 -07009159 /* Now bind the underlying wlan device with wiphy */
9160 set_wiphy_dev(wiphy, dev);
9161
9162 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009163
Kiet Lam6c583332013-10-14 05:37:09 +05309164#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009165 /* the flag for the other case would be initialzed in
9166 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05309167#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9168 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
9169#else
Amar Singhal0a402232013-10-11 20:57:16 -07009170 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05309171#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05309172#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009173
Amar Singhalfddc28c2013-09-05 13:03:40 -07009174 /* This will disable updating of NL channels from passive to
9175 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309176#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9177 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
9178#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07009179 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309180#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07009181
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309182#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
9183 wiphy->wowlan = &wowlan_support_cfg80211_init;
9184#else
9185 wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT;
9186 wiphy->wowlan.n_patterns = WOWL_MAX_PTRNS_ALLOWED;
9187 wiphy->wowlan.pattern_min_len = 1;
9188 wiphy->wowlan.pattern_max_len = WOWL_PTRN_MAX_SIZE;
9189#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009190
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009191#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009192 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
9193 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
9194 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07009195 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309196#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05309197 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309198#else
9199 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
9200#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009201#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009202
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009203#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009204 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08009205#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009206 || pCfg->isFastRoamIniFeatureEnabled
9207#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009208#ifdef FEATURE_WLAN_ESE
9209 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009210#endif
9211 )
9212 {
9213 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
9214 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08009215#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009216#ifdef FEATURE_WLAN_TDLS
9217 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
9218 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
9219#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309220#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05309221 if (pCfg->configPNOScanSupport)
9222 {
9223 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
9224 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
9225 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
9226 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
9227 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309228#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009229
Abhishek Singh10d85972015-04-17 10:27:23 +05309230#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9231 wiphy->features |= NL80211_FEATURE_HT_IBSS;
9232#endif
9233
Amar Singhalfddc28c2013-09-05 13:03:40 -07009234#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009235 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
9236 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07009237 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009238 driver need to determine what to do with both
9239 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07009240
9241 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07009242#else
9243 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009244#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009245
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309246 wiphy->max_scan_ssids = MAX_SCAN_SSID;
9247
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05309248 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07009249
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309250 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
9251
Jeff Johnson295189b2012-06-20 16:38:30 -07009252 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05309253 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
9254 | BIT(NL80211_IFTYPE_ADHOC)
9255 | BIT(NL80211_IFTYPE_P2P_CLIENT)
9256 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309257 | BIT(NL80211_IFTYPE_AP)
9258 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07009259
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309260 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009261 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309262#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9263 if( pCfg->enableMCC )
9264 {
9265 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309266 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009267
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309268 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309269 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009270
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309271 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309272 wiphy->iface_combinations = wlan_hdd_iface_combination;
9273 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009274#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309275 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009276
Jeff Johnson295189b2012-06-20 16:38:30 -07009277 /* Before registering we need to update the ht capabilitied based
9278 * on ini values*/
9279 if( !pCfg->ShortGI20MhzEnable )
9280 {
9281 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
9282 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07009283 }
9284
9285 if( !pCfg->ShortGI40MhzEnable )
9286 {
9287 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9288 }
9289
9290 if( !pCfg->nChannelBondingMode5GHz )
9291 {
9292 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9293 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309294 /*
9295 * In case of static linked driver at the time of driver unload,
9296 * module exit doesn't happens. Module cleanup helps in cleaning
9297 * of static memory.
9298 * If driver load happens statically, at the time of driver unload,
9299 * wiphy flags don't get reset because of static memory.
9300 * It's better not to store channel in static memory.
9301 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309302 wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9303 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309304 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309305 if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309306 {
9307 hddLog(VOS_TRACE_LEVEL_ERROR,
9308 FL("Not enough memory to allocate channels"));
9309 return -ENOMEM;
9310 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309311 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309312 &hdd_channels_2_4_GHZ[0],
9313 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009314
Agrawal Ashish97dec502015-11-26 20:20:58 +05309315 if (true == hdd_is_5g_supported(pHddCtx))
9316 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309317 wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9318 wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309319 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309320 if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309321 {
9322 hddLog(VOS_TRACE_LEVEL_ERROR,
9323 FL("Not enough memory to allocate channels"));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309324 vos_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
9325 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
Agrawal Ashish97dec502015-11-26 20:20:58 +05309326 return -ENOMEM;
9327 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309328 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309329 &hdd_channels_5_GHZ[0],
9330 sizeof(hdd_channels_5_GHZ));
9331 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309332
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309333 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309334 {
9335
9336 if (NULL == wiphy->bands[i])
9337 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309338 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309339 __func__, i);
9340 continue;
9341 }
9342
9343 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9344 {
9345 struct ieee80211_supported_band *band = wiphy->bands[i];
9346
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309347 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309348 {
9349 // Enable social channels for P2P
9350 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9351 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9352 else
9353 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9354 continue;
9355 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309356 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309357 {
9358 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9359 continue;
9360 }
9361 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009362 }
9363 /*Initialise the supported cipher suite details*/
9364 wiphy->cipher_suites = hdd_cipher_suites;
9365 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9366
9367 /*signal strength in mBm (100*dBm) */
9368 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9369
9370#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309371 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009372#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009373
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309374 hdd_add_channel_switch_support(wiphy);
Sunil Duttc69bccb2014-05-26 21:30:20 +05309375 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9376 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009377 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9378 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9379
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309380 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
9381
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309382 EXIT();
9383 return 0;
9384}
9385
9386/* In this function we are registering wiphy. */
9387int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9388{
9389 ENTER();
9390 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009391 if (0 > wiphy_register(wiphy))
9392 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309393 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009394 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9395 return -EIO;
9396 }
9397
9398 EXIT();
9399 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309400}
Jeff Johnson295189b2012-06-20 16:38:30 -07009401
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309402/* In this function we are updating channel list when,
9403 regulatory domain is FCC and country code is US.
9404 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9405 As per FCC smart phone is not a indoor device.
9406 GO should not opeate on indoor channels */
9407void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9408{
9409 int j;
9410 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9411 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9412 //Default counrtycode from NV at the time of wiphy initialization.
9413 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9414 &defaultCountryCode[0]))
9415 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009416 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309417 }
9418 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9419 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309420 if (NULL == wiphy->bands[HDD_NL80211_BAND_5GHZ])
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309421 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309422 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[HDD_NL80211_BAND_5GHZ] is NULL",__func__ );
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309423 return;
9424 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309425 for (j = 0; j < wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels; j++)
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309426 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309427 struct ieee80211_supported_band *band = wiphy->bands[HDD_NL80211_BAND_5GHZ];
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309428 // Mark UNII -1 band channel as passive
9429 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9430 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9431 }
9432 }
9433}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309434/* This function registers for all frame which supplicant is interested in */
9435void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009436{
Jeff Johnson295189b2012-06-20 16:38:30 -07009437 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9438 /* Register for all P2P action, public action etc frames */
9439 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009440 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309441 /* Register frame indication call back */
9442 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009443 /* Right now we are registering these frame when driver is getting
9444 initialized. Once we will move to 2.6.37 kernel, in which we have
9445 frame register ops, we will move this code as a part of that */
9446 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309447 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009448 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9449
9450 /* GAS Initial Response */
9451 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9452 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309453
Jeff Johnson295189b2012-06-20 16:38:30 -07009454 /* GAS Comeback Request */
9455 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9456 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9457
9458 /* GAS Comeback Response */
9459 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9460 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9461
9462 /* P2P Public Action */
9463 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309464 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009465 P2P_PUBLIC_ACTION_FRAME_SIZE );
9466
9467 /* P2P Action */
9468 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9469 (v_U8_t*)P2P_ACTION_FRAME,
9470 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009471
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309472 /* WNM BSS Transition Request frame */
9473 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9474 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9475 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009476
9477 /* WNM-Notification */
9478 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9479 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9480 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009481}
9482
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309483void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009484{
Jeff Johnson295189b2012-06-20 16:38:30 -07009485 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9486 /* Register for all P2P action, public action etc frames */
9487 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9488
Jeff Johnsone7245742012-09-05 17:12:55 -07009489 ENTER();
9490
Jeff Johnson295189b2012-06-20 16:38:30 -07009491 /* Right now we are registering these frame when driver is getting
9492 initialized. Once we will move to 2.6.37 kernel, in which we have
9493 frame register ops, we will move this code as a part of that */
9494 /* GAS Initial Request */
9495
9496 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9497 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9498
9499 /* GAS Initial Response */
9500 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9501 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309502
Jeff Johnson295189b2012-06-20 16:38:30 -07009503 /* GAS Comeback Request */
9504 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9505 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9506
9507 /* GAS Comeback Response */
9508 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9509 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9510
9511 /* P2P Public Action */
9512 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309513 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009514 P2P_PUBLIC_ACTION_FRAME_SIZE );
9515
9516 /* P2P Action */
9517 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9518 (v_U8_t*)P2P_ACTION_FRAME,
9519 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009520 /* WNM-Notification */
9521 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9522 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9523 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009524}
9525
9526#ifdef FEATURE_WLAN_WAPI
9527void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309528 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009529{
9530 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9531 tCsrRoamSetKey setKey;
9532 v_BOOL_t isConnected = TRUE;
9533 int status = 0;
9534 v_U32_t roamId= 0xFF;
9535 tANI_U8 *pKeyPtr = NULL;
9536 int n = 0;
9537
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309538 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9539 __func__, hdd_device_modetoString(pAdapter->device_mode),
9540 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009541
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309542 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009543 setKey.keyId = key_index; // Store Key ID
9544 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9545 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9546 setKey.paeRole = 0 ; // the PAE role
9547 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9548 {
9549 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9550 }
9551 else
9552 {
9553 isConnected = hdd_connIsConnected(pHddStaCtx);
9554 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9555 }
9556 setKey.keyLength = key_Len;
9557 pKeyPtr = setKey.Key;
9558 memcpy( pKeyPtr, key, key_Len);
9559
Arif Hussain6d2a3322013-11-17 19:50:10 -08009560 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009561 __func__, key_Len);
9562 for (n = 0 ; n < key_Len; n++)
9563 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9564 __func__,n,setKey.Key[n]);
9565
9566 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9567 if ( isConnected )
9568 {
9569 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9570 pAdapter->sessionId, &setKey, &roamId );
9571 }
9572 if ( status != 0 )
9573 {
9574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9575 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9576 __LINE__, status );
9577 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9578 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309579 /* Need to clear any trace of key value in the memory.
9580 * Thus zero out the memory even though it is local
9581 * variable.
9582 */
9583 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009584}
9585#endif /* FEATURE_WLAN_WAPI*/
9586
9587#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309588int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009589 beacon_data_t **ppBeacon,
9590 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009591#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309592int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009593 beacon_data_t **ppBeacon,
9594 struct cfg80211_beacon_data *params,
9595 int dtim_period)
9596#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309597{
Jeff Johnson295189b2012-06-20 16:38:30 -07009598 int size;
9599 beacon_data_t *beacon = NULL;
9600 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309601 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9602 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009603
Jeff Johnsone7245742012-09-05 17:12:55 -07009604 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009605 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309606 {
9607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9608 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009609 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309610 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009611
9612 old = pAdapter->sessionCtx.ap.beacon;
9613
9614 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309615 {
9616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9617 FL("session(%d) old and new heads points to NULL"),
9618 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009619 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309620 }
9621
9622 if (params->tail && !params->tail_len)
9623 {
9624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9625 FL("tail_len is zero but tail is not NULL"));
9626 return -EINVAL;
9627 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009628
Jeff Johnson295189b2012-06-20 16:38:30 -07009629#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9630 /* Kernel 3.0 is not updating dtim_period for set beacon */
9631 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309632 {
9633 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9634 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009635 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309636 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009637#endif
9638
Kapil Gupta137ef892016-12-13 19:38:00 +05309639 if (params->head)
9640 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009641 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309642 head = params->head;
9643 } else
9644 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009645 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309646 head = old->head;
9647 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009648
Kapil Gupta137ef892016-12-13 19:38:00 +05309649 if (params->tail || !old)
9650 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009651 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309652 tail = params->tail;
9653 } else
9654 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009655 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309656 tail = old->tail;
9657 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009658
Kapil Gupta137ef892016-12-13 19:38:00 +05309659 if (params->proberesp_ies || !old)
9660 {
9661 proberesp_ies_len = params->proberesp_ies_len;
9662 proberesp_ies = params->proberesp_ies;
9663 } else
9664 {
9665 proberesp_ies_len = old->proberesp_ies_len;
9666 proberesp_ies = old->proberesp_ies;
9667 }
9668
9669 if (params->assocresp_ies || !old)
9670 {
9671 assocresp_ies_len = params->assocresp_ies_len;
9672 assocresp_ies = params->assocresp_ies;
9673 } else
9674 {
9675 assocresp_ies_len = old->assocresp_ies_len;
9676 assocresp_ies = old->assocresp_ies;
9677 }
9678
9679 size = sizeof(beacon_data_t) + head_len + tail_len +
9680 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009681
9682 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009683 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309684 {
9685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9686 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009687 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309688 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009689
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009690#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309691 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009692 beacon->dtim_period = params->dtim_period;
9693 else
9694 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009695#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309696 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009697 beacon->dtim_period = dtim_period;
9698 else
9699 beacon->dtim_period = old->dtim_period;
9700#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309701
Jeff Johnson295189b2012-06-20 16:38:30 -07009702 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9703 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309704 beacon->proberesp_ies = beacon->tail + tail_len;
9705 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9706
Jeff Johnson295189b2012-06-20 16:38:30 -07009707 beacon->head_len = head_len;
9708 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309709 beacon->proberesp_ies_len = proberesp_ies_len;
9710 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009711
c_manjee527ecac2017-01-25 12:25:27 +05309712 if (head && head_len)
9713 memcpy(beacon->head, head, head_len);
9714 if (tail && tail_len)
9715 memcpy(beacon->tail, tail, tail_len);
9716 if (proberesp_ies && proberesp_ies_len)
9717 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9718 if (assocresp_ies && assocresp_ies_len)
9719 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009720
9721 *ppBeacon = beacon;
9722
9723 kfree(old);
9724
9725 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009726}
Jeff Johnson295189b2012-06-20 16:38:30 -07009727
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309728v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9729#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9730 const v_U8_t *pIes,
9731#else
9732 v_U8_t *pIes,
9733#endif
9734 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009735{
9736 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309737 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009738 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309739
Jeff Johnson295189b2012-06-20 16:38:30 -07009740 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309741 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009742 elem_id = ptr[0];
9743 elem_len = ptr[1];
9744 left -= 2;
9745 if(elem_len > left)
9746 {
9747 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009748 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009749 eid,elem_len,left);
9750 return NULL;
9751 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309752 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009753 {
9754 return ptr;
9755 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309756
Jeff Johnson295189b2012-06-20 16:38:30 -07009757 left -= elem_len;
9758 ptr += (elem_len + 2);
9759 }
9760 return NULL;
9761}
9762
Jeff Johnson295189b2012-06-20 16:38:30 -07009763/* Check if rate is 11g rate or not */
9764static int wlan_hdd_rate_is_11g(u8 rate)
9765{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009766 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009767 u8 i;
9768 for (i = 0; i < 8; i++)
9769 {
9770 if(rate == gRateArray[i])
9771 return TRUE;
9772 }
9773 return FALSE;
9774}
9775
9776/* Check for 11g rate and set proper 11g only mode */
9777static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9778 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9779{
9780 u8 i, num_rates = pIe[0];
9781
9782 pIe += 1;
9783 for ( i = 0; i < num_rates; i++)
9784 {
9785 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9786 {
9787 /* If rate set have 11g rate than change the mode to 11G */
9788 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9789 if (pIe[i] & BASIC_RATE_MASK)
9790 {
9791 /* If we have 11g rate as basic rate, it means mode
9792 is 11g only mode.
9793 */
9794 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9795 *pCheckRatesfor11g = FALSE;
9796 }
9797 }
9798 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9799 {
9800 *require_ht = TRUE;
9801 }
9802 }
9803 return;
9804}
9805
9806static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9807{
9808 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9809 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9810 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9811 u8 checkRatesfor11g = TRUE;
9812 u8 require_ht = FALSE;
9813 u8 *pIe=NULL;
9814
9815 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9816
9817 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9818 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9819 if (pIe != NULL)
9820 {
9821 pIe += 1;
9822 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9823 &pConfig->SapHw_mode);
9824 }
9825
9826 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9827 WLAN_EID_EXT_SUPP_RATES);
9828 if (pIe != NULL)
9829 {
9830
9831 pIe += 1;
9832 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9833 &pConfig->SapHw_mode);
9834 }
9835
9836 if( pConfig->channel > 14 )
9837 {
9838 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9839 }
9840
9841 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9842 WLAN_EID_HT_CAPABILITY);
9843
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309844 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009845 {
9846 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9847 if(require_ht)
9848 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9849 }
9850}
9851
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309852static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9853 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9854{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009855 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309856 v_U8_t *pIe = NULL;
9857 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9858
9859 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9860 pBeacon->tail, pBeacon->tail_len);
9861
9862 if (pIe)
9863 {
9864 ielen = pIe[1] + 2;
9865 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9866 {
9867 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9868 }
9869 else
9870 {
9871 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9872 return -EINVAL;
9873 }
9874 *total_ielen += ielen;
9875 }
9876 return 0;
9877}
9878
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009879static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9880 v_U8_t *genie, v_U8_t *total_ielen)
9881{
9882 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9883 int left = pBeacon->tail_len;
9884 v_U8_t *ptr = pBeacon->tail;
9885 v_U8_t elem_id, elem_len;
9886 v_U16_t ielen = 0;
9887
9888 if ( NULL == ptr || 0 == left )
9889 return;
9890
9891 while (left >= 2)
9892 {
9893 elem_id = ptr[0];
9894 elem_len = ptr[1];
9895 left -= 2;
9896 if (elem_len > left)
9897 {
9898 hddLog( VOS_TRACE_LEVEL_ERROR,
9899 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9900 elem_id, elem_len, left);
9901 return;
9902 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309903 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009904 {
9905 /* skipping the VSIE's which we don't want to include or
9906 * it will be included by existing code
9907 */
9908 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9909#ifdef WLAN_FEATURE_WFD
9910 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9911#endif
9912 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9913 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9914 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9915 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9916 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9917 {
9918 ielen = ptr[1] + 2;
9919 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9920 {
9921 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9922 *total_ielen += ielen;
9923 }
9924 else
9925 {
9926 hddLog( VOS_TRACE_LEVEL_ERROR,
9927 "IE Length is too big "
9928 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9929 elem_id, elem_len, *total_ielen);
9930 }
9931 }
9932 }
9933
9934 left -= elem_len;
9935 ptr += (elem_len + 2);
9936 }
9937 return;
9938}
9939
Kapil Gupta137ef892016-12-13 19:38:00 +05309940int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009941{
9942 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309943 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009944 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009945 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309946 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009947
9948 genie = vos_mem_malloc(MAX_GENIE_LEN);
9949
9950 if(genie == NULL) {
9951
9952 return -ENOMEM;
9953 }
9954
Kapil Gupta137ef892016-12-13 19:38:00 +05309955 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309956 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9957 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009958 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309959 hddLog(LOGE,
9960 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309961 ret = -EINVAL;
9962 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009963 }
9964
9965#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309966 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9967 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9968 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309969 hddLog(LOGE,
9970 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309971 ret = -EINVAL;
9972 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009973 }
9974#endif
9975
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309976 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9977 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009978 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309979 hddLog(LOGE,
9980 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309981 ret = -EINVAL;
9982 goto done;
9983 }
9984
9985 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9986 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009987 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009988 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009989
9990 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9991 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9992 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9993 {
9994 hddLog(LOGE,
9995 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009996 ret = -EINVAL;
9997 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009998 }
9999
10000 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10001 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10002 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10003 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10004 ==eHAL_STATUS_FAILURE)
10005 {
10006 hddLog(LOGE,
10007 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010008 ret = -EINVAL;
10009 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010010 }
10011
10012 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +053010013 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010014 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010015 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -070010016 u8 probe_rsp_ie_len[3] = {0};
10017 u8 counter = 0;
10018 /* Check Probe Resp Length if it is greater then 255 then Store
10019 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
10020 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
10021 Store More then 255 bytes into One Variable.
10022 */
10023 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
10024 {
10025 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
10026 {
10027 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
10028 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
10029 }
10030 else
10031 {
10032 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
10033 rem_probe_resp_ie_len = 0;
10034 }
10035 }
10036
10037 rem_probe_resp_ie_len = 0;
10038
10039 if (probe_rsp_ie_len[0] > 0)
10040 {
10041 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10042 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +053010043 (tANI_U8*)&pBeacon->
10044 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010045 probe_rsp_ie_len[0], NULL,
10046 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10047 {
10048 hddLog(LOGE,
10049 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010050 ret = -EINVAL;
10051 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010052 }
10053 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10054 }
10055
10056 if (probe_rsp_ie_len[1] > 0)
10057 {
10058 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10059 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +053010060 (tANI_U8*)&pBeacon->
10061 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010062 probe_rsp_ie_len[1], NULL,
10063 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10064 {
10065 hddLog(LOGE,
10066 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010067 ret = -EINVAL;
10068 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010069 }
10070 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10071 }
10072
10073 if (probe_rsp_ie_len[2] > 0)
10074 {
10075 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10076 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +053010077 (tANI_U8*)&pBeacon->
10078 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010079 probe_rsp_ie_len[2], NULL,
10080 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10081 {
10082 hddLog(LOGE,
10083 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010084 ret = -EINVAL;
10085 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010086 }
10087 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10088 }
10089
10090 if (probe_rsp_ie_len[1] == 0 )
10091 {
10092 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10093 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10094 eANI_BOOLEAN_FALSE) )
10095 {
10096 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010097 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010098 }
10099 }
10100
10101 if (probe_rsp_ie_len[2] == 0 )
10102 {
10103 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10104 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10105 eANI_BOOLEAN_FALSE) )
10106 {
10107 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010108 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010109 }
10110 }
10111
10112 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10113 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10114 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10115 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10116 == eHAL_STATUS_FAILURE)
10117 {
10118 hddLog(LOGE,
10119 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010120 ret = -EINVAL;
10121 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010122 }
10123 }
10124 else
10125 {
10126 // Reset WNI_CFG_PROBE_RSP Flags
10127 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
10128
10129 hddLog(VOS_TRACE_LEVEL_INFO,
10130 "%s: No Probe Response IE received in set beacon",
10131 __func__);
10132 }
10133
10134 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +053010135 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010136 {
10137 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +053010138 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
10139 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -070010140 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10141 {
10142 hddLog(LOGE,
10143 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010144 ret = -EINVAL;
10145 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010146 }
10147
10148 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10149 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
10150 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10151 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10152 == eHAL_STATUS_FAILURE)
10153 {
10154 hddLog(LOGE,
10155 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010156 ret = -EINVAL;
10157 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010158 }
10159 }
10160 else
10161 {
10162 hddLog(VOS_TRACE_LEVEL_INFO,
10163 "%s: No Assoc Response IE received in set beacon",
10164 __func__);
10165
10166 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10167 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10168 eANI_BOOLEAN_FALSE) )
10169 {
10170 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010171 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010172 }
10173 }
10174
Jeff Johnsone7245742012-09-05 17:12:55 -070010175done:
Jeff Johnson295189b2012-06-20 16:38:30 -070010176 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010177 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010178}
Jeff Johnson295189b2012-06-20 16:38:30 -070010179
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010180/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010181 * FUNCTION: wlan_hdd_validate_operation_channel
10182 * called by wlan_hdd_cfg80211_start_bss() and
10183 * wlan_hdd_cfg80211_set_channel()
10184 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010185 * channel list.
10186 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -070010187VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010188{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010189
Jeff Johnson295189b2012-06-20 16:38:30 -070010190 v_U32_t num_ch = 0;
10191 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10192 u32 indx = 0;
10193 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010194 v_U8_t fValidChannel = FALSE, count = 0;
10195 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010196
Jeff Johnson295189b2012-06-20 16:38:30 -070010197 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10198
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010199 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010200 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010201 /* Validate the channel */
10202 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010203 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010204 if ( channel == rfChannels[count].channelNum )
10205 {
10206 fValidChannel = TRUE;
10207 break;
10208 }
10209 }
10210 if (fValidChannel != TRUE)
10211 {
10212 hddLog(VOS_TRACE_LEVEL_ERROR,
10213 "%s: Invalid Channel [%d]", __func__, channel);
10214 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010215 }
10216 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010217 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010218 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010219 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10220 valid_ch, &num_ch))
10221 {
10222 hddLog(VOS_TRACE_LEVEL_ERROR,
10223 "%s: failed to get valid channel list", __func__);
10224 return VOS_STATUS_E_FAILURE;
10225 }
10226 for (indx = 0; indx < num_ch; indx++)
10227 {
10228 if (channel == valid_ch[indx])
10229 {
10230 break;
10231 }
10232 }
10233
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010234 if (indx >= num_ch)
10235 {
10236 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10237 {
10238 eCsrBand band;
10239 unsigned int freq;
10240
10241 sme_GetFreqBand(hHal, &band);
10242
10243 if (eCSR_BAND_5G == band)
10244 {
10245#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10246 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10247 {
10248 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010249 HDD_NL80211_BAND_2GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010250 }
10251 else
10252 {
10253 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010254 HDD_NL80211_BAND_5GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010255 }
10256#else
10257 freq = ieee80211_channel_to_frequency(channel);
10258#endif
10259 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
10260 return VOS_STATUS_SUCCESS;
10261 }
10262 }
10263
10264 hddLog(VOS_TRACE_LEVEL_ERROR,
10265 "%s: Invalid Channel [%d]", __func__, channel);
10266 return VOS_STATUS_E_FAILURE;
10267 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010268 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010269
Jeff Johnson295189b2012-06-20 16:38:30 -070010270 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010271
Jeff Johnson295189b2012-06-20 16:38:30 -070010272}
10273
Viral Modi3a32cc52013-02-08 11:14:52 -080010274/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010275 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -080010276 * This function is used to set the channel number
10277 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010278static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -080010279 struct ieee80211_channel *chan,
10280 enum nl80211_channel_type channel_type
10281 )
10282{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010283 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -080010284 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -070010285 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -080010286 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010287 hdd_context_t *pHddCtx;
10288 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010289
10290 ENTER();
10291
10292 if( NULL == dev )
10293 {
10294 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010295 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010296 return -ENODEV;
10297 }
10298 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010299
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010300 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10301 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10302 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010303 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010304 "%s: device_mode = %s (%d) freq = %d", __func__,
10305 hdd_device_modetoString(pAdapter->device_mode),
10306 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010307
10308 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10309 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010310 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010311 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010312 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010313 }
10314
10315 /*
10316 * Do freq to chan conversion
10317 * TODO: for 11a
10318 */
10319
10320 channel = ieee80211_frequency_to_channel(freq);
10321
10322 /* Check freq range */
10323 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10324 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10325 {
10326 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010327 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010328 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10329 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10330 return -EINVAL;
10331 }
10332
10333 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10334
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010335 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10336 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010337 {
10338 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10339 {
10340 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010341 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010342 return -EINVAL;
10343 }
10344 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10345 "%s: set channel to [%d] for device mode =%d",
10346 __func__, channel,pAdapter->device_mode);
10347 }
10348 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010349 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010350 )
10351 {
10352 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10353 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10354 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10355
10356 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10357 {
10358 /* Link is up then return cant set channel*/
10359 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010360 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010361 return -EINVAL;
10362 }
10363
10364 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10365 pHddStaCtx->conn_info.operationChannel = channel;
10366 pRoamProfile->ChannelInfo.ChannelList =
10367 &pHddStaCtx->conn_info.operationChannel;
10368 }
10369 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010370 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010371 )
10372 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010373 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10374 {
10375 if(VOS_STATUS_SUCCESS !=
10376 wlan_hdd_validate_operation_channel(pAdapter,channel))
10377 {
10378 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010379 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010380 return -EINVAL;
10381 }
10382 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10383 }
10384 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010385 {
10386 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10387
10388 /* If auto channel selection is configured as enable/ 1 then ignore
10389 channel set by supplicant
10390 */
10391 if ( cfg_param->apAutoChannelSelection )
10392 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010393 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10394 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010395 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010396 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10397 __func__, hdd_device_modetoString(pAdapter->device_mode),
10398 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010399 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010400 else
10401 {
10402 if(VOS_STATUS_SUCCESS !=
10403 wlan_hdd_validate_operation_channel(pAdapter,channel))
10404 {
10405 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010406 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010407 return -EINVAL;
10408 }
10409 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10410 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010411 }
10412 }
10413 else
10414 {
10415 hddLog(VOS_TRACE_LEVEL_FATAL,
10416 "%s: Invalid device mode failed to set valid channel", __func__);
10417 return -EINVAL;
10418 }
10419 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010420 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010421}
10422
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010423static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10424 struct net_device *dev,
10425 struct ieee80211_channel *chan,
10426 enum nl80211_channel_type channel_type
10427 )
10428{
10429 int ret;
10430
10431 vos_ssr_protect(__func__);
10432 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10433 vos_ssr_unprotect(__func__);
10434
10435 return ret;
10436}
10437
Anurag Chouhan83026002016-12-13 22:46:21 +053010438#ifdef DHCP_SERVER_OFFLOAD
10439void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10440 VOS_STATUS status)
10441{
10442 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10443
10444 ENTER();
10445
10446 if (NULL == adapter)
10447 {
10448 hddLog(VOS_TRACE_LEVEL_ERROR,
10449 "%s: adapter is NULL",__func__);
10450 return;
10451 }
10452
10453 adapter->dhcp_status.dhcp_offload_status = status;
10454 vos_event_set(&adapter->dhcp_status.vos_event);
10455 return;
10456}
10457
10458/**
10459 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10460 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010461 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010462 *
10463 * Return: None
10464 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010465VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10466 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010467{
10468 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10469 sir_dhcp_srv_offload_info dhcp_srv_info;
10470 tANI_U8 num_entries = 0;
10471 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10472 tANI_U8 num;
10473 tANI_U32 temp;
10474 VOS_STATUS ret;
10475
10476 ENTER();
10477
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010478 if (!re_init) {
10479 ret = wlan_hdd_validate_context(hdd_ctx);
10480 if (0 != ret)
10481 return VOS_STATUS_E_INVAL;
10482 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010483
10484 /* Prepare the request to send to SME */
10485 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10486 if (NULL == dhcp_srv_info) {
10487 hddLog(VOS_TRACE_LEVEL_ERROR,
10488 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10489 return VOS_STATUS_E_NOMEM;
10490 }
10491
10492 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10493
10494 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10495 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10496 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10497 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10498 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10499 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10500
10501 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10502 srv_ip,
10503 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010504 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010505 if (num_entries != IPADDR_NUM_ENTRIES) {
10506 hddLog(VOS_TRACE_LEVEL_ERROR,
10507 "%s: incorrect IP address (%s) assigned for DHCP server!",
10508 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10509 vos_mem_free(dhcp_srv_info);
10510 return VOS_STATUS_E_FAILURE;
10511 }
10512
10513 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10514 hddLog(VOS_TRACE_LEVEL_ERROR,
10515 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10516 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10517 vos_mem_free(dhcp_srv_info);
10518 return VOS_STATUS_E_FAILURE;
10519 }
10520
10521 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10522 hddLog(VOS_TRACE_LEVEL_ERROR,
10523 "%s: invalid IP address (%s)! The last field must be less than 100!",
10524 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10525 vos_mem_free(dhcp_srv_info);
10526 return VOS_STATUS_E_FAILURE;
10527 }
10528
10529 for (num = 0; num < num_entries; num++) {
10530 temp = srv_ip[num];
10531 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10532 }
10533
10534 if (eHAL_STATUS_SUCCESS !=
10535 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10536 hddLog(VOS_TRACE_LEVEL_ERROR,
10537 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10538 vos_mem_free(dhcp_srv_info);
10539 return VOS_STATUS_E_FAILURE;
10540 }
10541
10542 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10543 "%s: enable DHCP Server offload successfully!", __func__);
10544
10545 vos_mem_free(dhcp_srv_info);
10546 return 0;
10547}
10548#endif /* DHCP_SERVER_OFFLOAD */
10549
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010550/*
10551 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10552 * @wiphy_chan: wiphy channel number
10553 * @rfChannel: channel hw value
10554 * @disable: Disable/enable the flags
10555 *
10556 * Modify wiphy flags and cds state if channel is indoor.
10557 *
10558 * Return: void
10559 */
10560void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
10561 v_U32_t rfChannel, bool disable)
10562{
10563 v_U32_t channelLoop;
10564 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10565
10566 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10567
10568 if (rfChannels[channelLoop].channelNum == rfChannel) {
10569 channelEnum = (eRfChannels)channelLoop;
10570 break;
10571 }
10572 }
10573
10574 if (INVALID_RF_CHANNEL == channelEnum)
10575 return;
10576
10577 if (disable) {
10578 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10579 wiphy_chan->flags |=
10580 IEEE80211_CHAN_DISABLED;
10581 regChannels[channelEnum].enabled =
10582 NV_CHANNEL_DISABLE;
10583 }
10584 } else {
10585 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10586 wiphy_chan->flags &=
10587 ~IEEE80211_CHAN_DISABLED;
10588 /*
10589 * Indoor channels are marked as DFS
10590 * during regulatory processing
10591 */
10592
10593 regChannels[channelEnum].enabled =
10594 NV_CHANNEL_DFS;
10595 }
10596 }
10597
10598}
10599
10600void hdd_update_indoor_channel(hdd_context_t *hdd_ctx,
10601 bool disable)
10602{
10603 int band_num;
10604 int chan_num;
10605 v_U32_t rfChannel;
10606 struct ieee80211_channel *wiphy_chan;
10607 struct wiphy *wiphy;
10608
10609 ENTER();
10610 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10611
10612 wiphy = hdd_ctx->wiphy;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010613 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010614
10615 if (wiphy->bands[band_num] == NULL)
10616 continue;
10617
10618 for (chan_num = 0;
10619 chan_num < wiphy->bands[band_num]->n_channels;
10620 chan_num++) {
10621
10622 wiphy_chan =
10623 &(wiphy->bands[band_num]->channels[chan_num]);
10624 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10625
10626 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
10627 disable);
10628 }
10629 }
10630 EXIT();
10631}
10632
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010633/*
10634 * FUNCTION: wlan_hdd_disconnect
10635 * This function is used to issue a disconnect request to SME
10636 */
10637int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10638{
10639 int status, result = 0;
10640 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10641 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10642 long ret;
10643 eConnectionState prev_conn_state;
10644 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
10645
10646 ENTER();
10647
10648 status = wlan_hdd_validate_context(pHddCtx);
10649 if (0 != status)
10650 {
10651 return status;
10652 }
10653 /* Indicate sme of disconnect so that in progress connection or preauth
10654 * can be aborted
10655 */
10656 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10657 pAdapter->sessionId);
10658 pHddCtx->isAmpAllowed = VOS_TRUE;
10659
10660 /* Need to apply spin lock before decreasing active sessions
10661 * as there can be chance for double decrement if context switch
10662 * Calls hdd_DisConnectHandler.
10663 */
10664
10665 prev_conn_state = pHddStaCtx->conn_info.connState;
10666
10667 spin_lock_bh(&pAdapter->lock_for_active_session);
10668 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10669 {
10670 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10671 }
10672 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10673 spin_unlock_bh(&pAdapter->lock_for_active_session);
10674 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
10675
10676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10677 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10678
10679 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10680
10681 /*
10682 * stop tx queues before deleting STA/BSS context from the firmware.
10683 * tx has to be disabled because the firmware can get busy dropping
10684 * the tx frames after BSS/STA has been deleted and will not send
10685 * back a response resulting in WDI timeout
10686 */
10687 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10688 netif_tx_disable(pAdapter->dev);
10689 netif_carrier_off(pAdapter->dev);
10690
10691 wlan_hdd_check_and_stop_mon(pAdapter, true);
10692
10693 /*issue disconnect*/
10694 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10695 pAdapter->sessionId, reason);
10696 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
10697 prev_conn_state != eConnectionState_Connecting)
10698 {
10699 hddLog(LOG1,
10700 FL("status = %d, already disconnected"), status);
10701 result = 0;
10702 /*
10703 * Wait here instead of returning directly. This will block the
10704 * next connect command and allow processing of the disconnect
10705 * in SME else we might hit some race conditions leading to SME
10706 * and HDD out of sync. As disconnect is already in progress,
10707 * wait here for 1 sec instead of 5 sec.
10708 */
10709 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
10710 goto wait_for_disconnect;
10711 }
10712 /*
10713 * Wait here instead of returning directly, this will block the next
10714 * connect command and allow processing of the scan for ssid and
10715 * the previous connect command in CSR. Else we might hit some
10716 * race conditions leading to SME and HDD out of sync.
10717 */
10718 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10719 {
10720 hddLog(LOG1,
10721 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
10722 }
10723 else if ( 0 != status )
10724 {
10725 hddLog(LOGE,
10726 FL("csrRoamDisconnect failure, returned %d"),
10727 (int)status);
10728 result = -EINVAL;
10729 goto disconnected;
10730 }
10731wait_for_disconnect:
10732 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
10733 msecs_to_jiffies(wait_time));
10734 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
10735 {
10736 hddLog(LOGE,
10737 "%s: Failed to disconnect, timed out", __func__);
10738 result = -ETIMEDOUT;
10739 }
10740disconnected:
10741 hddLog(LOG1,
10742 FL("Set HDD connState to eConnectionState_NotConnected"));
10743 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10744#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
10745 /* Sending disconnect event to userspace for kernel version < 3.11
10746 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
10747 */
10748 hddLog(LOG1, FL("Send disconnected event to userspace"));
10749
10750 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
10751 WLAN_REASON_UNSPECIFIED);
10752#endif
10753
10754 EXIT();
10755 return result;
10756}
10757
10758/*
10759 * hdd_check_and_disconnect_sta_on_invalid_channel() - Disconnect STA if it is
10760 * on indoor channel
10761 * @hdd_ctx: pointer to hdd context
10762 *
10763 * STA should be disconnected before starting the SAP if it is on indoor
10764 * channel.
10765 *
10766 * Return: void
10767 */
10768void hdd_check_and_disconnect_sta_on_invalid_channel(hdd_context_t *hdd_ctx)
10769{
10770
10771 hdd_adapter_t *sta_adapter;
10772 tANI_U8 sta_chan;
10773
10774 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
10775
10776 if (!sta_chan) {
10777 hddLog(LOG1, FL("STA not connected"));
10778 return;
10779 }
10780
10781 hddLog(LOG1, FL("STA connected on chan %hu"), sta_chan);
10782
10783 if (sme_IsChannelValid(hdd_ctx->hHal, sta_chan)) {
10784 hddLog(LOG1, FL("STA connected on chan %hu and it is valid"),
10785 sta_chan);
10786 return;
10787 }
10788
10789 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
10790
10791 if (!sta_adapter) {
10792 hddLog(LOG1, FL("STA adapter doesn't exist"));
10793 return;
10794 }
10795
10796 hddLog(LOG1, FL("chan %hu not valid, issue disconnect"), sta_chan);
10797 /* Issue Disconnect request */
10798 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10799}
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010800
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010801int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx)
10802{
10803 struct hdd_cache_channels *cache_chann;
10804 struct wiphy *wiphy;
10805 int freq, status, rfChannel;
10806 int i, band_num, channel_num;
10807 struct ieee80211_channel *wiphy_channel;
10808
10809 ENTER();
10810
10811 if (!hdd_ctx) {
10812 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10813 return -EINVAL;
10814 }
10815
10816 wiphy = hdd_ctx->wiphy;
10817
10818 mutex_lock(&hdd_ctx->cache_channel_lock);
10819
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010820 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010821
10822 if (!cache_chann || !cache_chann->num_channels) {
10823 hddLog(VOS_TRACE_LEVEL_INFO,
10824 "%s channel list is NULL or num channels are zero",
10825 __func__);
10826 mutex_unlock(&hdd_ctx->cache_channel_lock);
10827 return -EINVAL;
10828 }
10829
10830 for (i = 0; i < cache_chann->num_channels; i++) {
10831 status = hdd_wlan_get_freq(
10832 cache_chann->channel_info[i].channel_num,
10833 &freq);
10834
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010835 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
10836 band_num++) {
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010837 for (channel_num = 0; channel_num <
10838 wiphy->bands[band_num]->n_channels;
10839 channel_num++) {
10840 wiphy_channel = &(wiphy->bands[band_num]->
10841 channels[channel_num]);
10842 if (wiphy_channel->center_freq == freq) {
10843 rfChannel = wiphy_channel->hw_value;
10844 /*
10845 *Restore the orginal states
10846 *of the channels
10847 */
10848 vos_nv_set_channel_state(
10849 rfChannel,
10850 cache_chann->
10851 channel_info[i].reg_status);
10852 wiphy_channel->flags =
10853 cache_chann->
10854 channel_info[i].wiphy_status;
10855 break;
10856 }
10857 }
10858 if (channel_num < wiphy->bands[band_num]->n_channels)
10859 break;
10860 }
10861 }
10862
10863 mutex_unlock(&hdd_ctx->cache_channel_lock);
10864
10865 status = sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10866 if (status)
10867 hddLog(VOS_TRACE_LEVEL_ERROR, "Can't Restore channel list");
10868 EXIT();
10869
10870 return 0;
10871}
10872
10873/*
10874 * wlan_hdd_disable_channels() - Cache the the channels
10875 * and current state of the channels from the channel list
10876 * received in the command and disable the channels on the
10877 * wiphy and NV table.
10878 * @hdd_ctx: Pointer to hdd context
10879 *
10880 * @return: 0 on success, Error code on failure
10881 */
10882
10883static int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx)
10884{
10885 struct hdd_cache_channels *cache_chann;
10886 struct wiphy *wiphy;
10887 int freq, status, rfChannel;
10888 int i, band_num, band_ch_num;
10889 struct ieee80211_channel *wiphy_channel;
10890
10891 if (!hdd_ctx) {
10892 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10893 return -EINVAL;
10894 }
10895
10896 wiphy = hdd_ctx->wiphy;
10897
10898 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010899 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010900
10901 if (!cache_chann || !cache_chann->num_channels) {
10902 hddLog(VOS_TRACE_LEVEL_INFO,
10903 "%s channel list is NULL or num channels are zero",
10904 __func__);
10905 mutex_unlock(&hdd_ctx->cache_channel_lock);
10906 return -EINVAL;
10907 }
10908
10909 for (i = 0; i < cache_chann->num_channels; i++) {
10910 status = hdd_wlan_get_freq(
10911 cache_chann->channel_info[i].channel_num,
10912 &freq);
10913
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010914 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010915 band_num++) {
10916 for (band_ch_num = 0; band_ch_num <
10917 wiphy->bands[band_num]->n_channels;
10918 band_ch_num++) {
10919 wiphy_channel = &(wiphy->bands[band_num]->
10920 channels[band_ch_num]);
10921 if (wiphy_channel->center_freq == freq) {
10922 rfChannel = wiphy_channel->hw_value;
10923 /*
10924 * Cache the current states of
10925 * the channels
10926 */
10927 cache_chann->
10928 channel_info[i].reg_status =
10929 vos_nv_getChannelEnabledState(
10930 rfChannel);
10931
10932 cache_chann->
10933 channel_info[i].wiphy_status =
10934 wiphy_channel->flags;
10935 hddLog(VOS_TRACE_LEVEL_INFO,
10936 "Disable channel %d reg_stat %d wiphy_stat 0x%x",
10937 cache_chann->
10938 channel_info[i].channel_num,
10939 cache_chann->
10940 channel_info[i].reg_status,
10941 wiphy_channel->flags);
10942
10943 vos_nv_set_channel_state(
10944 rfChannel,
10945 NV_CHANNEL_DISABLE);
10946 wiphy_channel->flags |=
10947 IEEE80211_CHAN_DISABLED;
10948 break;
10949 }
10950 }
10951 if (band_ch_num < wiphy->bands[band_num]->n_channels)
10952 break;
10953 }
10954 }
10955
10956 mutex_unlock(&hdd_ctx->cache_channel_lock);
10957 sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10958 return 0;
10959}
10960
Jeff Johnson295189b2012-06-20 16:38:30 -070010961#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10962static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10963 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010964#else
10965static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10966 struct cfg80211_beacon_data *params,
10967 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010968 enum nl80211_hidden_ssid hidden_ssid,
10969 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010970#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010971{
10972 tsap_Config_t *pConfig;
10973 beacon_data_t *pBeacon = NULL;
10974 struct ieee80211_mgmt *pMgmt_frame;
10975 v_U8_t *pIe=NULL;
10976 v_U16_t capab_info;
10977 eCsrAuthType RSNAuthType;
10978 eCsrEncryptionType RSNEncryptType;
10979 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010980 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010981 tpWLAN_SAPEventCB pSapEventCallback;
10982 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070010983 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010984 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010985 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010986 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070010987 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080010988 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +053010989 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070010990 v_BOOL_t MFPCapable = VOS_FALSE;
10991 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010992 v_BOOL_t sapEnable11AC =
10993 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053010994 u_int16_t prev_rsn_length = 0;
10995
Jeff Johnson295189b2012-06-20 16:38:30 -070010996 ENTER();
10997
Nitesh Shah9b066282017-06-06 18:05:52 +053010998 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010999 iniConfig = pHddCtx->cfg_ini;
11000
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011001 /* Mark the indoor channel (passive) to disable */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011002 if (iniConfig->disable_indoor_channel &&
11003 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011004 hdd_update_indoor_channel(pHddCtx, true);
11005
11006 if (!VOS_IS_STATUS_SUCCESS(
11007 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
11008 hdd_update_indoor_channel(pHddCtx, false);
11009 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
11010 FL("Can't start BSS: update channel list failed"));
11011 return eHAL_STATUS_FAILURE;
11012 }
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053011013
11014 /* check if STA is on indoor channel */
11015 if (hdd_is_sta_sap_scc_allowed_on_dfs_chan(pHddCtx))
11016 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011017 }
11018
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011019 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
11020 /* Disable the channels received in command SET_DISABLE_CHANNEL_LIST*/
11021 wlan_hdd_disable_channels(pHddCtx);
11022 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
11023 }
11024
Jeff Johnson295189b2012-06-20 16:38:30 -070011025 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
11026
11027 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
11028
11029 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
11030
11031 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
11032
11033 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
11034
11035 //channel is already set in the set_channel Call back
11036 //pConfig->channel = pCommitConfig->channel;
11037
11038 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011039 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070011040 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
11041
11042 pConfig->dtim_period = pBeacon->dtim_period;
11043
Arif Hussain6d2a3322013-11-17 19:50:10 -080011044 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070011045 pConfig->dtim_period);
11046
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080011047 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070011048 {
11049 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011050 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053011051 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
11052 {
11053 tANI_BOOLEAN restartNeeded;
11054 pConfig->ieee80211d = 1;
11055 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
11056 sme_setRegInfo(hHal, pConfig->countryCode);
11057 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
11058 }
11059 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070011060 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070011061 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070011062 pConfig->ieee80211d = 1;
11063 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
11064 sme_setRegInfo(hHal, pConfig->countryCode);
11065 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070011066 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011067 else
11068 {
11069 pConfig->ieee80211d = 0;
11070 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011071 /*
11072 * If auto channel is configured i.e. channel is 0,
11073 * so skip channel validation.
11074 */
11075 if( AUTO_CHANNEL_SELECT != pConfig->channel )
11076 {
11077 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
11078 {
11079 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011080 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011081 ret = -EINVAL;
11082 goto error;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011083 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011084 pConfig->user_config_channel = pConfig->channel;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011085 }
11086 else
11087 {
11088 if(1 != pHddCtx->is_dynamic_channel_range_set)
11089 {
11090 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
11091 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
11092 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
11093 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011094 pHddCtx->is_dynamic_channel_range_set = 0;
11095 pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011096 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011097 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011098 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011099 {
11100 pConfig->ieee80211d = 0;
11101 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011102
11103#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11104 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11105 pConfig->authType = eSAP_OPEN_SYSTEM;
11106 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11107 pConfig->authType = eSAP_SHARED_KEY;
11108 else
11109 pConfig->authType = eSAP_AUTO_SWITCH;
11110#else
11111 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11112 pConfig->authType = eSAP_OPEN_SYSTEM;
11113 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11114 pConfig->authType = eSAP_SHARED_KEY;
11115 else
11116 pConfig->authType = eSAP_AUTO_SWITCH;
11117#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011118
11119 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011120
11121 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070011122 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053011123#ifdef SAP_AUTH_OFFLOAD
11124 /* In case of sap offload, hostapd.conf is configuted with open mode and
11125 * security is configured from ini file. Due to open mode in hostapd.conf
11126 * privacy bit is set to false which will result in not sending,
11127 * data packets as encrypted.
11128 * If enable_sap_auth_offload is enabled in ini and
11129 * sap_auth_offload_sec_type is type of WPA2-PSK,
11130 * driver will set privacy bit to 1.
11131 */
11132 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
11133 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
11134 pConfig->privacy = VOS_TRUE;
11135#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011136
11137 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
11138
11139 /*Set wps station to configured*/
11140 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
11141
11142 if(pIe)
11143 {
11144 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
11145 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011146 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011147 ret = -EINVAL;
11148 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011149 }
11150 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
11151 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070011152 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070011153 /* Check 15 bit of WPS IE as it contain information for wps state
11154 * WPS state
11155 */
11156 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
11157 {
11158 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
11159 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
11160 {
11161 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
11162 }
11163 }
11164 }
11165 else
11166 {
11167 pConfig->wps_state = SAP_WPS_DISABLED;
11168 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011169 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070011170
c_hpothufe599e92014-06-16 11:38:55 +053011171 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11172 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11173 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
11174 eCSR_ENCRYPT_TYPE_NONE;
11175
Jeff Johnson295189b2012-06-20 16:38:30 -070011176 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053011177 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011178 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011179 WLAN_EID_RSN);
11180 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011181 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011182 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011183 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11184 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11185 pConfig->RSNWPAReqIELength);
11186 else
11187 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11188 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011189 /* The actual processing may eventually be more extensive than
11190 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070011191 * by the app.
11192 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011193 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011194 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11195 &RSNEncryptType,
11196 &mcRSNEncryptType,
11197 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011198 &MFPCapable,
11199 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011200 pConfig->RSNWPAReqIE[1]+2,
11201 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011202
11203 if( VOS_STATUS_SUCCESS == status )
11204 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011205 /* Now copy over all the security attributes you have
11206 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011207 * */
11208 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11209 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11210 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11211 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011212 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011213 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011214 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11215 }
11216 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011217
Jeff Johnson295189b2012-06-20 16:38:30 -070011218 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11219 pBeacon->tail, pBeacon->tail_len);
11220
11221 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
11222 {
Kapil Gupta137ef892016-12-13 19:38:00 +053011223 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011224 {
11225 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053011226 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070011227 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011228 if (pConfig->RSNWPAReqIELength <=
11229 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
11230 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
11231 pIe[1] + 2);
11232 else
11233 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11234 pConfig->RSNWPAReqIELength);
11235
Jeff Johnson295189b2012-06-20 16:38:30 -070011236 }
11237 else
11238 {
11239 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011240 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11241 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11242 pConfig->RSNWPAReqIELength);
11243 else
11244 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11245 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011246 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011247 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11248 &RSNEncryptType,
11249 &mcRSNEncryptType,
11250 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011251 &MFPCapable,
11252 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011253 pConfig->RSNWPAReqIE[1]+2,
11254 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011255
11256 if( VOS_STATUS_SUCCESS == status )
11257 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011258 /* Now copy over all the security attributes you have
11259 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011260 * */
11261 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11262 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11263 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11264 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011265 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011266 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011267 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11268 }
11269 }
11270 }
11271
Kapil Gupta137ef892016-12-13 19:38:00 +053011272 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070011273 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011274 ret = -EINVAL;
11275 goto error;
Jeff Johnson4416a782013-03-25 14:17:50 -070011276 }
11277
Jeff Johnson295189b2012-06-20 16:38:30 -070011278 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
11279
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011280#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011281 if (params->ssid != NULL)
11282 {
11283 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
11284 pConfig->SSIDinfo.ssid.length = params->ssid_len;
11285 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11286 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11287 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011288#else
11289 if (ssid != NULL)
11290 {
11291 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
11292 pConfig->SSIDinfo.ssid.length = ssid_len;
11293 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11294 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11295 }
11296#endif
11297
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011298 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070011299 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011300
Jeff Johnson295189b2012-06-20 16:38:30 -070011301 /* default value */
11302 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
11303 pConfig->num_accept_mac = 0;
11304 pConfig->num_deny_mac = 0;
11305
11306 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11307 pBeacon->tail, pBeacon->tail_len);
11308
11309 /* pIe for black list is following form:
11310 type : 1 byte
11311 length : 1 byte
11312 OUI : 4 bytes
11313 acl type : 1 byte
11314 no of mac addr in black list: 1 byte
11315 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011316 */
11317 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011318 {
11319 pConfig->SapMacaddr_acl = pIe[6];
11320 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011321 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011322 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011323 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
11324 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011325 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11326 for (i = 0; i < pConfig->num_deny_mac; i++)
11327 {
11328 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11329 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011330 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011331 }
11332 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11333 pBeacon->tail, pBeacon->tail_len);
11334
11335 /* pIe for white list is following form:
11336 type : 1 byte
11337 length : 1 byte
11338 OUI : 4 bytes
11339 acl type : 1 byte
11340 no of mac addr in white list: 1 byte
11341 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011342 */
11343 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011344 {
11345 pConfig->SapMacaddr_acl = pIe[6];
11346 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011347 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011348 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011349 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
11350 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011351 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11352 for (i = 0; i < pConfig->num_accept_mac; i++)
11353 {
11354 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11355 acl_entry++;
11356 }
11357 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011358
Jeff Johnson295189b2012-06-20 16:38:30 -070011359 wlan_hdd_set_sapHwmode(pHostapdAdapter);
11360
Jeff Johnsone7245742012-09-05 17:12:55 -070011361#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011362 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011363 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
11364 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053011365 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
11366 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011367 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
11368 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011369 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
11370 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070011371 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011372 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070011373 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011374 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011375
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011376 /* If ACS disable and selected channel <= 14
11377 * OR
11378 * ACS enabled and ACS operating band is choosen as 2.4
11379 * AND
11380 * VHT in 2.4G Disabled
11381 * THEN
11382 * Fallback to 11N mode
11383 */
11384 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
11385 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053011386 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011387 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011388 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011389 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
11390 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011391 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
11392 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011393 }
11394#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011395
Jeff Johnson295189b2012-06-20 16:38:30 -070011396 // ht_capab is not what the name conveys,this is used for protection bitmap
11397 pConfig->ht_capab =
11398 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
11399
Kapil Gupta137ef892016-12-13 19:38:00 +053011400 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070011401 {
11402 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011403 ret = -EINVAL;
11404 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011405 }
11406
11407 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011408 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070011409 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
11410 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011411 pConfig->obssProtEnabled =
11412 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070011413
Chet Lanctot8cecea22014-02-11 19:09:36 -080011414#ifdef WLAN_FEATURE_11W
11415 pConfig->mfpCapable = MFPCapable;
11416 pConfig->mfpRequired = MFPRequired;
11417 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
11418 pConfig->mfpCapable, pConfig->mfpRequired);
11419#endif
11420
Arif Hussain6d2a3322013-11-17 19:50:10 -080011421 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070011422 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011423 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
11424 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
11425 (int)pConfig->channel);
11426 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
11427 pConfig->SapHw_mode, pConfig->privacy,
11428 pConfig->authType);
11429 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
11430 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
11431 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
11432 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070011433
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011434 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070011435 {
11436 //Bss already started. just return.
11437 //TODO Probably it should update some beacon params.
11438 hddLog( LOGE, "Bss Already started...Ignore the request");
11439 EXIT();
11440 return 0;
11441 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011442
Agarwal Ashish51325b52014-06-16 16:50:49 +053011443 if (vos_max_concurrent_connections_reached()) {
11444 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011445 ret = -EINVAL;
11446 goto error;
Agarwal Ashish51325b52014-06-16 16:50:49 +053011447 }
11448
Jeff Johnson295189b2012-06-20 16:38:30 -070011449 pConfig->persona = pHostapdAdapter->device_mode;
11450
Peng Xu2446a892014-09-05 17:21:18 +053011451 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
11452 if ( NULL != psmeConfig)
11453 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011454 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053011455 sme_GetConfigParam(hHal, psmeConfig);
11456 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011457#ifdef WLAN_FEATURE_AP_HT40_24G
11458 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11459 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
11460 && pHddCtx->cfg_ini->apHT40_24GEnabled)
11461 {
11462 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
11463 sme_UpdateConfig (hHal, psmeConfig);
11464 }
11465#endif
Peng Xu2446a892014-09-05 17:21:18 +053011466 vos_mem_free(psmeConfig);
11467 }
Peng Xuafc34e32014-09-25 13:23:55 +053011468 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053011469
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011470 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
11471
Jeff Johnson295189b2012-06-20 16:38:30 -070011472 pSapEventCallback = hdd_hostapd_SAPEventCB;
11473 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
11474 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
11475 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011476 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011477 ret = -EINVAL;
11478 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011479 }
11480
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011481 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070011482 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
11483
11484 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011485
Jeff Johnson295189b2012-06-20 16:38:30 -070011486 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011487 {
11488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011489 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070011490 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011491 VOS_ASSERT(0);
11492 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011493
Jeff Johnson295189b2012-06-20 16:38:30 -070011494 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053011495 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
11496 VOS_STATUS_SUCCESS)
11497 {
11498 hddLog(LOGE,FL("Fail to get Softap sessionID"));
11499 VOS_ASSERT(0);
11500 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053011501 /* Initialize WMM configuation */
11502 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011503 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011504
Anurag Chouhan83026002016-12-13 22:46:21 +053011505#ifdef DHCP_SERVER_OFFLOAD
11506 /* set dhcp server offload */
11507 if (iniConfig->enable_dhcp_srv_offload &&
11508 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011509 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053011510 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053011511 if (!VOS_IS_STATUS_SUCCESS(status))
11512 {
11513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11514 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011515 vos_event_reset(&pHostapdState->vosEvent);
11516 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11517 status = vos_wait_single_event(&pHostapdState->vosEvent,
11518 10000);
11519 if (!VOS_IS_STATUS_SUCCESS(status)) {
11520 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011521 ret = -EINVAL;
11522 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011523 }
11524 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011525 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011526 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
11527 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
11528 {
11529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11530 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
11531 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011532 vos_event_reset(&pHostapdState->vosEvent);
11533 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11534 status = vos_wait_single_event(&pHostapdState->vosEvent,
11535 10000);
11536 if (!VOS_IS_STATUS_SUCCESS(status)) {
11537 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011538 ret = -EINVAL;
11539 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011540 }
11541 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011542 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011543#ifdef MDNS_OFFLOAD
11544 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011545 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011546 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
11547 if (VOS_IS_STATUS_SUCCESS(status))
11548 {
11549 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11550 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011551 vos_event_reset(&pHostapdState->vosEvent);
11552 if (VOS_STATUS_SUCCESS ==
11553 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11554 status = vos_wait_single_event(&pHostapdState->vosEvent,
11555 10000);
11556 if (!VOS_IS_STATUS_SUCCESS(status)) {
11557 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011558 ret = -EINVAL;
11559 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011560 }
11561 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011562 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011563 status = vos_wait_single_event(&pHostapdAdapter->
11564 mdns_status.vos_event, 2000);
11565 if (!VOS_IS_STATUS_SUCCESS(status) ||
11566 pHostapdAdapter->mdns_status.mdns_enable_status ||
11567 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
11568 pHostapdAdapter->mdns_status.mdns_resp_status)
11569 {
11570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11571 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
11572 pHostapdAdapter->mdns_status.mdns_enable_status,
11573 pHostapdAdapter->mdns_status.mdns_fqdn_status,
11574 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011575 vos_event_reset(&pHostapdState->vosEvent);
11576 if (VOS_STATUS_SUCCESS ==
11577 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11578 status = vos_wait_single_event(&pHostapdState->vosEvent,
11579 10000);
11580 if (!VOS_IS_STATUS_SUCCESS(status)) {
11581 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011582 ret = -EINVAL;
11583 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011584 }
11585 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011586 }
11587 }
11588#endif /* MDNS_OFFLOAD */
11589 } else {
11590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11591 ("DHCP Disabled ini %d, FW %d"),
11592 iniConfig->enable_dhcp_srv_offload,
11593 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053011594 }
11595#endif /* DHCP_SERVER_OFFLOAD */
11596
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011597#ifdef WLAN_FEATURE_P2P_DEBUG
11598 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
11599 {
11600 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
11601 {
11602 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11603 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011604 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011605 }
11606 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
11607 {
11608 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11609 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011610 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011611 }
11612 }
11613#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053011614 /* Check and restart SAP if it is on Unsafe channel */
11615 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011616
Jeff Johnson295189b2012-06-20 16:38:30 -070011617 pHostapdState->bCommit = TRUE;
11618 EXIT();
11619
11620 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011621error:
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011622 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11623 wlan_hdd_restore_channels(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011624 /* Revert the indoor to passive marking if START BSS fails */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011625 if (iniConfig->disable_indoor_channel &&
11626 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011627 hdd_update_indoor_channel(pHddCtx, false);
11628 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
11629 }
11630
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011631 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
11632 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011633}
11634
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011635#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011636static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011637 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011638 struct beacon_parameters *params)
11639{
11640 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011641 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011642 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011643
11644 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011645
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011646 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11647 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11648 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011649 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11650 hdd_device_modetoString(pAdapter->device_mode),
11651 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011652
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011653 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11654 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011655 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011656 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011657 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011658 }
11659
Agarwal Ashish51325b52014-06-16 16:50:49 +053011660 if (vos_max_concurrent_connections_reached()) {
11661 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11662 return -EINVAL;
11663 }
11664
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011665 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011666 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011667 )
11668 {
11669 beacon_data_t *old,*new;
11670
11671 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011672
Jeff Johnson295189b2012-06-20 16:38:30 -070011673 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011674 {
11675 hddLog(VOS_TRACE_LEVEL_WARN,
11676 FL("already beacon info added to session(%d)"),
11677 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011678 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011679 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011680
11681 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11682
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011683 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011684 {
11685 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011686 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011687 return -EINVAL;
11688 }
11689
11690 pAdapter->sessionCtx.ap.beacon = new;
11691
11692 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11693 }
11694
11695 EXIT();
11696 return status;
11697}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011698
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011699static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11700 struct net_device *dev,
11701 struct beacon_parameters *params)
11702{
11703 int ret;
11704
11705 vos_ssr_protect(__func__);
11706 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11707 vos_ssr_unprotect(__func__);
11708
11709 return ret;
11710}
11711
11712static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011713 struct net_device *dev,
11714 struct beacon_parameters *params)
11715{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011716 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011717 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11718 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011719 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011720
11721 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011722
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011723 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11724 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11725 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11726 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11727 __func__, hdd_device_modetoString(pAdapter->device_mode),
11728 pAdapter->device_mode);
11729
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011730 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11731 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011732 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011733 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011734 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011735 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011736
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011737 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011738 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011739 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011740 {
11741 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011742
Jeff Johnson295189b2012-06-20 16:38:30 -070011743 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011744
Jeff Johnson295189b2012-06-20 16:38:30 -070011745 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011746 {
11747 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11748 FL("session(%d) old and new heads points to NULL"),
11749 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011750 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011751 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011752
11753 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11754
11755 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011756 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011757 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011758 return -EINVAL;
11759 }
11760
11761 pAdapter->sessionCtx.ap.beacon = new;
11762
11763 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11764 }
11765
11766 EXIT();
11767 return status;
11768}
11769
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011770static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11771 struct net_device *dev,
11772 struct beacon_parameters *params)
11773{
11774 int ret;
11775
11776 vos_ssr_protect(__func__);
11777 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11778 vos_ssr_unprotect(__func__);
11779
11780 return ret;
11781}
11782
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011783#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11784
11785#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011786static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011787 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011788#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011789static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011790 struct net_device *dev)
11791#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011792{
11793 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070011794 hdd_context_t *pHddCtx = NULL;
11795 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011796 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011797 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011798
11799 ENTER();
11800
11801 if (NULL == pAdapter)
11802 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011804 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011805 return -ENODEV;
11806 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011807
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011808 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11809 TRACE_CODE_HDD_CFG80211_STOP_AP,
11810 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011811 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11812 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011813 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011814 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011815 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011816 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011817
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011818 pScanInfo = &pHddCtx->scan_info;
11819
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011820 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11821 __func__, hdd_device_modetoString(pAdapter->device_mode),
11822 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011823
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011824 ret = wlan_hdd_scan_abort(pAdapter);
11825
Girish Gowli4bf7a632014-06-12 13:42:11 +053011826 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011827 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011828 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11829 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011830
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011831 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011832 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11834 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011835
Jeff Johnsone7245742012-09-05 17:12:55 -070011836 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011837 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011838 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011839 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011840 }
11841
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011842 /* Delete all associated STAs before stopping AP/P2P GO */
11843 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011844 hdd_hostapd_stop(dev);
11845
Jeff Johnson295189b2012-06-20 16:38:30 -070011846 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011847 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011848 )
11849 {
11850 beacon_data_t *old;
11851
11852 old = pAdapter->sessionCtx.ap.beacon;
11853
11854 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011855 {
11856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11857 FL("session(%d) beacon data points to NULL"),
11858 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011859 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011860 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011861
Jeff Johnson295189b2012-06-20 16:38:30 -070011862 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011863
11864 mutex_lock(&pHddCtx->sap_lock);
11865 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11866 {
Abhishek Singh10e17cf2018-03-12 14:34:22 +053011867 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
11868 hdd_wait_for_ecsa_complete(pHddCtx);
Jeff Johnson4416a782013-03-25 14:17:50 -070011869 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011870 {
11871 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11872
11873 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11874
11875 if (!VOS_IS_STATUS_SUCCESS(status))
11876 {
11877 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011878 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011879 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011880 }
11881 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011882 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011883 /* BSS stopped, clear the active sessions for this device mode */
11884 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011885 }
11886 mutex_unlock(&pHddCtx->sap_lock);
11887
11888 if(status != VOS_STATUS_SUCCESS)
11889 {
11890 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011891 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011892 return -EINVAL;
11893 }
11894
Jeff Johnson4416a782013-03-25 14:17:50 -070011895 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011896 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11897 ==eHAL_STATUS_FAILURE)
11898 {
11899 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011900 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011901 }
11902
Jeff Johnson4416a782013-03-25 14:17:50 -070011903 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011904 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11905 eANI_BOOLEAN_FALSE) )
11906 {
11907 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011908 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011909 }
11910
11911 // Reset WNI_CFG_PROBE_RSP Flags
11912 wlan_hdd_reset_prob_rspies(pAdapter);
11913
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011914 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11915
Jeff Johnson295189b2012-06-20 16:38:30 -070011916 pAdapter->sessionCtx.ap.beacon = NULL;
11917 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011918#ifdef WLAN_FEATURE_P2P_DEBUG
11919 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11920 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11921 {
11922 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11923 "GO got removed");
11924 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11925 }
11926#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011927 }
11928 EXIT();
11929 return status;
11930}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011931
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011932#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11933static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
11934 struct net_device *dev)
11935{
11936 int ret;
11937
11938 vos_ssr_protect(__func__);
11939 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
11940 vos_ssr_unprotect(__func__);
11941
11942 return ret;
11943}
11944#else
11945static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
11946 struct net_device *dev)
11947{
11948 int ret;
11949
11950 vos_ssr_protect(__func__);
11951 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
11952 vos_ssr_unprotect(__func__);
11953
11954 return ret;
11955}
11956#endif
11957
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011958#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
11959
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011960static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011961 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011962 struct cfg80211_ap_settings *params)
11963{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011964 hdd_adapter_t *pAdapter;
11965 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011966 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011967
11968 ENTER();
11969
Girish Gowlib143d7a2015-02-18 19:39:55 +053011970 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011971 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011972 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053011973 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011974 return -ENODEV;
11975 }
11976
11977 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11978 if (NULL == pAdapter)
11979 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011980 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011981 "%s: HDD adapter is Null", __func__);
11982 return -ENODEV;
11983 }
11984
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011985 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11986 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
11987 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011988 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
11989 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011990 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011991 "%s: HDD adapter magic is invalid", __func__);
11992 return -ENODEV;
11993 }
11994
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011995 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11996
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011997 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011998 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011999 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012000 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012001 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012002 }
12003
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012004 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
12005 __func__, hdd_device_modetoString(pAdapter->device_mode),
12006 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012007
12008 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012009 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012010 )
12011 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012012 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012013
12014 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012015
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012016 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012017 {
12018 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12019 FL("already beacon info added to session(%d)"),
12020 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012021 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012022 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012023
Girish Gowlib143d7a2015-02-18 19:39:55 +053012024#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
12025 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12026 &new,
12027 &params->beacon);
12028#else
12029 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12030 &new,
12031 &params->beacon,
12032 params->dtim_period);
12033#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012034
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012035 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012036 {
12037 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012038 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012039 return -EINVAL;
12040 }
12041 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080012042#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070012043 wlan_hdd_cfg80211_set_channel(wiphy, dev,
12044#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
12045 params->channel, params->channel_type);
12046#else
12047 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
12048#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080012049#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012050 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012051 params->ssid_len, params->hidden_ssid,
12052 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012053 }
12054
12055 EXIT();
12056 return status;
12057}
12058
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012059static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
12060 struct net_device *dev,
12061 struct cfg80211_ap_settings *params)
12062{
12063 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012064
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012065 vos_ssr_protect(__func__);
12066 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
12067 vos_ssr_unprotect(__func__);
12068
12069 return ret;
12070}
12071
12072static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012073 struct net_device *dev,
12074 struct cfg80211_beacon_data *params)
12075{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012076 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012077 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012078 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012079
12080 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012081
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012082 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12083 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
12084 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080012085 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012086 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012087
12088 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12089 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012090 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012091 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012092 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012093 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012094
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012095 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012096 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012097 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012098 {
12099 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012100
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012101 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012102
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012103 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012104 {
12105 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12106 FL("session(%d) beacon data points to NULL"),
12107 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012108 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012109 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012110
12111 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
12112
12113 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012114 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012115 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012116 return -EINVAL;
12117 }
12118
12119 pAdapter->sessionCtx.ap.beacon = new;
12120
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012121 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
12122 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012123 }
12124
12125 EXIT();
12126 return status;
12127}
12128
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012129static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
12130 struct net_device *dev,
12131 struct cfg80211_beacon_data *params)
12132{
12133 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012134
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012135 vos_ssr_protect(__func__);
12136 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
12137 vos_ssr_unprotect(__func__);
12138
12139 return ret;
12140}
12141
12142#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070012143
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012144static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012145 struct net_device *dev,
12146 struct bss_parameters *params)
12147{
12148 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012149 hdd_context_t *pHddCtx;
12150 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012151
12152 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012153
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012154 if (NULL == pAdapter)
12155 {
12156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12157 "%s: HDD adapter is Null", __func__);
12158 return -ENODEV;
12159 }
12160 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012161 ret = wlan_hdd_validate_context(pHddCtx);
12162 if (0 != ret)
12163 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012164 return ret;
12165 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012166 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12167 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
12168 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012169 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12170 __func__, hdd_device_modetoString(pAdapter->device_mode),
12171 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012172
12173 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012174 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012175 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012176 {
12177 /* ap_isolate == -1 means that in change bss, upper layer doesn't
12178 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012179 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070012180 {
12181 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012182 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012183 }
12184
12185 EXIT();
12186 return 0;
12187}
12188
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012189static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
12190 struct net_device *dev,
12191 struct bss_parameters *params)
12192{
12193 int ret;
12194
12195 vos_ssr_protect(__func__);
12196 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
12197 vos_ssr_unprotect(__func__);
12198
12199 return ret;
12200}
Kiet Lam10841362013-11-01 11:36:50 +053012201/* FUNCTION: wlan_hdd_change_country_code_cd
12202* to wait for contry code completion
12203*/
12204void* wlan_hdd_change_country_code_cb(void *pAdapter)
12205{
12206 hdd_adapter_t *call_back_pAdapter = pAdapter;
12207 complete(&call_back_pAdapter->change_country_code);
12208 return NULL;
12209}
12210
Jeff Johnson295189b2012-06-20 16:38:30 -070012211/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012212 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070012213 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
12214 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012215int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012216 struct net_device *ndev,
12217 enum nl80211_iftype type,
12218 u32 *flags,
12219 struct vif_params *params
12220 )
12221{
12222 struct wireless_dev *wdev;
12223 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012224 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070012225 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012226 tCsrRoamProfile *pRoamProfile = NULL;
12227 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012228 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012229 eMib_dot11DesiredBssType connectedBssType;
12230 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012231 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012232
12233 ENTER();
12234
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012235 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012236 {
12237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12238 "%s: Adapter context is null", __func__);
12239 return VOS_STATUS_E_FAILURE;
12240 }
12241
12242 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12243 if (!pHddCtx)
12244 {
12245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12246 "%s: HDD context is null", __func__);
12247 return VOS_STATUS_E_FAILURE;
12248 }
12249
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012250 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12251 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
12252 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012253 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012254 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012255 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012256 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012257 }
12258
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012259 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12260 __func__, hdd_device_modetoString(pAdapter->device_mode),
12261 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012262
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012263 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
12264 hddLog(VOS_TRACE_LEVEL_FATAL,
12265 "%s: STA + MON is in progress, cannot change interface",
12266 __func__);
12267 }
12268
Agarwal Ashish51325b52014-06-16 16:50:49 +053012269 if (vos_max_concurrent_connections_reached()) {
12270 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12271 return -EINVAL;
12272 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012273 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012274 wdev = ndev->ieee80211_ptr;
12275
12276#ifdef WLAN_BTAMP_FEATURE
12277 if((NL80211_IFTYPE_P2P_CLIENT == type)||
12278 (NL80211_IFTYPE_ADHOC == type)||
12279 (NL80211_IFTYPE_AP == type)||
12280 (NL80211_IFTYPE_P2P_GO == type))
12281 {
12282 pHddCtx->isAmpAllowed = VOS_FALSE;
12283 // stop AMP traffic
12284 status = WLANBAP_StopAmp();
12285 if(VOS_STATUS_SUCCESS != status )
12286 {
12287 pHddCtx->isAmpAllowed = VOS_TRUE;
12288 hddLog(VOS_TRACE_LEVEL_FATAL,
12289 "%s: Failed to stop AMP", __func__);
12290 return -EINVAL;
12291 }
12292 }
12293#endif //WLAN_BTAMP_FEATURE
12294 /* Reset the current device mode bit mask*/
12295 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
12296
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053012297 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
12298 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
12299 (type == NL80211_IFTYPE_P2P_GO)))
12300 {
12301 /* Notify Mode change in case of concurrency.
12302 * Below function invokes TDLS teardown Functionality Since TDLS is
12303 * not Supported in case of concurrency i.e Once P2P session
12304 * is detected disable offchannel and teardown TDLS links
12305 */
12306 hddLog(LOG1,
12307 FL("Device mode = %d Interface type = %d"),
12308 pAdapter->device_mode, type);
12309 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
12310 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053012311
Jeff Johnson295189b2012-06-20 16:38:30 -070012312 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012313 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070012314 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012315 )
12316 {
12317 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012318 if (!pWextState)
12319 {
12320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12321 "%s: pWextState is null", __func__);
12322 return VOS_STATUS_E_FAILURE;
12323 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012324 pRoamProfile = &pWextState->roamProfile;
12325 LastBSSType = pRoamProfile->BSSType;
12326
12327 switch (type)
12328 {
12329 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012330 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012331 hddLog(VOS_TRACE_LEVEL_INFO,
12332 "%s: setting interface Type to INFRASTRUCTURE", __func__);
12333 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012334#ifdef WLAN_FEATURE_11AC
12335 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
12336 {
12337 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
12338 }
12339#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012340 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070012341 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012342 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012343 //Check for sub-string p2p to confirm its a p2p interface
12344 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012345 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053012346#ifdef FEATURE_WLAN_TDLS
12347 mutex_lock(&pHddCtx->tdls_lock);
12348 wlan_hdd_tdls_exit(pAdapter, TRUE);
12349 mutex_unlock(&pHddCtx->tdls_lock);
12350#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012351 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12352 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12353 }
12354 else
12355 {
12356 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012357 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012358 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012359 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053012360
Jeff Johnson295189b2012-06-20 16:38:30 -070012361 case NL80211_IFTYPE_ADHOC:
12362 hddLog(VOS_TRACE_LEVEL_INFO,
12363 "%s: setting interface Type to ADHOC", __func__);
12364 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
12365 pRoamProfile->phyMode =
12366 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070012367 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012368 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053012369 hdd_set_ibss_ops( pAdapter );
12370 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053012371
12372 status = hdd_sta_id_hash_attach(pAdapter);
12373 if (VOS_STATUS_SUCCESS != status) {
12374 hddLog(VOS_TRACE_LEVEL_ERROR,
12375 FL("Failed to initialize hash for IBSS"));
12376 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012377 break;
12378
12379 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012380 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012381 {
12382 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12383 "%s: setting interface Type to %s", __func__,
12384 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
12385
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012386 //Cancel any remain on channel for GO mode
12387 if (NL80211_IFTYPE_P2P_GO == type)
12388 {
12389 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
12390 }
Mohit Khanna0f232092012-09-11 14:46:08 -070012391 if (NL80211_IFTYPE_AP == type)
12392 {
12393 /* As Loading WLAN Driver one interface being created for p2p device
12394 * address. This will take one HW STA and the max number of clients
12395 * that can connect to softAP will be reduced by one. so while changing
12396 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
12397 * interface as it is not required in SoftAP mode.
12398 */
12399
12400 // Get P2P Adapter
12401 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
12402
12403 if (pP2pAdapter)
12404 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053012405 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053012406 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070012407 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12408 }
12409 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053012410 //Disable IMPS & BMPS for SAP/GO
12411 if(VOS_STATUS_E_FAILURE ==
12412 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
12413 {
12414 //Fail to Exit BMPS
12415 VOS_ASSERT(0);
12416 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053012417
12418 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
12419
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012420#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070012421
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012422 /* A Mutex Lock is introduced while changing the mode to
12423 * protect the concurrent access for the Adapters by TDLS
12424 * module.
12425 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012426 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012427#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012428 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053012429 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012430 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070012431 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12432 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012433#ifdef FEATURE_WLAN_TDLS
12434 mutex_unlock(&pHddCtx->tdls_lock);
12435#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012436 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
12437 (pConfig->apRandomBssidEnabled))
12438 {
12439 /* To meet Android requirements create a randomized
12440 MAC address of the form 02:1A:11:Fx:xx:xx */
12441 get_random_bytes(&ndev->dev_addr[3], 3);
12442 ndev->dev_addr[0] = 0x02;
12443 ndev->dev_addr[1] = 0x1A;
12444 ndev->dev_addr[2] = 0x11;
12445 ndev->dev_addr[3] |= 0xF0;
12446 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
12447 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080012448 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
12449 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012450 }
12451
Jeff Johnson295189b2012-06-20 16:38:30 -070012452 hdd_set_ap_ops( pAdapter->dev );
12453
Kiet Lam10841362013-11-01 11:36:50 +053012454 /* This is for only SAP mode where users can
12455 * control country through ini.
12456 * P2P GO follows station country code
12457 * acquired during the STA scanning. */
12458 if((NL80211_IFTYPE_AP == type) &&
12459 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
12460 {
12461 int status = 0;
12462 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
12463 "%s: setting country code from INI ", __func__);
12464 init_completion(&pAdapter->change_country_code);
12465 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
12466 (void *)(tSmeChangeCountryCallback)
12467 wlan_hdd_change_country_code_cb,
12468 pConfig->apCntryCode, pAdapter,
12469 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012470 eSIR_FALSE,
12471 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053012472 if (eHAL_STATUS_SUCCESS == status)
12473 {
12474 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012475 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053012476 &pAdapter->change_country_code,
12477 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012478 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053012479 {
12480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012481 FL("SME Timed out while setting country code %ld"),
12482 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080012483
12484 if (pHddCtx->isLogpInProgress)
12485 {
12486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12487 "%s: LOGP in Progress. Ignore!!!", __func__);
12488 return -EAGAIN;
12489 }
Kiet Lam10841362013-11-01 11:36:50 +053012490 }
12491 }
12492 else
12493 {
12494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012495 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053012496 return -EINVAL;
12497 }
12498 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053012499 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070012500 if(status != VOS_STATUS_SUCCESS)
12501 {
12502 hddLog(VOS_TRACE_LEVEL_FATAL,
12503 "%s: Error initializing the ap mode", __func__);
12504 return -EINVAL;
12505 }
12506 hdd_set_conparam(1);
12507
Nirav Shah7e3c8132015-06-22 23:51:42 +053012508 status = hdd_sta_id_hash_attach(pAdapter);
12509 if (VOS_STATUS_SUCCESS != status)
12510 {
12511 hddLog(VOS_TRACE_LEVEL_ERROR,
12512 FL("Failed to initialize hash for AP"));
12513 return -EINVAL;
12514 }
12515
Jeff Johnson295189b2012-06-20 16:38:30 -070012516 /*interface type changed update in wiphy structure*/
12517 if(wdev)
12518 {
12519 wdev->iftype = type;
12520 pHddCtx->change_iface = type;
12521 }
12522 else
12523 {
12524 hddLog(VOS_TRACE_LEVEL_ERROR,
12525 "%s: ERROR !!!! Wireless dev is NULL", __func__);
12526 return -EINVAL;
12527 }
12528 goto done;
12529 }
12530
12531 default:
12532 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12533 __func__);
12534 return -EOPNOTSUPP;
12535 }
12536 }
12537 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012538 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070012539 )
12540 {
12541 switch(type)
12542 {
12543 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012544 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012545 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053012546
12547 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012548#ifdef FEATURE_WLAN_TDLS
12549
12550 /* A Mutex Lock is introduced while changing the mode to
12551 * protect the concurrent access for the Adapters by TDLS
12552 * module.
12553 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012554 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012555#endif
c_hpothu002231a2015-02-05 14:58:51 +053012556 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012557 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012558 //Check for sub-string p2p to confirm its a p2p interface
12559 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012560 {
12561 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12562 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12563 }
12564 else
12565 {
12566 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012567 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012568 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053012569
12570 /* set con_mode to STA only when no SAP concurrency mode */
12571 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
12572 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012573 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012574 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
12575 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012576#ifdef FEATURE_WLAN_TDLS
12577 mutex_unlock(&pHddCtx->tdls_lock);
12578#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053012579 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070012580 if( VOS_STATUS_SUCCESS != status )
12581 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070012582 /* In case of JB, for P2P-GO, only change interface will be called,
12583 * This is the right place to enable back bmps_imps()
12584 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012585 if (pHddCtx->hdd_wlan_suspended)
12586 {
12587 hdd_set_pwrparams(pHddCtx);
12588 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012589 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012590 goto done;
12591 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012592 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012593 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012594 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12595 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012596 goto done;
12597 default:
12598 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12599 __func__);
12600 return -EOPNOTSUPP;
12601
12602 }
12603
12604 }
12605 else
12606 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012607 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
12608 __func__, hdd_device_modetoString(pAdapter->device_mode),
12609 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012610 return -EOPNOTSUPP;
12611 }
12612
12613
12614 if(pRoamProfile)
12615 {
12616 if ( LastBSSType != pRoamProfile->BSSType )
12617 {
12618 /*interface type changed update in wiphy structure*/
12619 wdev->iftype = type;
12620
12621 /*the BSS mode changed, We need to issue disconnect
12622 if connected or in IBSS disconnect state*/
12623 if ( hdd_connGetConnectedBssType(
12624 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
12625 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
12626 {
12627 /*need to issue a disconnect to CSR.*/
12628 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12629 if( eHAL_STATUS_SUCCESS ==
12630 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12631 pAdapter->sessionId,
12632 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12633 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012634 ret = wait_for_completion_interruptible_timeout(
12635 &pAdapter->disconnect_comp_var,
12636 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12637 if (ret <= 0)
12638 {
12639 hddLog(VOS_TRACE_LEVEL_ERROR,
12640 FL("wait on disconnect_comp_var failed %ld"), ret);
12641 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012642 }
12643 }
12644 }
12645 }
12646
12647done:
12648 /*set bitmask based on updated value*/
12649 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012650
12651 /* Only STA mode support TM now
12652 * all other mode, TM feature should be disabled */
12653 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12654 (~VOS_STA & pHddCtx->concurrency_mode) )
12655 {
12656 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12657 }
12658
Jeff Johnson295189b2012-06-20 16:38:30 -070012659#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012660 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012661 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012662 {
12663 //we are ok to do AMP
12664 pHddCtx->isAmpAllowed = VOS_TRUE;
12665 }
12666#endif //WLAN_BTAMP_FEATURE
12667 EXIT();
12668 return 0;
12669}
12670
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012671/*
12672 * FUNCTION: wlan_hdd_cfg80211_change_iface
12673 * wrapper function to protect the actual implementation from SSR.
12674 */
12675int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12676 struct net_device *ndev,
12677 enum nl80211_iftype type,
12678 u32 *flags,
12679 struct vif_params *params
12680 )
12681{
12682 int ret;
12683
12684 vos_ssr_protect(__func__);
12685 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12686 vos_ssr_unprotect(__func__);
12687
12688 return ret;
12689}
12690
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012691#ifdef FEATURE_WLAN_TDLS
12692static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012693 struct net_device *dev,
12694#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12695 const u8 *mac,
12696#else
12697 u8 *mac,
12698#endif
12699 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012700{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012701 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012702 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012703 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012704 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012705 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012706 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012707
12708 ENTER();
12709
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012710 if (!dev) {
12711 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12712 return -EINVAL;
12713 }
12714
12715 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12716 if (!pAdapter) {
12717 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12718 return -EINVAL;
12719 }
12720
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012721 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012722 {
12723 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12724 "Invalid arguments");
12725 return -EINVAL;
12726 }
Hoonki Lee27511902013-03-14 18:19:06 -070012727
12728 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12729 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12730 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012731 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012732 "%s: TDLS mode is disabled OR not enabled in FW."
12733 MAC_ADDRESS_STR " Request declined.",
12734 __func__, MAC_ADDR_ARRAY(mac));
12735 return -ENOTSUPP;
12736 }
12737
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012738 if (pHddCtx->isLogpInProgress)
12739 {
12740 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12741 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012742 wlan_hdd_tdls_set_link_status(pAdapter,
12743 mac,
12744 eTDLS_LINK_IDLE,
12745 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012746 return -EBUSY;
12747 }
12748
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012749 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012750 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012751
12752 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012754 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12755 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012756 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012757 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012758 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012759
12760 /* in add station, we accept existing valid staId if there is */
12761 if ((0 == update) &&
12762 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12763 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012764 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012766 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012767 " link_status %d. staId %d. add station ignored.",
12768 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012769 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012770 return 0;
12771 }
12772 /* in change station, we accept only when staId is valid */
12773 if ((1 == update) &&
12774 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12775 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12776 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012777 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012778 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012779 "%s: " MAC_ADDRESS_STR
12780 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012781 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12782 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12783 mutex_unlock(&pHddCtx->tdls_lock);
12784 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012785 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012786 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012787
12788 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012789 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012790 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12792 "%s: " MAC_ADDRESS_STR
12793 " TDLS setup is ongoing. Request declined.",
12794 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012795 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012796 }
12797
12798 /* first to check if we reached to maximum supported TDLS peer.
12799 TODO: for now, return -EPERM looks working fine,
12800 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012801 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12802 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012803 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12805 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012806 " TDLS Max peer already connected. Request declined."
12807 " Num of peers (%d), Max allowed (%d).",
12808 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12809 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012810 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012811 }
12812 else
12813 {
12814 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012815 mutex_lock(&pHddCtx->tdls_lock);
12816 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012817 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012818 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012819 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12821 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12822 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012823 return -EPERM;
12824 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012825 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012826 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012827 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012828 wlan_hdd_tdls_set_link_status(pAdapter,
12829 mac,
12830 eTDLS_LINK_CONNECTING,
12831 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012832
Jeff Johnsond75fe012013-04-06 10:53:06 -070012833 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012834 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012835 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012837 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012838 if(StaParams->htcap_present)
12839 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012840 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012841 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012843 "ht_capa->extended_capabilities: %0x",
12844 StaParams->HTCap.extendedHtCapInfo);
12845 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012847 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012849 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012850 if(StaParams->vhtcap_present)
12851 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012853 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12854 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12855 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12856 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012857 {
12858 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012859 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012860 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012862 "[%d]: %x ", i, StaParams->supported_rates[i]);
12863 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012864 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012865 else if ((1 == update) && (NULL == StaParams))
12866 {
12867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12868 "%s : update is true, but staParams is NULL. Error!", __func__);
12869 return -EPERM;
12870 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012871
12872 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12873
12874 if (!update)
12875 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012876 /*Before adding sta make sure that device exited from BMPS*/
12877 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12878 {
12879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12880 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12881 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12882 if (status != VOS_STATUS_SUCCESS) {
12883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12884 }
12885 }
12886
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012887 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012888 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012889 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012890 hddLog(VOS_TRACE_LEVEL_ERROR,
12891 FL("Failed to add TDLS peer STA. Enable Bmps"));
12892 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012893 return -EPERM;
12894 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012895 }
12896 else
12897 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012898 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012899 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012900 if (ret != eHAL_STATUS_SUCCESS) {
12901 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12902 return -EPERM;
12903 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012904 }
12905
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012906 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012907 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12908
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012909 mutex_lock(&pHddCtx->tdls_lock);
12910 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12911
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012912 if ((pTdlsPeer != NULL) &&
12913 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012914 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012915 hddLog(VOS_TRACE_LEVEL_ERROR,
12916 FL("peer link status %u"), pTdlsPeer->link_status);
12917 mutex_unlock(&pHddCtx->tdls_lock);
12918 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012919 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012920 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012921
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012922 if (ret <= 0)
12923 {
12924 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12925 "%s: timeout waiting for tdls add station indication %ld",
12926 __func__, ret);
12927 goto error;
12928 }
12929
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012930 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12931 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012933 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012934 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012935 }
12936
12937 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012938
12939error:
Atul Mittal115287b2014-07-08 13:26:33 +053012940 wlan_hdd_tdls_set_link_status(pAdapter,
12941 mac,
12942 eTDLS_LINK_IDLE,
12943 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012944 return -EPERM;
12945
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012946}
12947#endif
12948
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053012949VOS_STATUS wlan_hdd_send_sta_authorized_event(
12950 hdd_adapter_t *adapter,
12951 hdd_context_t *hdd_ctx,
12952 const v_MACADDR_t *mac_addr)
12953{
12954 struct sk_buff *vendor_event;
12955 uint32_t sta_flags = 0;
12956 VOS_STATUS status;
12957
12958 ENTER();
12959
12960 if (!hdd_ctx) {
12961 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null"));
12962 return -EINVAL;
12963 }
12964
12965 vendor_event =
12966 cfg80211_vendor_event_alloc(
Ashish Kumar Dhanotiyac99fbef2018-04-11 12:23:32 +053012967 hdd_ctx->wiphy,
12968#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
12969 &adapter->wdev,
12970#endif
12971 sizeof(sta_flags) +
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053012972 VOS_MAC_ADDR_SIZE + NLMSG_HDRLEN,
12973 QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX,
12974 GFP_KERNEL);
12975 if (!vendor_event) {
12976 hddLog(VOS_TRACE_LEVEL_ERROR,
12977 FL("cfg80211_vendor_event_alloc failed"));
12978 return -EINVAL;
12979 }
12980
12981 sta_flags |= BIT(NL80211_STA_FLAG_AUTHORIZED);
12982
12983 status = nla_put_u32(vendor_event,
12984 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS,
12985 sta_flags);
12986 if (status) {
12987 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA flag put fails"));
12988 kfree_skb(vendor_event);
12989 return VOS_STATUS_E_FAILURE;
12990 }
12991 status = nla_put(vendor_event,
12992 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_MAC,
12993 VOS_MAC_ADDR_SIZE, mac_addr->bytes);
12994 if (status) {
12995 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA MAC put fails"));
12996 kfree_skb(vendor_event);
12997 return VOS_STATUS_E_FAILURE;
12998 }
12999
13000 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
13001
13002 EXIT();
13003 return 0;
13004}
13005
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013006static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013007 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013008#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13009 const u8 *mac,
13010#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013011 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013012#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013013 struct station_parameters *params)
13014{
13015 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013016 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013017 hdd_context_t *pHddCtx;
13018 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013019 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013020 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013021#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013022 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013023 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013024 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013025 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013026#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013027
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013028 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013029
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013030 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013031 if ((NULL == pAdapter))
13032 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013034 "invalid adapter ");
13035 return -EINVAL;
13036 }
13037
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013038 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13039 TRACE_CODE_HDD_CHANGE_STATION,
13040 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053013041 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013042
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013043 ret = wlan_hdd_validate_context(pHddCtx);
13044 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053013045 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013046 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013047 }
13048
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013049 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13050
13051 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013052 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013053 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13054 "invalid HDD station context");
13055 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013056 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013057 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
13058
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013059 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
13060 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070013061 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013062 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070013063 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013064 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070013065 WLANTL_STA_AUTHENTICATED);
13066
Gopichand Nakkala29149562013-05-10 21:43:41 +053013067 if (status != VOS_STATUS_SUCCESS)
13068 {
13069 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13070 "%s: Not able to change TL state to AUTHENTICATED", __func__);
13071 return -EINVAL;
13072 }
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013073 status = wlan_hdd_send_sta_authorized_event(pAdapter, pHddCtx,
13074 &STAMacAddress);
13075 if (status != VOS_STATUS_SUCCESS)
13076 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013077 }
13078 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070013079 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
13080 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013081#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013082 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13083 StaParams.capability = params->capability;
13084 StaParams.uapsd_queues = params->uapsd_queues;
13085 StaParams.max_sp = params->max_sp;
13086
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013087 /* Convert (first channel , number of channels) tuple to
13088 * the total list of channels. This goes with the assumption
13089 * that if the first channel is < 14, then the next channels
13090 * are an incremental of 1 else an incremental of 4 till the number
13091 * of channels.
13092 */
13093 if (0 != params->supported_channels_len) {
13094 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013095 for ( i = 0 ; i < params->supported_channels_len
13096 && j < SIR_MAC_MAX_SUPP_CHANNELS; i+=2)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013097 {
13098 int wifi_chan_index;
13099 StaParams.supported_channels[j] = params->supported_channels[i];
13100 wifi_chan_index =
13101 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
13102 no_of_channels = params->supported_channels[i+1];
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013103 for(k=1; k <= no_of_channels
13104 && j < SIR_MAC_MAX_SUPP_CHANNELS - 1; k++)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013105 {
13106 StaParams.supported_channels[j+1] =
13107 StaParams.supported_channels[j] + wifi_chan_index;
13108 j+=1;
13109 }
13110 }
13111 StaParams.supported_channels_len = j;
13112 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053013113 if (params->supported_oper_classes_len >
13114 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
13115 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13116 "received oper classes:%d, resetting it to max supported %d",
13117 params->supported_oper_classes_len,
13118 SIR_MAC_MAX_SUPP_OPER_CLASSES);
13119 params->supported_oper_classes_len =
13120 SIR_MAC_MAX_SUPP_OPER_CLASSES;
13121 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013122 vos_mem_copy(StaParams.supported_oper_classes,
13123 params->supported_oper_classes,
13124 params->supported_oper_classes_len);
13125 StaParams.supported_oper_classes_len =
13126 params->supported_oper_classes_len;
13127
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013128 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
13129 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13130 "received extn capabilities:%d, resetting it to max supported",
13131 params->ext_capab_len);
13132 params->ext_capab_len = sizeof(StaParams.extn_capability);
13133 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013134 if (0 != params->ext_capab_len)
13135 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013136 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013137
13138 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013139 {
13140 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013141 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013142 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013143
13144 StaParams.supported_rates_len = params->supported_rates_len;
13145
13146 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
13147 * The supported_rates array , for all the structures propogating till Add Sta
13148 * to the firmware has to be modified , if the supplicant (ieee80211) is
13149 * modified to send more rates.
13150 */
13151
13152 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
13153 */
13154 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
13155 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
13156
13157 if (0 != StaParams.supported_rates_len) {
13158 int i = 0;
13159 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
13160 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013161 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013162 "Supported Rates with Length %d", StaParams.supported_rates_len);
13163 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013165 "[%d]: %0x", i, StaParams.supported_rates[i]);
13166 }
13167
13168 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013169 {
13170 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013171 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013172 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013173
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013174 if (0 != params->ext_capab_len ) {
13175 /*Define A Macro : TODO Sunil*/
13176 if ((1<<4) & StaParams.extn_capability[3]) {
13177 isBufSta = 1;
13178 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013179 /* TDLS Channel Switching Support */
13180 if ((1<<6) & StaParams.extn_capability[3]) {
13181 isOffChannelSupported = 1;
13182 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013183 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013184
13185 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053013186 (params->ht_capa || params->vht_capa ||
13187 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013188 /* TDLS Peer is WME/QoS capable */
13189 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013190
13191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13192 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
13193 __func__, isQosWmmSta, StaParams.htcap_present);
13194
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013195 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
13196 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013197 isOffChannelSupported,
13198 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013199
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013200 if (VOS_STATUS_SUCCESS != status) {
13201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13202 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
13203 return -EINVAL;
13204 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013205 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
13206
13207 if (VOS_STATUS_SUCCESS != status) {
13208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13209 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
13210 return -EINVAL;
13211 }
13212 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013213#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053013214 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013215 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013216 return status;
13217}
13218
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013219#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13220static int wlan_hdd_change_station(struct wiphy *wiphy,
13221 struct net_device *dev,
13222 const u8 *mac,
13223 struct station_parameters *params)
13224#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013225static int wlan_hdd_change_station(struct wiphy *wiphy,
13226 struct net_device *dev,
13227 u8 *mac,
13228 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013229#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013230{
13231 int ret;
13232
13233 vos_ssr_protect(__func__);
13234 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
13235 vos_ssr_unprotect(__func__);
13236
13237 return ret;
13238}
13239
Jeff Johnson295189b2012-06-20 16:38:30 -070013240/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013241 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013242 * This function is used to initialize the key information
13243 */
13244#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013245static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013246 struct net_device *ndev,
13247 u8 key_index, bool pairwise,
13248 const u8 *mac_addr,
13249 struct key_params *params
13250 )
13251#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013252static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013253 struct net_device *ndev,
13254 u8 key_index, const u8 *mac_addr,
13255 struct key_params *params
13256 )
13257#endif
13258{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013259 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013260 tCsrRoamSetKey setKey;
13261 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013262 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013263 v_U32_t roamId= 0xFF;
13264 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013265 hdd_hostapd_state_t *pHostapdState;
13266 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013267 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013268 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013269 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013270 v_MACADDR_t *peerMacAddr;
13271 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013272 uint8_t staid = HDD_MAX_STA_COUNT;
13273 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013274
13275 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013276
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013277 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13278 TRACE_CODE_HDD_CFG80211_ADD_KEY,
13279 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013280 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13281 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013282 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013283 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013284 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013285 }
13286
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013287 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13288 __func__, hdd_device_modetoString(pAdapter->device_mode),
13289 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013290
13291 if (CSR_MAX_NUM_KEY <= key_index)
13292 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013293 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013294 key_index);
13295
13296 return -EINVAL;
13297 }
13298
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013299 if (CSR_MAX_KEY_LEN < params->key_len)
13300 {
13301 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
13302 params->key_len);
13303
13304 return -EINVAL;
13305 }
13306
Jingxiang Gec438aea2017-10-26 16:44:00 +080013307 if (CSR_MAX_RSC_LEN < params->seq_len)
13308 {
13309 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
13310 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053013311
13312 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080013313 }
13314
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013315 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080013316 "%s: called with key index = %d & key length %d & seq length %d",
13317 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013318
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013319 peerMacAddr = (v_MACADDR_t *)mac_addr;
13320
Jeff Johnson295189b2012-06-20 16:38:30 -070013321 /*extract key idx, key len and key*/
13322 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13323 setKey.keyId = key_index;
13324 setKey.keyLength = params->key_len;
13325 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080013326 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013327
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013328 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013329 {
13330 case WLAN_CIPHER_SUITE_WEP40:
13331 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13332 break;
13333
13334 case WLAN_CIPHER_SUITE_WEP104:
13335 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
13336 break;
13337
13338 case WLAN_CIPHER_SUITE_TKIP:
13339 {
13340 u8 *pKey = &setKey.Key[0];
13341 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
13342
13343 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
13344
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013345 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070013346
13347 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013348 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013349 |--------------|----------|----------|
13350 <---16bytes---><--8bytes--><--8bytes-->
13351
13352 */
13353 /*Sme expects the 32 bytes key to be in the below order
13354
13355 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013356 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013357 |--------------|----------|----------|
13358 <---16bytes---><--8bytes--><--8bytes-->
13359 */
13360 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013361 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070013362
13363 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013364 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013365
13366 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013367 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013368
13369
13370 break;
13371 }
13372
13373 case WLAN_CIPHER_SUITE_CCMP:
13374 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
13375 break;
13376
13377#ifdef FEATURE_WLAN_WAPI
13378 case WLAN_CIPHER_SUITE_SMS4:
13379 {
13380 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13381 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
13382 params->key, params->key_len);
13383 return 0;
13384 }
13385#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013386
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013387#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013388 case WLAN_CIPHER_SUITE_KRK:
13389 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
13390 break;
13391#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013392
13393#ifdef WLAN_FEATURE_11W
13394 case WLAN_CIPHER_SUITE_AES_CMAC:
13395 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070013396 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070013397#endif
13398
Jeff Johnson295189b2012-06-20 16:38:30 -070013399 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013400 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070013401 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013402 status = -EOPNOTSUPP;
13403 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013404 }
13405
13406 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
13407 __func__, setKey.encType);
13408
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013409 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070013410#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13411 (!pairwise)
13412#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013413 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013414#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013415 )
13416 {
13417 /* set group key*/
13418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13419 "%s- %d: setting Broadcast key",
13420 __func__, __LINE__);
13421 setKey.keyDirection = eSIR_RX_ONLY;
13422 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13423 }
13424 else
13425 {
13426 /* set pairwise key*/
13427 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13428 "%s- %d: setting pairwise key",
13429 __func__, __LINE__);
13430 setKey.keyDirection = eSIR_TX_RX;
13431 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013432 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013433 }
13434 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
13435 {
13436 setKey.keyDirection = eSIR_TX_RX;
13437 /*Set the group key*/
13438 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13439 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070013440
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013441 if ( 0 != status )
13442 {
13443 hddLog(VOS_TRACE_LEVEL_ERROR,
13444 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013445 status = -EINVAL;
13446 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013447 }
13448 /*Save the keys here and call sme_RoamSetKey for setting
13449 the PTK after peer joins the IBSS network*/
13450 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
13451 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013452 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013453 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053013454 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
13455 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
13456 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013457 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013458 if( pHostapdState->bssState == BSS_START )
13459 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013460 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13461 vos_status = wlan_hdd_check_ula_done(pAdapter);
13462
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013463 if (peerMacAddr && (pairwise_set_key == true))
13464 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013465
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013466 if ( vos_status != VOS_STATUS_SUCCESS )
13467 {
13468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13469 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13470 __LINE__, vos_status );
13471
13472 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13473
13474 status = -EINVAL;
13475 goto end;
13476 }
13477
Jeff Johnson295189b2012-06-20 16:38:30 -070013478 status = WLANSAP_SetKeySta( pVosContext, &setKey);
13479
13480 if ( status != eHAL_STATUS_SUCCESS )
13481 {
13482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13483 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13484 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013485 status = -EINVAL;
13486 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013487 }
13488 }
13489
13490 /* Saving WEP keys */
13491 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
13492 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
13493 {
13494 //Save the wep key in ap context. Issue setkey after the BSS is started.
13495 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13496 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
13497 }
13498 else
13499 {
13500 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013501 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013502 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
13503 }
13504 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013505 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
13506 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013507 {
13508 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13509 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13510
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013511#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13512 if (!pairwise)
13513#else
13514 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
13515#endif
13516 {
13517 /* set group key*/
13518 if (pHddStaCtx->roam_info.deferKeyComplete)
13519 {
13520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13521 "%s- %d: Perform Set key Complete",
13522 __func__, __LINE__);
13523 hdd_PerformRoamSetKeyComplete(pAdapter);
13524 }
13525 }
13526
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013527 if (pairwise_set_key == true)
13528 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013529
Jeff Johnson295189b2012-06-20 16:38:30 -070013530 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
13531
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080013532 pWextState->roamProfile.Keys.defaultIndex = key_index;
13533
13534
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013535 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013536 params->key, params->key_len);
13537
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013538
Jeff Johnson295189b2012-06-20 16:38:30 -070013539 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13540
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013541 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013542 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013543 __func__, setKey.peerMac[0], setKey.peerMac[1],
13544 setKey.peerMac[2], setKey.peerMac[3],
13545 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013546 setKey.keyDirection);
13547
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013548 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053013549
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013550 if ( vos_status != VOS_STATUS_SUCCESS )
13551 {
13552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013553 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13554 __LINE__, vos_status );
13555
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013556 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013557
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013558 status = -EINVAL;
13559 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013560
13561 }
13562
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013563#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013564 /* The supplicant may attempt to set the PTK once pre-authentication
13565 is done. Save the key in the UMAC and include it in the ADD BSS
13566 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013567 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013568 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013569 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013570 hddLog(VOS_TRACE_LEVEL_INFO_MED,
13571 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013572 status = 0;
13573 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013574 }
13575 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
13576 {
13577 hddLog(VOS_TRACE_LEVEL_ERROR,
13578 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013579 status = -EINVAL;
13580 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013581 }
13582#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070013583
13584 /* issue set key request to SME*/
13585 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13586 pAdapter->sessionId, &setKey, &roamId );
13587
13588 if ( 0 != status )
13589 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013590 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013591 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
13592 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013593 status = -EINVAL;
13594 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013595 }
13596
13597
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013598 /* in case of IBSS as there was no information available about WEP keys during
13599 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070013600 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013601 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
13602 !( ( IW_AUTH_KEY_MGMT_802_1X
13603 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070013604 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
13605 )
13606 &&
13607 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
13608 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
13609 )
13610 )
13611 {
13612 setKey.keyDirection = eSIR_RX_ONLY;
13613 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13614
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013615 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013616 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013617 __func__, setKey.peerMac[0], setKey.peerMac[1],
13618 setKey.peerMac[2], setKey.peerMac[3],
13619 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013620 setKey.keyDirection);
13621
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013622 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013623 pAdapter->sessionId, &setKey, &roamId );
13624
13625 if ( 0 != status )
13626 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013627 hddLog(VOS_TRACE_LEVEL_ERROR,
13628 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013629 __func__, status);
13630 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013631 status = -EINVAL;
13632 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013633 }
13634 }
13635 }
13636
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013637 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013638 for (i = 0; i < params->seq_len; i++) {
13639 rsc_counter |= (params->seq[i] << i*8);
13640 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013641 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
13642 }
13643
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013644end:
13645 /* Need to clear any trace of key value in the memory.
13646 * Thus zero out the memory even though it is local
13647 * variable.
13648 */
13649 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013650 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013651 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013652}
13653
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013654#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13655static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13656 struct net_device *ndev,
13657 u8 key_index, bool pairwise,
13658 const u8 *mac_addr,
13659 struct key_params *params
13660 )
13661#else
13662static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13663 struct net_device *ndev,
13664 u8 key_index, const u8 *mac_addr,
13665 struct key_params *params
13666 )
13667#endif
13668{
13669 int ret;
13670 vos_ssr_protect(__func__);
13671#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13672 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
13673 mac_addr, params);
13674#else
13675 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
13676 params);
13677#endif
13678 vos_ssr_unprotect(__func__);
13679
13680 return ret;
13681}
13682
Jeff Johnson295189b2012-06-20 16:38:30 -070013683/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013684 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013685 * This function is used to get the key information
13686 */
13687#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013688static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013689 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013690 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013691 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013692 const u8 *mac_addr, void *cookie,
13693 void (*callback)(void *cookie, struct key_params*)
13694 )
13695#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013696static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013697 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013698 struct net_device *ndev,
13699 u8 key_index, const u8 *mac_addr, void *cookie,
13700 void (*callback)(void *cookie, struct key_params*)
13701 )
13702#endif
13703{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013704 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013705 hdd_wext_state_t *pWextState = NULL;
13706 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013707 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013708 hdd_context_t *pHddCtx;
13709 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013710
13711 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013712
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013713 if (NULL == pAdapter)
13714 {
13715 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13716 "%s: HDD adapter is Null", __func__);
13717 return -ENODEV;
13718 }
13719
13720 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13721 ret = wlan_hdd_validate_context(pHddCtx);
13722 if (0 != ret)
13723 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013724 return ret;
13725 }
13726
13727 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13728 pRoamProfile = &(pWextState->roamProfile);
13729
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013730 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13731 __func__, hdd_device_modetoString(pAdapter->device_mode),
13732 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013733
Jeff Johnson295189b2012-06-20 16:38:30 -070013734 memset(&params, 0, sizeof(params));
13735
13736 if (CSR_MAX_NUM_KEY <= key_index)
13737 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013738 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013739 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013740 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013741
13742 switch(pRoamProfile->EncryptionType.encryptionType[0])
13743 {
13744 case eCSR_ENCRYPT_TYPE_NONE:
13745 params.cipher = IW_AUTH_CIPHER_NONE;
13746 break;
13747
13748 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13749 case eCSR_ENCRYPT_TYPE_WEP40:
13750 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13751 break;
13752
13753 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13754 case eCSR_ENCRYPT_TYPE_WEP104:
13755 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13756 break;
13757
13758 case eCSR_ENCRYPT_TYPE_TKIP:
13759 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13760 break;
13761
13762 case eCSR_ENCRYPT_TYPE_AES:
13763 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13764 break;
13765
13766 default:
13767 params.cipher = IW_AUTH_CIPHER_NONE;
13768 break;
13769 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013770
c_hpothuaaf19692014-05-17 17:01:48 +053013771 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13772 TRACE_CODE_HDD_CFG80211_GET_KEY,
13773 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013774
Jeff Johnson295189b2012-06-20 16:38:30 -070013775 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13776 params.seq_len = 0;
13777 params.seq = NULL;
13778 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13779 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013780 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013781 return 0;
13782}
13783
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013784#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13785static int wlan_hdd_cfg80211_get_key(
13786 struct wiphy *wiphy,
13787 struct net_device *ndev,
13788 u8 key_index, bool pairwise,
13789 const u8 *mac_addr, void *cookie,
13790 void (*callback)(void *cookie, struct key_params*)
13791 )
13792#else
13793static int wlan_hdd_cfg80211_get_key(
13794 struct wiphy *wiphy,
13795 struct net_device *ndev,
13796 u8 key_index, const u8 *mac_addr, void *cookie,
13797 void (*callback)(void *cookie, struct key_params*)
13798 )
13799#endif
13800{
13801 int ret;
13802
13803 vos_ssr_protect(__func__);
13804#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13805 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13806 mac_addr, cookie, callback);
13807#else
13808 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13809 callback);
13810#endif
13811 vos_ssr_unprotect(__func__);
13812
13813 return ret;
13814}
13815
Jeff Johnson295189b2012-06-20 16:38:30 -070013816/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013817 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013818 * This function is used to delete the key information
13819 */
13820#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013821static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013822 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013823 u8 key_index,
13824 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013825 const u8 *mac_addr
13826 )
13827#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013828static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013829 struct net_device *ndev,
13830 u8 key_index,
13831 const u8 *mac_addr
13832 )
13833#endif
13834{
13835 int status = 0;
13836
13837 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013838 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013839 //it is observed that this is invalidating peer
13840 //key index whenever re-key is done. This is affecting data link.
13841 //It should be ok to ignore del_key.
13842#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013843 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13844 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013845 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13846 tCsrRoamSetKey setKey;
13847 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013848
Jeff Johnson295189b2012-06-20 16:38:30 -070013849 ENTER();
13850
13851 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13852 __func__,pAdapter->device_mode);
13853
13854 if (CSR_MAX_NUM_KEY <= key_index)
13855 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013856 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013857 key_index);
13858
13859 return -EINVAL;
13860 }
13861
13862 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13863 setKey.keyId = key_index;
13864
13865 if (mac_addr)
13866 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13867 else
13868 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13869
13870 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13871
13872 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013873 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013874 )
13875 {
13876
13877 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013878 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13879 if( pHostapdState->bssState == BSS_START)
13880 {
13881 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013882
Jeff Johnson295189b2012-06-20 16:38:30 -070013883 if ( status != eHAL_STATUS_SUCCESS )
13884 {
13885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13886 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13887 __LINE__, status );
13888 }
13889 }
13890 }
13891 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013892 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013893 )
13894 {
13895 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13896
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013897 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13898
13899 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013900 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013901 __func__, setKey.peerMac[0], setKey.peerMac[1],
13902 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013903 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013904 if(pAdapter->sessionCtx.station.conn_info.connState ==
13905 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013906 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013907 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013908 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013909
Jeff Johnson295189b2012-06-20 16:38:30 -070013910 if ( 0 != status )
13911 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013912 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013913 "%s: sme_RoamSetKey failure, returned %d",
13914 __func__, status);
13915 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13916 return -EINVAL;
13917 }
13918 }
13919 }
13920#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013921 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013922 return status;
13923}
13924
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013925#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13926static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13927 struct net_device *ndev,
13928 u8 key_index,
13929 bool pairwise,
13930 const u8 *mac_addr
13931 )
13932#else
13933static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13934 struct net_device *ndev,
13935 u8 key_index,
13936 const u8 *mac_addr
13937 )
13938#endif
13939{
13940 int ret;
13941
13942 vos_ssr_protect(__func__);
13943#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13944 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
13945 mac_addr);
13946#else
13947 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
13948#endif
13949 vos_ssr_unprotect(__func__);
13950
13951 return ret;
13952}
13953
Jeff Johnson295189b2012-06-20 16:38:30 -070013954/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013955 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013956 * This function is used to set the default tx key index
13957 */
13958#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013959static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013960 struct net_device *ndev,
13961 u8 key_index,
13962 bool unicast, bool multicast)
13963#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013964static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013965 struct net_device *ndev,
13966 u8 key_index)
13967#endif
13968{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013969 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013970 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013971 hdd_wext_state_t *pWextState;
13972 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013973 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013974
13975 ENTER();
13976
Gopichand Nakkala29149562013-05-10 21:43:41 +053013977 if ((NULL == pAdapter))
13978 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013980 "invalid adapter");
13981 return -EINVAL;
13982 }
13983
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013984 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13985 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
13986 pAdapter->sessionId, key_index));
13987
Gopichand Nakkala29149562013-05-10 21:43:41 +053013988 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13989 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13990
13991 if ((NULL == pWextState) || (NULL == pHddStaCtx))
13992 {
13993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13994 "invalid Wext state or HDD context");
13995 return -EINVAL;
13996 }
13997
Arif Hussain6d2a3322013-11-17 19:50:10 -080013998 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013999 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014000
Jeff Johnson295189b2012-06-20 16:38:30 -070014001 if (CSR_MAX_NUM_KEY <= key_index)
14002 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014003 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014004 key_index);
14005
14006 return -EINVAL;
14007 }
14008
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014009 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14010 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014011 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014012 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014013 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014014 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014015
Jeff Johnson295189b2012-06-20 16:38:30 -070014016 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070014017 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014018 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014019 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053014020 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080014021 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080014022#ifdef FEATURE_WLAN_WAPI
14023 (eCSR_ENCRYPT_TYPE_WPI !=
14024 pHddStaCtx->conn_info.ucEncryptionType) &&
14025#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014026 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080014027 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070014028 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014029 {
14030 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070014031 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014032
Jeff Johnson295189b2012-06-20 16:38:30 -070014033 tCsrRoamSetKey setKey;
14034 v_U32_t roamId= 0xFF;
14035 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014036
14037 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014038 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014039
Jeff Johnson295189b2012-06-20 16:38:30 -070014040 Keys->defaultIndex = (u8)key_index;
14041 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
14042 setKey.keyId = key_index;
14043 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014044
14045 vos_mem_copy(&setKey.Key[0],
14046 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014047 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014048
Gopichand Nakkala29149562013-05-10 21:43:41 +053014049 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014050
14051 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070014052 &pHddStaCtx->conn_info.bssId[0],
14053 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014054
Gopichand Nakkala29149562013-05-10 21:43:41 +053014055 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
14056 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
14057 eCSR_ENCRYPT_TYPE_WEP104)
14058 {
14059 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
14060 even though ap is configured for WEP-40 encryption. In this canse the key length
14061 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
14062 type(104) and switching encryption type to 40*/
14063 pWextState->roamProfile.EncryptionType.encryptionType[0] =
14064 eCSR_ENCRYPT_TYPE_WEP40;
14065 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
14066 eCSR_ENCRYPT_TYPE_WEP40;
14067 }
14068
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014069 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014070 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014071
Jeff Johnson295189b2012-06-20 16:38:30 -070014072 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014073 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014074 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014075
Jeff Johnson295189b2012-06-20 16:38:30 -070014076 if ( 0 != status )
14077 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014078 hddLog(VOS_TRACE_LEVEL_ERROR,
14079 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014080 status);
14081 return -EINVAL;
14082 }
14083 }
14084 }
14085
14086 /* In SoftAp mode setting key direction for default mode */
14087 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
14088 {
14089 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
14090 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
14091 (eCSR_ENCRYPT_TYPE_AES !=
14092 pWextState->roamProfile.EncryptionType.encryptionType[0])
14093 )
14094 {
14095 /* Saving key direction for default key index to TX default */
14096 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
14097 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
14098 }
14099 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014100 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014101 return status;
14102}
14103
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014104#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14105static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14106 struct net_device *ndev,
14107 u8 key_index,
14108 bool unicast, bool multicast)
14109#else
14110static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14111 struct net_device *ndev,
14112 u8 key_index)
14113#endif
14114{
14115 int ret;
14116 vos_ssr_protect(__func__);
14117#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14118 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
14119 multicast);
14120#else
14121 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
14122#endif
14123 vos_ssr_unprotect(__func__);
14124
14125 return ret;
14126}
14127
Jeff Johnson295189b2012-06-20 16:38:30 -070014128/*
14129 * FUNCTION: wlan_hdd_cfg80211_inform_bss
14130 * This function is used to inform the BSS details to nl80211 interface.
14131 */
14132static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
14133 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
14134{
14135 struct net_device *dev = pAdapter->dev;
14136 struct wireless_dev *wdev = dev->ieee80211_ptr;
14137 struct wiphy *wiphy = wdev->wiphy;
14138 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
14139 int chan_no;
14140 int ie_length;
14141 const char *ie;
14142 unsigned int freq;
14143 struct ieee80211_channel *chan;
14144 int rssi = 0;
14145 struct cfg80211_bss *bss = NULL;
14146
Jeff Johnson295189b2012-06-20 16:38:30 -070014147 if( NULL == pBssDesc )
14148 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014149 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014150 return bss;
14151 }
14152
14153 chan_no = pBssDesc->channelId;
14154 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
14155 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
14156
14157 if( NULL == ie )
14158 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014159 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014160 return bss;
14161 }
14162
14163#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
14164 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
14165 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014166 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014167 }
14168 else
14169 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014170 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014171 }
14172#else
14173 freq = ieee80211_channel_to_frequency(chan_no);
14174#endif
14175
14176 chan = __ieee80211_get_channel(wiphy, freq);
14177
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053014178 if (!chan) {
14179 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
14180 return NULL;
14181 }
14182
Abhishek Singhaee43942014-06-16 18:55:47 +053014183 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070014184
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014185 return cfg80211_inform_bss(wiphy, chan,
14186#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14187 CFG80211_BSS_FTYPE_UNKNOWN,
14188#endif
14189 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014190 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070014191 pBssDesc->capabilityInfo,
14192 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053014193 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070014194}
14195
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014196/*
14197 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
14198 * interface that BSS might have been lost.
14199 * @pAdapter: adaptor
14200 * @bssid: bssid which might have been lost
14201 *
14202 * Return: bss which is unlinked from kernel cache
14203 */
14204struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
14205 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
14206{
14207 struct net_device *dev = pAdapter->dev;
14208 struct wireless_dev *wdev = dev->ieee80211_ptr;
14209 struct wiphy *wiphy = wdev->wiphy;
14210 struct cfg80211_bss *bss = NULL;
14211
Abhishek Singh5a597e62016-12-05 15:16:30 +053014212 bss = hdd_get_bss_entry(wiphy,
14213 NULL, bssid,
14214 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014215 if (bss == NULL) {
14216 hddLog(LOGE, FL("BSS not present"));
14217 } else {
14218 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
14219 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
14220 cfg80211_unlink_bss(wiphy, bss);
14221 }
14222 return bss;
14223}
Jeff Johnson295189b2012-06-20 16:38:30 -070014224
14225
14226/*
14227 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
14228 * This function is used to inform the BSS details to nl80211 interface.
14229 */
14230struct cfg80211_bss*
14231wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
14232 tSirBssDescription *bss_desc
14233 )
14234{
14235 /*
14236 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
14237 already exists in bss data base of cfg80211 for that particular BSS ID.
14238 Using cfg80211_inform_bss_frame to update the bss entry instead of
14239 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
14240 now there is no possibility to get the mgmt(probe response) frame from PE,
14241 converting bss_desc to ieee80211_mgmt(probe response) and passing to
14242 cfg80211_inform_bss_frame.
14243 */
14244 struct net_device *dev = pAdapter->dev;
14245 struct wireless_dev *wdev = dev->ieee80211_ptr;
14246 struct wiphy *wiphy = wdev->wiphy;
14247 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014248#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14249 qcom_ie_age *qie_age = NULL;
14250 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
14251#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014252 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014253#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014254 const char *ie =
14255 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
14256 unsigned int freq;
14257 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014258 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014259 struct cfg80211_bss *bss_status = NULL;
14260 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
14261 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070014262 hdd_context_t *pHddCtx;
14263 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070014264#ifdef WLAN_OPEN_SOURCE
14265 struct timespec ts;
14266#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014267
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014268
Wilson Yangf80a0542013-10-07 13:02:37 -070014269 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14270 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070014271 if (0 != status)
14272 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014273 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014274 }
14275
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014276 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070014277 if (!mgmt)
14278 {
14279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14280 "%s: memory allocation failed ", __func__);
14281 return NULL;
14282 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014283
Jeff Johnson295189b2012-06-20 16:38:30 -070014284 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014285
14286#ifdef WLAN_OPEN_SOURCE
14287 /* Android does not want the timestamp from the frame.
14288 Instead it wants a monotonic increasing value */
14289 get_monotonic_boottime(&ts);
14290 mgmt->u.probe_resp.timestamp =
14291 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
14292#else
14293 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014294 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
14295 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070014296
14297#endif
14298
Jeff Johnson295189b2012-06-20 16:38:30 -070014299 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
14300 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014301
14302#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14303 /* GPS Requirement: need age ie per entry. Using vendor specific. */
14304 /* Assuming this is the last IE, copy at the end */
14305 ie_length -=sizeof(qcom_ie_age);
14306 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
14307 qie_age->element_id = QCOM_VENDOR_IE_ID;
14308 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
14309 qie_age->oui_1 = QCOM_OUI1;
14310 qie_age->oui_2 = QCOM_OUI2;
14311 qie_age->oui_3 = QCOM_OUI3;
14312 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053014313 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
14314 * bss related timestamp is in units of ms. Due to this when scan results
14315 * are sent to lowi the scan age is high.To address this, send age in units
14316 * of 1/10 ms.
14317 */
14318 qie_age->age = (vos_timer_get_system_time() -
14319 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014320#endif
14321
Jeff Johnson295189b2012-06-20 16:38:30 -070014322 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053014323 if (bss_desc->fProbeRsp)
14324 {
14325 mgmt->frame_control |=
14326 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
14327 }
14328 else
14329 {
14330 mgmt->frame_control |=
14331 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
14332 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014333
14334#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014335 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014336 (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014337 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014338 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014339 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014340 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014341 (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014342
14343 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014344 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014345 }
14346 else
14347 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014348 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
14349 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070014350 kfree(mgmt);
14351 return NULL;
14352 }
14353#else
14354 freq = ieee80211_channel_to_frequency(chan_no);
14355#endif
14356 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014357 /*when the band is changed on the fly using the GUI, three things are done
14358 * 1. scan abort 2.flush scan results from cache 3.update the band with the new band user specified(refer to the hdd_setBand_helper function)
14359 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
14360 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
14361 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
14362 * and discards the channels correponding to previous band and calls back with zero bss results.
14363 * but if the time between band update and scan done callback is very small then band change will not reflect in SME and SME reports to HDD
14364 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
14365 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
14366 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
14367 * So drop the bss and continue to next bss.
14368 */
14369 if(chan == NULL)
14370 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053014371 hddLog(VOS_TRACE_LEVEL_ERROR,
14372 FL("chan pointer is NULL, chan_no: %d freq: %d"),
14373 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070014374 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014375 return NULL;
14376 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053014377 /*To keep the rssi icon of the connected AP in the scan window
14378 *and the rssi icon of the wireless networks in sync
14379 * */
14380 if (( eConnectionState_Associated ==
14381 pAdapter->sessionCtx.station.conn_info.connState ) &&
14382 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
14383 pAdapter->sessionCtx.station.conn_info.bssId,
14384 WNI_CFG_BSSID_LEN)) &&
14385 (pHddCtx->hdd_wlan_suspended == FALSE))
14386 {
14387 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
14388 rssi = (pAdapter->rssi * 100);
14389 }
14390 else
14391 {
14392 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
14393 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014394
Nirav Shah20ac06f2013-12-12 18:14:06 +053014395 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053014396 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
14397 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053014398
Jeff Johnson295189b2012-06-20 16:38:30 -070014399 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
14400 frame_len, rssi, GFP_KERNEL);
14401 kfree(mgmt);
14402 return bss_status;
14403}
14404
14405/*
14406 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
14407 * This function is used to update the BSS data base of CFG8011
14408 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014409struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014410 tCsrRoamInfo *pRoamInfo
14411 )
14412{
14413 tCsrRoamConnectedProfile roamProfile;
14414 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14415 struct cfg80211_bss *bss = NULL;
14416
14417 ENTER();
14418
14419 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
14420 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
14421
14422 if (NULL != roamProfile.pBssDesc)
14423 {
Girish Gowlif4b68022014-08-28 23:18:57 +053014424 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14425 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070014426
14427 if (NULL == bss)
14428 {
14429 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
14430 __func__);
14431 }
14432
14433 sme_RoamFreeConnectProfile(hHal, &roamProfile);
14434 }
14435 else
14436 {
14437 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
14438 __func__);
14439 }
14440 return bss;
14441}
14442
14443/*
14444 * FUNCTION: wlan_hdd_cfg80211_update_bss
14445 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014446static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
14447 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070014448 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014449{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014450 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014451 tCsrScanResultInfo *pScanResult;
14452 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014453 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014454 tScanResultHandle pResult;
14455 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014456 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014457 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070014458 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014459
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014460 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14461 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
14462 NO_SESSION, pAdapter->sessionId));
14463
Wilson Yangf80a0542013-10-07 13:02:37 -070014464 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014465 ret = wlan_hdd_validate_context(pHddCtx);
14466 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070014467 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014468 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070014469 }
14470
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014471 if (pAdapter->request != NULL)
14472 {
14473 if ((pAdapter->request->n_ssids == 1)
14474 && (pAdapter->request->ssids != NULL)
14475 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
14476 is_p2p_scan = true;
14477 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014478 /*
14479 * start getting scan results and populate cgf80211 BSS database
14480 */
14481 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
14482
14483 /* no scan results */
14484 if (NULL == pResult)
14485 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014486 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
14487 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014488 wlan_hdd_get_frame_logs(pAdapter,
14489 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070014490 return status;
14491 }
14492
14493 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
14494
14495 while (pScanResult)
14496 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014497 /*
14498 * cfg80211_inform_bss() is not updating ie field of bss entry, if
14499 * entry already exists in bss data base of cfg80211 for that
14500 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
14501 * bss entry instead of cfg80211_inform_bss, But this call expects
14502 * mgmt packet as input. As of now there is no possibility to get
14503 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070014504 * ieee80211_mgmt(probe response) and passing to c
14505 * fg80211_inform_bss_frame.
14506 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014507 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
14508 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
14509 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014510 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14511 continue; //Skip the non p2p bss entries
14512 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014513 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14514 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014515
Jeff Johnson295189b2012-06-20 16:38:30 -070014516
14517 if (NULL == bss_status)
14518 {
14519 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014520 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014521 }
14522 else
14523 {
Yue Maf49ba872013-08-19 12:04:25 -070014524 cfg80211_put_bss(
14525#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
14526 wiphy,
14527#endif
14528 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070014529 }
14530
14531 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14532 }
14533
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014534 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014535 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014536 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014537}
14538
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014539void
14540hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
14541{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014542 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080014543 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014544} /****** end hddPrintMacAddr() ******/
14545
14546void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014547hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014548{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014549 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014550 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014551 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
14552 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
14553 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014554} /****** end hddPrintPmkId() ******/
14555
14556//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
14557//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
14558
14559//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
14560//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
14561
14562#define dump_bssid(bssid) \
14563 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014564 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
14565 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014566 }
14567
14568#define dump_pmkid(pMac, pmkid) \
14569 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014570 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
14571 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014572 }
14573
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070014574#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014575/*
14576 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
14577 * This function is used to notify the supplicant of a new PMKSA candidate.
14578 */
14579int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014580 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014581 int index, bool preauth )
14582{
Jeff Johnsone7245742012-09-05 17:12:55 -070014583#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014584 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014585 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014586
14587 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070014588 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014589
14590 if( NULL == pRoamInfo )
14591 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014592 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014593 return -EINVAL;
14594 }
14595
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014596 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
14597 {
14598 dump_bssid(pRoamInfo->bssid);
14599 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014600 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014601 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014602#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014603 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014604}
14605#endif //FEATURE_WLAN_LFR
14606
Yue Maef608272013-04-08 23:09:17 -070014607#ifdef FEATURE_WLAN_LFR_METRICS
14608/*
14609 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
14610 * 802.11r/LFR metrics reporting function to report preauth initiation
14611 *
14612 */
14613#define MAX_LFR_METRICS_EVENT_LENGTH 100
14614VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
14615 tCsrRoamInfo *pRoamInfo)
14616{
14617 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14618 union iwreq_data wrqu;
14619
14620 ENTER();
14621
14622 if (NULL == pAdapter)
14623 {
14624 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14625 return VOS_STATUS_E_FAILURE;
14626 }
14627
14628 /* create the event */
14629 memset(&wrqu, 0, sizeof(wrqu));
14630 memset(metrics_notification, 0, sizeof(metrics_notification));
14631
14632 wrqu.data.pointer = metrics_notification;
14633 wrqu.data.length = scnprintf(metrics_notification,
14634 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
14635 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14636
14637 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14638
14639 EXIT();
14640
14641 return VOS_STATUS_SUCCESS;
14642}
14643
14644/*
14645 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
14646 * 802.11r/LFR metrics reporting function to report preauth completion
14647 * or failure
14648 */
14649VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
14650 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
14651{
14652 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14653 union iwreq_data wrqu;
14654
14655 ENTER();
14656
14657 if (NULL == pAdapter)
14658 {
14659 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14660 return VOS_STATUS_E_FAILURE;
14661 }
14662
14663 /* create the event */
14664 memset(&wrqu, 0, sizeof(wrqu));
14665 memset(metrics_notification, 0, sizeof(metrics_notification));
14666
14667 scnprintf(metrics_notification, sizeof(metrics_notification),
14668 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
14669 MAC_ADDR_ARRAY(pRoamInfo->bssid));
14670
14671 if (1 == preauth_status)
14672 strncat(metrics_notification, " TRUE", 5);
14673 else
14674 strncat(metrics_notification, " FALSE", 6);
14675
14676 wrqu.data.pointer = metrics_notification;
14677 wrqu.data.length = strlen(metrics_notification);
14678
14679 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14680
14681 EXIT();
14682
14683 return VOS_STATUS_SUCCESS;
14684}
14685
14686/*
14687 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
14688 * 802.11r/LFR metrics reporting function to report handover initiation
14689 *
14690 */
14691VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
14692 tCsrRoamInfo *pRoamInfo)
14693{
14694 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14695 union iwreq_data wrqu;
14696
14697 ENTER();
14698
14699 if (NULL == pAdapter)
14700 {
14701 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14702 return VOS_STATUS_E_FAILURE;
14703 }
14704
14705 /* create the event */
14706 memset(&wrqu, 0, sizeof(wrqu));
14707 memset(metrics_notification, 0, sizeof(metrics_notification));
14708
14709 wrqu.data.pointer = metrics_notification;
14710 wrqu.data.length = scnprintf(metrics_notification,
14711 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14712 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14713
14714 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14715
14716 EXIT();
14717
14718 return VOS_STATUS_SUCCESS;
14719}
14720#endif
14721
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014722
14723/**
14724 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14725 * @scan_req: scan request to be checked
14726 *
14727 * Return: true or false
14728 */
14729#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14730static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14731 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014732 *scan_req, hdd_context_t
14733 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014734{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014735 if (!scan_req || !scan_req->wiphy ||
14736 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014737 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14738 return false;
14739 }
14740 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14741 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14742 return false;
14743 }
14744 return true;
14745}
14746#else
14747static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14748 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014749 *scan_req, hdd_context_t
14750 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014751{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014752 if (!scan_req || !scan_req->wiphy ||
14753 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014754 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14755 return false;
14756 }
14757 return true;
14758}
14759#endif
14760
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014761#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
14762/**
14763 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14764 * @adapter: Pointer to the adapter
14765 * @req : Scan request
14766 * @aborted : true scan aborted false scan success
14767 *
14768 * This function notifies scan done to cfg80211
14769 *
14770 * Return: none
14771 */
14772static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14773 struct cfg80211_scan_request *req,
14774 bool aborted)
14775{
14776 struct cfg80211_scan_info info = {
14777 .aborted = aborted
14778 };
14779
14780 if (adapter->dev->flags & IFF_UP)
14781 cfg80211_scan_done(req, &info);
14782 else
14783 hddLog(LOGW,
14784 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14785}
14786#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14787/**
14788 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14789 * @adapter: Pointer to the adapter
14790 * @req : Scan request
14791 * @aborted : true scan aborted false scan success
14792 *
14793 * This function notifies scan done to cfg80211
14794 *
14795 * Return: none
14796 */
14797static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14798 struct cfg80211_scan_request *req,
14799 bool aborted)
14800{
14801 if (adapter->dev->flags & IFF_UP)
14802 cfg80211_scan_done(req, aborted);
14803 else
14804 hddLog(LOGW,
14805 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14806}
14807#else
14808/**
14809 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14810 * @adapter: Pointer to the adapter
14811 * @req : Scan request
14812 * @aborted : true scan aborted false scan success
14813 *
14814 * This function notifies scan done to cfg80211
14815 *
14816 * Return: none
14817 */
14818static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14819 struct cfg80211_scan_request *req,
14820 bool aborted)
14821{
14822 cfg80211_scan_done(req, aborted);
14823}
14824#endif
14825
Mukul Sharmab392b642017-08-17 17:45:29 +053014826#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014827/*
14828 * FUNCTION: hdd_cfg80211_scan_done_callback
14829 * scanning callback function, called after finishing scan
14830 *
14831 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014832static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014833 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14834{
14835 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014836 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014837 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014838 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014839 struct cfg80211_scan_request *req = NULL;
14840 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014841 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014842 long waitRet = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014843 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014844
14845 ENTER();
14846
c_manjee1b4ab9a2016-10-26 11:36:55 +053014847 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14848 !pAdapter->dev) {
14849 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14850 return 0;
14851 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014852 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014853 if (NULL == pHddCtx) {
14854 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014855 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014856 }
14857
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014858#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014859 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014860 {
14861 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014862 }
14863#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014864 pScanInfo = &pHddCtx->scan_info;
14865
Jeff Johnson295189b2012-06-20 16:38:30 -070014866 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014867 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014868 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014869 __func__, halHandle, pContext, (int) scanId, (int) status);
14870
Kiet Lamac06e2c2013-10-23 16:25:07 +053014871 pScanInfo->mScanPendingCounter = 0;
14872
Jeff Johnson295189b2012-06-20 16:38:30 -070014873 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014874 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014875 &pScanInfo->scan_req_completion_event,
14876 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014877 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014878 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014879 hddLog(VOS_TRACE_LEVEL_ERROR,
14880 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014881 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014882 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014883 }
14884
Yue Maef608272013-04-08 23:09:17 -070014885 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014886 {
14887 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014888 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014889 }
14890
14891 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014892 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014893 {
14894 hddLog(VOS_TRACE_LEVEL_INFO,
14895 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014896 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014897 (int) scanId);
14898 }
14899
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014900#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014901 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014902#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014903 {
14904 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14905 pAdapter);
14906 if (0 > ret)
14907 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014908 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014909
Jeff Johnson295189b2012-06-20 16:38:30 -070014910 /* If any client wait scan result through WEXT
14911 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014912 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014913 {
14914 /* The other scan request waiting for current scan finish
14915 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014916 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014917 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014918 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014919 }
14920 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014921 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014922 {
14923 struct net_device *dev = pAdapter->dev;
14924 union iwreq_data wrqu;
14925 int we_event;
14926 char *msg;
14927
14928 memset(&wrqu, '\0', sizeof(wrqu));
14929 we_event = SIOCGIWSCAN;
14930 msg = NULL;
14931 wireless_send_event(dev, we_event, &wrqu, msg);
14932 }
14933 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014934 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014935
14936 /* Get the Scan Req */
14937 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014938 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014939
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014940 /* Scan is no longer pending */
14941 pScanInfo->mScanPending = VOS_FALSE;
14942
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014943 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070014944 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014945#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
14946 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053014947 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014948#endif
14949
14950 if (pAdapter->dev) {
14951 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
14952 pAdapter->dev->name);
14953 }
mukul sharmae7041822015-12-03 15:09:21 +053014954 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070014955 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014956 }
14957
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014958 /* last_scan_timestamp is used to decide if new scan
14959 * is needed or not on station interface. If last station
14960 * scan time and new station scan time is less then
14961 * last_scan_timestamp ; driver will return cached scan.
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014962 * Also only last_scan_timestamp is updated here last_scan_channellist
14963 * is updated on receiving scan request itself to make sure kernel
14964 * allocated scan request(scan_req) object is not dereferenced here,
14965 * because interface down, where kernel frees scan_req, may happen any
14966 * time while driver is processing scan_done_callback. So it's better
14967 * not to access scan_req in this routine.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014968 */
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014969 if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
14970 if (status == eCSR_SCAN_SUCCESS)
14971 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
14972 else {
14973 vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
14974 sizeof(pHddCtx->scan_info.last_scan_channelList));
14975 pHddCtx->scan_info.last_scan_numChannels = 0;
14976 pScanInfo->last_scan_timestamp = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014977 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014978 }
14979
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070014980 /*
14981 * cfg80211_scan_done informing NL80211 about completion
14982 * of scanning
14983 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014984 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
14985 {
14986 aborted = true;
14987 }
mukul sharmae7041822015-12-03 15:09:21 +053014988
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014989#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014990 if (NET_DEV_IS_IFF_UP(pAdapter) &&
14991 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014992#endif
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014993 hdd_cfg80211_scan_done(pAdapter, req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053014994
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080014995 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070014996
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014997allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014998 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
14999 ) && (pHddCtx->spoofMacAddr.isEnabled
15000 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053015001 /* Generate new random mac addr for next scan */
15002 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053015003
15004 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
15005 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053015006 }
15007
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015008 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015009 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015010
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015011 /* Acquire wakelock to handle the case where APP's tries to suspend
15012 * immediatly after the driver gets connect request(i.e after scan)
15013 * from supplicant, this result in app's is suspending and not able
15014 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015015 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015016
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015017#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015018 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015019#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015020#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015021 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015022#endif
15023
Jeff Johnson295189b2012-06-20 16:38:30 -070015024 EXIT();
15025 return 0;
15026}
15027
15028/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053015029 * FUNCTION: hdd_isConnectionInProgress
15030 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015031 *
15032 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015033v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
15034 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015035{
15036 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15037 hdd_station_ctx_t *pHddStaCtx = NULL;
15038 hdd_adapter_t *pAdapter = NULL;
15039 VOS_STATUS status = 0;
15040 v_U8_t staId = 0;
15041 v_U8_t *staMac = NULL;
15042
15043 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15044
15045 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15046 {
15047 pAdapter = pAdapterNode->pAdapter;
15048
15049 if( pAdapter )
15050 {
15051 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015052 "%s: Adapter with device mode %s (%d) exists",
15053 __func__, hdd_device_modetoString(pAdapter->device_mode),
15054 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015055 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053015056 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15057 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
15058 (eConnectionState_Connecting ==
15059 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
15060 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015061 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015062 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053015063 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015064 if (session_id && reason)
15065 {
15066 *session_id = pAdapter->sessionId;
15067 *reason = eHDD_CONNECTION_IN_PROGRESS;
15068 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015069 return VOS_TRUE;
15070 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015071 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053015072 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015073 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015074 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015075 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015076 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015077 if (session_id && reason)
15078 {
15079 *session_id = pAdapter->sessionId;
15080 *reason = eHDD_REASSOC_IN_PROGRESS;
15081 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015082 return VOS_TRUE;
15083 }
15084 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015085 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15086 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015087 {
15088 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15089 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015090 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015091 {
15092 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015093 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015094 "%s: client " MAC_ADDRESS_STR
15095 " is in the middle of WPS/EAPOL exchange.", __func__,
15096 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015097 if (session_id && reason)
15098 {
15099 *session_id = pAdapter->sessionId;
15100 *reason = eHDD_EAPOL_IN_PROGRESS;
15101 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015102 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015103 }
15104 }
15105 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
15106 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
15107 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015108 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15109 ptSapContext pSapCtx = NULL;
15110 pSapCtx = VOS_GET_SAP_CB(pVosContext);
15111 if(pSapCtx == NULL){
15112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15113 FL("psapCtx is NULL"));
15114 return VOS_FALSE;
15115 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015116 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
15117 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015118 if ((pSapCtx->aStaInfo[staId].isUsed) &&
15119 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015120 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015121 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015122
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015123 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015124 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
15125 "middle of WPS/EAPOL exchange.", __func__,
15126 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015127 if (session_id && reason)
15128 {
15129 *session_id = pAdapter->sessionId;
15130 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
15131 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015132 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015133 }
15134 }
15135 }
15136 }
15137 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15138 pAdapterNode = pNext;
15139 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015140 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015141}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015142
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015143/**
15144 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
15145 * to the Scan request
15146 * @scanRequest: Pointer to the csr scan request
15147 * @request: Pointer to the scan request from supplicant
15148 *
15149 * Return: None
15150 */
15151#ifdef CFG80211_SCAN_BSSID
15152static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15153 struct cfg80211_scan_request *request)
15154{
15155 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
15156}
15157#else
15158static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15159 struct cfg80211_scan_request *request)
15160{
15161}
15162#endif
15163
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015164/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015165 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070015166 * this scan respond to scan trigger and update cfg80211 scan database
15167 * later, scan dump command can be used to recieve scan results
15168 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015169int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015170#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15171 struct net_device *dev,
15172#endif
15173 struct cfg80211_scan_request *request)
15174{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015175 hdd_adapter_t *pAdapter = NULL;
15176 hdd_context_t *pHddCtx = NULL;
15177 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015178 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015179 tCsrScanRequest scanRequest;
15180 tANI_U8 *channelList = NULL, i;
15181 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015182 int status;
15183 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015184 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015185 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053015186 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015187 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015188 v_U8_t curr_session_id;
15189 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070015190
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015191#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
15192 struct net_device *dev = NULL;
15193 if (NULL == request)
15194 {
15195 hddLog(VOS_TRACE_LEVEL_ERROR,
15196 "%s: scan req param null", __func__);
15197 return -EINVAL;
15198 }
15199 dev = request->wdev->netdev;
15200#endif
15201
15202 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15203 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
15204 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15205
Jeff Johnson295189b2012-06-20 16:38:30 -070015206 ENTER();
15207
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015208 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
15209 __func__, hdd_device_modetoString(pAdapter->device_mode),
15210 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015211
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015212 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015213 if (0 != status)
15214 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015215 return status;
15216 }
15217
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015218 if (NULL == pwextBuf)
15219 {
15220 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
15221 __func__);
15222 return -EIO;
15223 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015224 cfg_param = pHddCtx->cfg_ini;
15225 pScanInfo = &pHddCtx->scan_info;
15226
Jeff Johnson295189b2012-06-20 16:38:30 -070015227#ifdef WLAN_BTAMP_FEATURE
15228 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015229 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070015230 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015231 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015232 "%s: No scanning when AMP is on", __func__);
15233 return -EOPNOTSUPP;
15234 }
15235#endif
15236 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015237 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070015238 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015239 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015240 "%s: Not scanning on device_mode = %s (%d)",
15241 __func__, hdd_device_modetoString(pAdapter->device_mode),
15242 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015243 return -EOPNOTSUPP;
15244 }
15245
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015246 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
15247 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
15248 return -EOPNOTSUPP;
15249 }
15250
Jeff Johnson295189b2012-06-20 16:38:30 -070015251 if (TRUE == pScanInfo->mScanPending)
15252 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015253 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
15254 {
15255 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
15256 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015257 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015258 }
15259
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053015260 // Don't allow scan if PNO scan is going on.
15261 if (pHddCtx->isPnoEnable)
15262 {
15263 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15264 FL("pno scan in progress"));
15265 return -EBUSY;
15266 }
15267
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015268 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070015269 //Channel and action frame is pending
15270 //Otherwise Cancel Remain On Channel and allow Scan
15271 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015272 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070015273 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015274 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070015275 return -EBUSY;
15276 }
15277
Jeff Johnson295189b2012-06-20 16:38:30 -070015278 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
15279 {
15280 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080015281 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015282 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015283 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015284 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
15285 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015286 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015287 "%s: MAX TM Level Scan not allowed", __func__);
15288 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015289 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015290 }
15291 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
15292
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015293 /* Check if scan is allowed at this point of time.
15294 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053015295 if (TRUE == pHddCtx->btCoexModeSet)
15296 {
15297 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15298 FL("BTCoex Mode operation in progress"));
15299 return -EBUSY;
15300 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015301 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015302 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015303
15304 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
15305 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
15306 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015307 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
15308 pHddCtx->last_scan_reject_reason != curr_reason ||
15309 !pHddCtx->last_scan_reject_timestamp)
15310 {
15311 pHddCtx->last_scan_reject_session_id = curr_session_id;
15312 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053015313 pHddCtx->last_scan_reject_timestamp =
15314 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015315 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053015316 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053015317 else
15318 {
15319 pHddCtx->scan_reject_cnt++;
15320
Abhishek Singhe4b12562017-06-20 16:53:39 +053015321 if ((pHddCtx->scan_reject_cnt >=
15322 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053015323 vos_system_time_after(jiffies_to_msecs(jiffies),
15324 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015325 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015326 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
15327 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
15328 vos_system_time_after(jiffies_to_msecs(jiffies),
15329 pHddCtx->last_scan_reject_timestamp));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015330 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015331 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015332 if (pHddCtx->cfg_ini->enableFatalEvent)
15333 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
15334 WLAN_LOG_INDICATOR_HOST_DRIVER,
15335 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
15336 FALSE, FALSE);
15337 else
15338 {
15339 hddLog(LOGE, FL("Triggering SSR"));
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +053015340 vos_wlanRestart(VOS_SCAN_REQ_EXPIRED);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015341 }
15342 }
15343 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015344 return -EBUSY;
15345 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015346 pHddCtx->last_scan_reject_timestamp = 0;
15347 pHddCtx->last_scan_reject_session_id = 0xFF;
15348 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015349 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015350
Jeff Johnson295189b2012-06-20 16:38:30 -070015351 vos_mem_zero( &scanRequest, sizeof(scanRequest));
15352
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015353 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
15354 * Becasue of this, driver is assuming that this is not wildcard scan and so
15355 * is not aging out the scan results.
15356 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053015357 if ((request->ssids) && (request->n_ssids == 1) &&
15358 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015359 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015360 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015361
15362 if ((request->ssids) && (0 < request->n_ssids))
15363 {
15364 tCsrSSIDInfo *SsidInfo;
15365 int j;
15366 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
15367 /* Allocate num_ssid tCsrSSIDInfo structure */
15368 SsidInfo = scanRequest.SSIDs.SSIDList =
15369 ( tCsrSSIDInfo *)vos_mem_malloc(
15370 request->n_ssids*sizeof(tCsrSSIDInfo));
15371
15372 if(NULL == scanRequest.SSIDs.SSIDList)
15373 {
15374 hddLog(VOS_TRACE_LEVEL_ERROR,
15375 "%s: memory alloc failed SSIDInfo buffer", __func__);
15376 return -ENOMEM;
15377 }
15378
15379 /* copy all the ssid's and their length */
15380 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
15381 {
15382 /* get the ssid length */
15383 SsidInfo->SSID.length = request->ssids[j].ssid_len;
15384 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
15385 SsidInfo->SSID.length);
15386 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
15387 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
15388 j, SsidInfo->SSID.ssId);
15389 }
15390 /* set the scan type to active */
15391 scanRequest.scanType = eSIR_ACTIVE_SCAN;
15392 }
15393 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015394 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015395 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15396 TRACE_CODE_HDD_CFG80211_SCAN,
15397 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070015398 /* set the scan type to active */
15399 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070015400 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015401 else
15402 {
15403 /*Set the scan type to default type, in this case it is ACTIVE*/
15404 scanRequest.scanType = pScanInfo->scan_mode;
15405 }
15406 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
15407 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070015408
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015409 csr_scan_request_assign_bssid(&scanRequest, request);
15410
Jeff Johnson295189b2012-06-20 16:38:30 -070015411 /* set BSSType to default type */
15412 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
15413
15414 /*TODO: scan the requested channels only*/
15415
15416 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015417 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070015418 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015419 hddLog(VOS_TRACE_LEVEL_WARN,
15420 "No of Scan Channels exceeded limit: %d", request->n_channels);
15421 request->n_channels = MAX_CHANNEL;
15422 }
15423
15424 hddLog(VOS_TRACE_LEVEL_INFO,
15425 "No of Scan Channels: %d", request->n_channels);
15426
15427
15428 if( request->n_channels )
15429 {
15430 char chList [(request->n_channels*5)+1];
15431 int len;
15432 channelList = vos_mem_malloc( request->n_channels );
15433 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053015434 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015435 hddLog(VOS_TRACE_LEVEL_ERROR,
15436 "%s: memory alloc failed channelList", __func__);
15437 status = -ENOMEM;
15438 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053015439 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015440
15441 for( i = 0, len = 0; i < request->n_channels ; i++ )
15442 {
15443 channelList[i] = request->channels[i]->hw_value;
15444 len += snprintf(chList+len, 5, "%d ", channelList[i]);
15445 }
15446
Nirav Shah20ac06f2013-12-12 18:14:06 +053015447 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015448 "Channel-List: %s ", chList);
15449 }
c_hpothu53512302014-04-15 18:49:53 +053015450
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015451 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
15452 scanRequest.ChannelInfo.ChannelList = channelList;
15453
15454 /* set requestType to full scan */
15455 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
15456
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015457 /* if there is back to back scan happening in driver with in
15458 * nDeferScanTimeInterval interval driver should defer new scan request
15459 * and should provide last cached scan results instead of new channel list.
15460 * This rule is not applicable if scan is p2p scan.
15461 * This condition will work only in case when last request no of channels
15462 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053015463 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053015464 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015465 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015466
Sushant Kaushik86592172015-04-27 16:35:03 +053015467 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
15468 /* if wps ie is NULL , then only defer scan */
15469 if ( pWpsIe == NULL &&
15470 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053015471 {
15472 if ( pScanInfo->last_scan_timestamp !=0 &&
15473 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
15474 {
15475 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
15476 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
15477 vos_mem_compare(pScanInfo->last_scan_channelList,
15478 channelList, pScanInfo->last_scan_numChannels))
15479 {
15480 hddLog(VOS_TRACE_LEVEL_WARN,
15481 " New and old station scan time differ is less then %u",
15482 pHddCtx->cfg_ini->nDeferScanTimeInterval);
15483
15484 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015485 pAdapter);
15486
Agarwal Ashish57e84372014-12-05 18:26:53 +053015487 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015488 "Return old cached scan as all channels and no of channels are same");
15489
Agarwal Ashish57e84372014-12-05 18:26:53 +053015490 if (0 > ret)
15491 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015492
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015493 hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015494
15495 status = eHAL_STATUS_SUCCESS;
15496 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053015497 }
15498 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015499 }
15500
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015501 /* Flush the scan results(only p2p beacons) for STA scan and P2P
15502 * search (Flush on both full scan and social scan but not on single
15503 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
15504 */
15505
15506 /* Supplicant does single channel scan after 8-way handshake
15507 * and in that case driver shoudnt flush scan results. If
15508 * driver flushes the scan results here and unfortunately if
15509 * the AP doesnt respond to our probe req then association
15510 * fails which is not desired
15511 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015512 if ((request->n_ssids == 1)
15513 && (request->ssids != NULL)
15514 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
15515 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015516
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015517 if( is_p2p_scan ||
15518 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015519 {
15520 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
15521 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
15522 pAdapter->sessionId );
15523 }
15524
15525 if( request->ie_len )
15526 {
15527 /* save this for future association (join requires this) */
15528 /*TODO: Array needs to be converted to dynamic allocation,
15529 * as multiple ie.s can be sent in cfg80211_scan_request structure
15530 * CR 597966
15531 */
15532 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
15533 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
15534 pScanInfo->scanAddIE.length = request->ie_len;
15535
15536 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15537 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15538 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015539 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015540 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070015541 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015542 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
15543 memcpy( pwextBuf->roamProfile.addIEScan,
15544 request->ie, request->ie_len);
15545 }
15546 else
15547 {
15548 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
15549 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070015550 }
15551
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015552 }
15553 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
15554 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
15555
15556 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
15557 request->ie_len);
15558 if (pP2pIe != NULL)
15559 {
15560#ifdef WLAN_FEATURE_P2P_DEBUG
15561 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
15562 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
15563 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053015564 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015565 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
15566 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15567 "Go nego completed to Connection is started");
15568 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15569 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053015570 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015571 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
15572 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015573 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015574 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
15575 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15576 "Disconnected state to Connection is started");
15577 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15578 "for 4way Handshake");
15579 }
15580#endif
15581
15582 /* no_cck will be set during p2p find to disable 11b rates */
15583 if(TRUE == request->no_cck)
15584 {
15585 hddLog(VOS_TRACE_LEVEL_INFO,
15586 "%s: This is a P2P Search", __func__);
15587 scanRequest.p2pSearch = 1;
15588
15589 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053015590 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015591 /* set requestType to P2P Discovery */
15592 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
15593 }
15594
15595 /*
15596 Skip Dfs Channel in case of P2P Search
15597 if it is set in ini file
15598 */
15599 if(cfg_param->skipDfsChnlInP2pSearch)
15600 {
15601 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015602 }
15603 else
15604 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015605 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015606 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015607
Agarwal Ashish4f616132013-12-30 23:32:50 +053015608 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015609 }
15610 }
15611
15612 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
15613
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015614#ifdef FEATURE_WLAN_TDLS
15615 /* if tdls disagree scan right now, return immediately.
15616 tdls will schedule the scan when scan is allowed. (return SUCCESS)
15617 or will reject the scan if any TDLS is in progress. (return -EBUSY)
15618 */
15619 status = wlan_hdd_tdls_scan_callback (pAdapter,
15620 wiphy,
15621#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15622 dev,
15623#endif
15624 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015625 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015626 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053015627 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015628 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
15629 "scan rejected %d", __func__, status);
15630 else
15631 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
15632 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015633 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053015634 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015635 }
15636#endif
15637
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015638 /* acquire the wakelock to avoid the apps suspend during the scan. To
15639 * address the following issues.
15640 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
15641 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
15642 * for long time, this result in apps running at full power for long time.
15643 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
15644 * be stuck in full power because of resume BMPS
15645 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015646 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015647
Nirav Shah20ac06f2013-12-12 18:14:06 +053015648 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
15649 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015650 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
15651 scanRequest.requestType, scanRequest.scanType,
15652 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053015653 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
15654
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015655 if (pHddCtx->spoofMacAddr.isEnabled &&
15656 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053015657 {
15658 hddLog(VOS_TRACE_LEVEL_INFO,
15659 "%s: MAC Spoofing enabled for current scan", __func__);
15660 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15661 * to fill TxBds for probe request during current scan
15662 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015663 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053015664 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015665
15666 if(status != VOS_STATUS_SUCCESS)
15667 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015668 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015669 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053015670#ifdef FEATURE_WLAN_TDLS
15671 wlan_hdd_tdls_scan_done_callback(pAdapter);
15672#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015673 goto free_mem;
15674 }
Siddharth Bhal76972212014-10-15 16:22:51 +053015675 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053015676 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070015677 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015678 pAdapter->sessionId, &scanRequest, &scanId,
15679 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070015680
Jeff Johnson295189b2012-06-20 16:38:30 -070015681 if (eHAL_STATUS_SUCCESS != status)
15682 {
15683 hddLog(VOS_TRACE_LEVEL_ERROR,
15684 "%s: sme_ScanRequest returned error %d", __func__, status);
15685 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015686 if(eHAL_STATUS_RESOURCES == status)
15687 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015688 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
15689 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015690 status = -EBUSY;
15691 } else {
15692 status = -EIO;
15693 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015694 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015695
15696#ifdef FEATURE_WLAN_TDLS
15697 wlan_hdd_tdls_scan_done_callback(pAdapter);
15698#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015699 goto free_mem;
15700 }
15701
15702 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015703 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070015704 pAdapter->request = request;
15705 pScanInfo->scanId = scanId;
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015706 pScanInfo->no_cck = request->no_cck;
15707 pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
15708 for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
15709 pHddCtx->scan_info.last_scan_channelList[i] =
15710 request->channels[i]->hw_value;
15711 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015712
15713 complete(&pScanInfo->scan_req_completion_event);
15714
15715free_mem:
15716 if( scanRequest.SSIDs.SSIDList )
15717 {
15718 vos_mem_free(scanRequest.SSIDs.SSIDList);
15719 }
15720
15721 if( channelList )
15722 vos_mem_free( channelList );
15723
15724 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015725 return status;
15726}
15727
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015728int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
15729#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15730 struct net_device *dev,
15731#endif
15732 struct cfg80211_scan_request *request)
15733{
15734 int ret;
15735
15736 vos_ssr_protect(__func__);
15737 ret = __wlan_hdd_cfg80211_scan(wiphy,
15738#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15739 dev,
15740#endif
15741 request);
15742 vos_ssr_unprotect(__func__);
15743
15744 return ret;
15745}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015746
15747void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
15748{
15749 v_U8_t iniDot11Mode =
15750 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
15751 eHddDot11Mode hddDot11Mode = iniDot11Mode;
15752
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015753 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
15754 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015755 switch ( iniDot11Mode )
15756 {
15757 case eHDD_DOT11_MODE_AUTO:
15758 case eHDD_DOT11_MODE_11ac:
15759 case eHDD_DOT11_MODE_11ac_ONLY:
15760#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053015761 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
15762 sme_IsFeatureSupportedByFW(DOT11AC) )
15763 hddDot11Mode = eHDD_DOT11_MODE_11ac;
15764 else
15765 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015766#else
15767 hddDot11Mode = eHDD_DOT11_MODE_11n;
15768#endif
15769 break;
15770 case eHDD_DOT11_MODE_11n:
15771 case eHDD_DOT11_MODE_11n_ONLY:
15772 hddDot11Mode = eHDD_DOT11_MODE_11n;
15773 break;
15774 default:
15775 hddDot11Mode = iniDot11Mode;
15776 break;
15777 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015778#ifdef WLAN_FEATURE_AP_HT40_24G
15779 if (operationChannel > SIR_11B_CHANNEL_END)
15780#endif
15781 {
15782 /* This call decides required channel bonding mode */
15783 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015784 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053015785 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015786 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015787}
15788
Jeff Johnson295189b2012-06-20 16:38:30 -070015789/*
15790 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015791 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015792 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015793int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053015794 const u8 *ssid, size_t ssid_len, const u8 *bssid,
15795 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070015796{
15797 int status = 0;
15798 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080015799 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015800 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015801 v_U32_t roamId;
15802 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070015803 eCsrAuthType RSNAuthType;
15804
15805 ENTER();
15806
15807 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015808 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015809 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015810
15811 status = wlan_hdd_validate_context(pHddCtx);
15812 if (status)
15813 {
Yue Mae36e3552014-03-05 17:06:20 -080015814 return status;
15815 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015816
Jeff Johnson295189b2012-06-20 16:38:30 -070015817 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
15818 {
15819 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
15820 return -EINVAL;
15821 }
15822
Nitesh Shah9b066282017-06-06 18:05:52 +053015823
Jeff Johnson295189b2012-06-20 16:38:30 -070015824 pRoamProfile = &pWextState->roamProfile;
15825
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015826 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070015827 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015828 hdd_station_ctx_t *pHddStaCtx;
15829 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053015830 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015831
Siddharth Bhalda0d1622015-04-24 15:47:49 +053015832 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
15833
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015834 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070015835 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
15836 {
15837 /*QoS not enabled in cfg file*/
15838 pRoamProfile->uapsd_mask = 0;
15839 }
15840 else
15841 {
15842 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015843 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070015844 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
15845 }
15846
15847 pRoamProfile->SSIDs.numOfSSIDs = 1;
15848 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
15849 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015850 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070015851 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
15852 ssid, ssid_len);
15853
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015854 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
15855 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
15856
Jeff Johnson295189b2012-06-20 16:38:30 -070015857 if (bssid)
15858 {
15859 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015860 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015861 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015862 /* Save BSSID in seperate variable as well, as RoamProfile
15863 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070015864 case of join failure we should send valid BSSID to supplicant
15865 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015866 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015867 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015868
Jeff Johnson295189b2012-06-20 16:38:30 -070015869 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015870 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070015871 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015872 /* Store bssid_hint to use in the scan filter. */
15873 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15874 WNI_CFG_BSSID_LEN);
15875 /*
15876 * Save BSSID in seperate variable as well, as RoamProfile
15877 * BSSID is getting zeroed out in the association process. And in
15878 * case of join failure we should send valid BSSID to supplicant
15879 */
15880 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15881 WNI_CFG_BSSID_LEN);
15882 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15883 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015884 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015885
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015886
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015887 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15888 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015889 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15890 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015891 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015892 /*set gen ie*/
15893 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15894 /*set auth*/
15895 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15896 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015897#ifdef FEATURE_WLAN_WAPI
15898 if (pAdapter->wapi_info.nWapiMode)
15899 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015900 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015901 switch (pAdapter->wapi_info.wapiAuthMode)
15902 {
15903 case WAPI_AUTH_MODE_PSK:
15904 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015905 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015906 pAdapter->wapi_info.wapiAuthMode);
15907 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15908 break;
15909 }
15910 case WAPI_AUTH_MODE_CERT:
15911 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015912 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015913 pAdapter->wapi_info.wapiAuthMode);
15914 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15915 break;
15916 }
15917 } // End of switch
15918 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15919 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15920 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015921 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015922 pRoamProfile->AuthType.numEntries = 1;
15923 pRoamProfile->EncryptionType.numEntries = 1;
15924 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15925 pRoamProfile->mcEncryptionType.numEntries = 1;
15926 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15927 }
15928 }
15929#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015930#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015931 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015932 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15933 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
15934 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015935 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
15936 sizeof (tSirGtkOffloadParams));
15937 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015938 }
15939#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015940 pRoamProfile->csrPersona = pAdapter->device_mode;
15941
Jeff Johnson32d95a32012-09-10 13:15:23 -070015942 if( operatingChannel )
15943 {
15944 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
15945 pRoamProfile->ChannelInfo.numOfChannels = 1;
15946 }
Chet Lanctot186b5732013-03-18 10:26:30 -070015947 else
15948 {
15949 pRoamProfile->ChannelInfo.ChannelList = NULL;
15950 pRoamProfile->ChannelInfo.numOfChannels = 0;
15951 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015952 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
15953 {
15954 hdd_select_cbmode(pAdapter,operatingChannel);
15955 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015956
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015957 /*
15958 * Change conn_state to connecting before sme_RoamConnect(),
15959 * because sme_RoamConnect() has a direct path to call
15960 * hdd_smeRoamCallback(), which will change the conn_state
15961 * If direct path, conn_state will be accordingly changed
15962 * to NotConnected or Associated by either
15963 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
15964 * in sme_RoamCallback()
15965 * if sme_RomConnect is to be queued,
15966 * Connecting state will remain until it is completed.
15967 * If connection state is not changed,
15968 * connection state will remain in eConnectionState_NotConnected state.
15969 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
15970 * if conn state is eConnectionState_NotConnected.
15971 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
15972 * informed of connect result indication which is an issue.
15973 */
15974
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015975 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15976 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053015977 {
15978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015979 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015980 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
15981 eConnectionState_Connecting);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053015982 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
15983 hdd_wait_for_ecsa_complete(pHddCtx);
Abhishek Singhf4669da2014-05-26 15:07:49 +053015984 }
Abhishek Singh10e17cf2018-03-12 14:34:22 +053015985
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015986 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015987 pAdapter->sessionId, pRoamProfile, &roamId);
15988
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015989 if ((eHAL_STATUS_SUCCESS != status) &&
15990 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15991 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015992
15993 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015994 hddLog(VOS_TRACE_LEVEL_ERROR,
15995 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
15996 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015997 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015998 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015999 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016000 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016001
16002 pRoamProfile->ChannelInfo.ChannelList = NULL;
16003 pRoamProfile->ChannelInfo.numOfChannels = 0;
16004
Jeff Johnson295189b2012-06-20 16:38:30 -070016005 }
16006 else
16007 {
16008 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
16009 return -EINVAL;
16010 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080016011 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016012 return status;
16013}
16014
16015/*
16016 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
16017 * This function is used to set the authentication type (OPEN/SHARED).
16018 *
16019 */
16020static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
16021 enum nl80211_auth_type auth_type)
16022{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016023 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016024 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16025
16026 ENTER();
16027
16028 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016029 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070016030 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016031 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016032 hddLog(VOS_TRACE_LEVEL_INFO,
16033 "%s: set authentication type to AUTOSWITCH", __func__);
16034 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
16035 break;
16036
16037 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016038#ifdef WLAN_FEATURE_VOWIFI_11R
16039 case NL80211_AUTHTYPE_FT:
16040#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016041 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016042 "%s: set authentication type to OPEN", __func__);
16043 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
16044 break;
16045
16046 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016047 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016048 "%s: set authentication type to SHARED", __func__);
16049 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
16050 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016051#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016052 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016053 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016054 "%s: set authentication type to CCKM WPA", __func__);
16055 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
16056 break;
16057#endif
16058
16059
16060 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016061 hddLog(VOS_TRACE_LEVEL_ERROR,
16062 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016063 auth_type);
16064 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
16065 return -EINVAL;
16066 }
16067
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016068 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016069 pHddStaCtx->conn_info.authType;
16070 return 0;
16071}
16072
16073/*
16074 * FUNCTION: wlan_hdd_set_akm_suite
16075 * This function is used to set the key mgmt type(PSK/8021x).
16076 *
16077 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016078static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016079 u32 key_mgmt
16080 )
16081{
16082 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16083 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053016084 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016085#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016086#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016087#endif
16088#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016089#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016090#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016091 /*set key mgmt type*/
16092 switch(key_mgmt)
16093 {
16094 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053016095 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016096#ifdef WLAN_FEATURE_VOWIFI_11R
16097 case WLAN_AKM_SUITE_FT_PSK:
16098#endif
16099 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070016100 __func__);
16101 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
16102 break;
16103
16104 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053016105 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016106#ifdef WLAN_FEATURE_VOWIFI_11R
16107 case WLAN_AKM_SUITE_FT_8021X:
16108#endif
16109 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070016110 __func__);
16111 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16112 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016113#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016114#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
16115#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
16116 case WLAN_AKM_SUITE_CCKM:
16117 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
16118 __func__);
16119 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
16120 break;
16121#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070016122#ifndef WLAN_AKM_SUITE_OSEN
16123#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
16124 case WLAN_AKM_SUITE_OSEN:
16125 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
16126 __func__);
16127 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16128 break;
16129#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016130
16131 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016132 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016133 __func__, key_mgmt);
16134 return -EINVAL;
16135
16136 }
16137 return 0;
16138}
16139
16140/*
16141 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016142 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070016143 * (NONE/WEP40/WEP104/TKIP/CCMP).
16144 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016145static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
16146 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070016147 bool ucast
16148 )
16149{
16150 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016151 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016152 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16153
16154 ENTER();
16155
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016156 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016157 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053016158 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070016159 __func__, cipher);
16160 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16161 }
16162 else
16163 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016164
Jeff Johnson295189b2012-06-20 16:38:30 -070016165 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016166 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016167 {
16168 case IW_AUTH_CIPHER_NONE:
16169 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16170 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016171
Jeff Johnson295189b2012-06-20 16:38:30 -070016172 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016173 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070016174 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016175
Jeff Johnson295189b2012-06-20 16:38:30 -070016176 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016177 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070016178 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016179
Jeff Johnson295189b2012-06-20 16:38:30 -070016180 case WLAN_CIPHER_SUITE_TKIP:
16181 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
16182 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016183
Jeff Johnson295189b2012-06-20 16:38:30 -070016184 case WLAN_CIPHER_SUITE_CCMP:
16185 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16186 break;
16187#ifdef FEATURE_WLAN_WAPI
16188 case WLAN_CIPHER_SUITE_SMS4:
16189 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
16190 break;
16191#endif
16192
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016193#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016194 case WLAN_CIPHER_SUITE_KRK:
16195 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
16196 break;
16197#endif
16198 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016199 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016200 __func__, cipher);
16201 return -EOPNOTSUPP;
16202 }
16203 }
16204
16205 if (ucast)
16206 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016207 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016208 __func__, encryptionType);
16209 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16210 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016211 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016212 encryptionType;
16213 }
16214 else
16215 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016216 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016217 __func__, encryptionType);
16218 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
16219 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
16220 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
16221 }
16222
16223 return 0;
16224}
16225
16226
16227/*
16228 * FUNCTION: wlan_hdd_cfg80211_set_ie
16229 * This function is used to parse WPA/RSN IE's.
16230 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016231int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016232#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16233 const u8 *ie,
16234#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016235 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016236#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016237 size_t ie_len
16238 )
16239{
16240 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016241#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16242 const u8 *genie = ie;
16243#else
Jeff Johnson295189b2012-06-20 16:38:30 -070016244 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016245#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016246 v_U16_t remLen = ie_len;
16247#ifdef FEATURE_WLAN_WAPI
16248 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
16249 u16 *tmp;
16250 v_U16_t akmsuiteCount;
16251 int *akmlist;
16252#endif
16253 ENTER();
16254
16255 /* clear previous assocAddIE */
16256 pWextState->assocAddIE.length = 0;
16257 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016258 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016259
16260 while (remLen >= 2)
16261 {
16262 v_U16_t eLen = 0;
16263 v_U8_t elementId;
16264 elementId = *genie++;
16265 eLen = *genie++;
16266 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016267
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053016268 /* Sanity check on eLen */
16269 if (eLen > remLen) {
16270 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
16271 __func__, eLen, elementId);
16272 VOS_ASSERT(0);
16273 return -EINVAL;
16274 }
16275
Arif Hussain6d2a3322013-11-17 19:50:10 -080016276 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070016277 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016278
16279 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070016280 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016281 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016282 if (4 > eLen) /* should have at least OUI which is 4 bytes so extra 2 bytes not needed */
Jeff Johnson295189b2012-06-20 16:38:30 -070016283 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016284 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016285 "%s: Invalid WPA IE", __func__);
16286 return -EINVAL;
16287 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016288 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070016289 {
16290 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016291 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016292 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016293
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016294 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016295 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016296 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
16297 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016298 VOS_ASSERT(0);
16299 return -ENOMEM;
16300 }
16301 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16302 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16303 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016304
Jeff Johnson295189b2012-06-20 16:38:30 -070016305 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
16306 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16307 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16308 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016309 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
16310 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053016311 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16312 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
16313 __func__, eLen);
16314 VOS_ASSERT(0);
16315 return -EINVAL;
16316 }
16317
Jeff Johnson295189b2012-06-20 16:38:30 -070016318 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
16319 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16320 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
16321 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
16322 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
16323 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016324 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053016325 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070016326 {
16327 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016328 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016329 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016330
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016331 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016332 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016333 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16334 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016335 VOS_ASSERT(0);
16336 return -ENOMEM;
16337 }
16338 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16339 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16340 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016341
Jeff Johnson295189b2012-06-20 16:38:30 -070016342 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16343 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16344 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016345#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016346 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
16347 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016348 /*Consider WFD IE, only for P2P Client */
16349 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
16350 {
16351 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016352 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016353 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016354
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016355 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016356 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016357 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16358 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016359 VOS_ASSERT(0);
16360 return -ENOMEM;
16361 }
16362 // WFD IE is saved to Additional IE ; it should be accumulated to handle
16363 // WPS IE + P2P IE + WFD IE
16364 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16365 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016366
Jeff Johnson295189b2012-06-20 16:38:30 -070016367 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16368 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16369 }
16370#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016371 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016372 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016373 HS20_OUI_TYPE_SIZE)) )
16374 {
16375 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016376 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016377 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016378
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016379 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016380 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016381 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16382 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016383 VOS_ASSERT(0);
16384 return -ENOMEM;
16385 }
16386 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16387 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016388
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016389 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16390 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16391 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016392 /* Appending OSEN Information Element in Assiciation Request */
16393 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
16394 OSEN_OUI_TYPE_SIZE)) )
16395 {
16396 v_U16_t curAddIELen = pWextState->assocAddIE.length;
16397 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
16398 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016399
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016400 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016401 {
16402 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16403 "Need bigger buffer space");
16404 VOS_ASSERT(0);
16405 return -ENOMEM;
16406 }
16407 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16408 pWextState->assocAddIE.length += eLen + 2;
16409
16410 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
16411 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16412 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16413 }
16414
Abhishek Singh4322e622015-06-10 15:42:54 +053016415 /* Update only for WPA IE */
16416 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
16417 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016418
16419 /* populating as ADDIE in beacon frames */
16420 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016421 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016422 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
16423 {
16424 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16425 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
16426 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16427 {
16428 hddLog(LOGE,
16429 "Coldn't pass "
16430 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
16431 }
16432 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
16433 else
16434 hddLog(LOGE,
16435 "Could not pass on "
16436 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
16437
16438 /* IBSS mode doesn't contain params->proberesp_ies still
16439 beaconIE's need to be populated in probe response frames */
16440 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
16441 {
16442 u16 rem_probe_resp_ie_len = eLen + 2;
16443 u8 probe_rsp_ie_len[3] = {0};
16444 u8 counter = 0;
16445
16446 /* Check Probe Resp Length if it is greater then 255 then
16447 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
16448 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
16449 not able Store More then 255 bytes into One Variable */
16450
16451 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
16452 {
16453 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
16454 {
16455 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
16456 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
16457 }
16458 else
16459 {
16460 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
16461 rem_probe_resp_ie_len = 0;
16462 }
16463 }
16464
16465 rem_probe_resp_ie_len = 0;
16466
16467 if (probe_rsp_ie_len[0] > 0)
16468 {
16469 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16470 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
16471 (tANI_U8*)(genie - 2),
16472 probe_rsp_ie_len[0], NULL,
16473 eANI_BOOLEAN_FALSE)
16474 == eHAL_STATUS_FAILURE)
16475 {
16476 hddLog(LOGE,
16477 "Could not pass"
16478 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
16479 }
16480 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
16481 }
16482
16483 if (probe_rsp_ie_len[1] > 0)
16484 {
16485 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16486 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
16487 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16488 probe_rsp_ie_len[1], NULL,
16489 eANI_BOOLEAN_FALSE)
16490 == eHAL_STATUS_FAILURE)
16491 {
16492 hddLog(LOGE,
16493 "Could not pass"
16494 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
16495 }
16496 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
16497 }
16498
16499 if (probe_rsp_ie_len[2] > 0)
16500 {
16501 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16502 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
16503 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16504 probe_rsp_ie_len[2], NULL,
16505 eANI_BOOLEAN_FALSE)
16506 == eHAL_STATUS_FAILURE)
16507 {
16508 hddLog(LOGE,
16509 "Could not pass"
16510 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
16511 }
16512 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
16513 }
16514
16515 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16516 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
16517 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16518 {
16519 hddLog(LOGE,
16520 "Could not pass"
16521 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
16522 }
16523 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016524 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070016525 break;
16526 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053016527 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16528 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
16529 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
16530 VOS_ASSERT(0);
16531 return -EINVAL;
16532 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016533 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
16534 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16535 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
16536 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
16537 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16538 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016539
Abhishek Singhb16f3562016-01-20 11:08:32 +053016540 /* Appending extended capabilities with Interworking or
16541 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016542 *
16543 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016544 * interworkingService or bsstransition bit is set to 1.
16545 * Driver is only interested in interworkingService and
16546 * bsstransition capability from supplicant.
16547 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016548 * required from supplicat, it needs to be handled while
16549 * sending Assoc Req in LIM.
16550 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016551 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016552 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016553 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016554 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016555 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016556
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016557 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016558 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016559 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16560 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016561 VOS_ASSERT(0);
16562 return -ENOMEM;
16563 }
16564 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16565 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016566
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016567 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16568 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16569 break;
16570 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016571#ifdef FEATURE_WLAN_WAPI
16572 case WLAN_EID_WAPI:
16573 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016574 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016575 pAdapter->wapi_info.nWapiMode);
16576 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016577 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016578 akmsuiteCount = WPA_GET_LE16(tmp);
16579 tmp = tmp + 1;
16580 akmlist = (int *)(tmp);
16581 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16582 {
16583 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16584 }
16585 else
16586 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016587 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016588 VOS_ASSERT(0);
16589 return -EINVAL;
16590 }
16591
16592 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16593 {
16594 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016595 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016596 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016597 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016598 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016599 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016600 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016601 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016602 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
16603 }
16604 break;
16605#endif
16606 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016607 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016608 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016609 /* when Unknown IE is received we should break and continue
16610 * to the next IE in the buffer instead we were returning
16611 * so changing this to break */
16612 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016613 }
16614 genie += eLen;
16615 remLen -= eLen;
16616 }
16617 EXIT();
16618 return 0;
16619}
16620
16621/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016622 * FUNCTION: hdd_isWPAIEPresent
16623 * Parse the received IE to find the WPA IE
16624 *
16625 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016626static bool hdd_isWPAIEPresent(
16627#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16628 const u8 *ie,
16629#else
16630 u8 *ie,
16631#endif
16632 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016633{
16634 v_U8_t eLen = 0;
16635 v_U16_t remLen = ie_len;
16636 v_U8_t elementId = 0;
16637
16638 while (remLen >= 2)
16639 {
16640 elementId = *ie++;
16641 eLen = *ie++;
16642 remLen -= 2;
16643 if (eLen > remLen)
16644 {
16645 hddLog(VOS_TRACE_LEVEL_ERROR,
16646 "%s: IE length is wrong %d", __func__, eLen);
16647 return FALSE;
16648 }
16649 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16650 {
16651 /* OUI - 0x00 0X50 0XF2
16652 WPA Information Element - 0x01
16653 WPA version - 0x01*/
16654 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16655 return TRUE;
16656 }
16657 ie += eLen;
16658 remLen -= eLen;
16659 }
16660 return FALSE;
16661}
16662
16663/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016664 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016665 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016666 * parameters during connect operation.
16667 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016668int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016669 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016670 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016671{
16672 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016673 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016674 ENTER();
16675
16676 /*set wpa version*/
16677 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
16678
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016679 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016680 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053016681 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016682 {
16683 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16684 }
16685 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
16686 {
16687 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16688 }
16689 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016690
16691 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016692 pWextState->wpaVersion);
16693
16694 /*set authentication type*/
16695 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
16696
16697 if (0 > status)
16698 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016699 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016700 "%s: failed to set authentication type ", __func__);
16701 return status;
16702 }
16703
16704 /*set key mgmt type*/
16705 if (req->crypto.n_akm_suites)
16706 {
16707 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
16708 if (0 > status)
16709 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016710 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070016711 __func__);
16712 return status;
16713 }
16714 }
16715
16716 /*set pairwise cipher type*/
16717 if (req->crypto.n_ciphers_pairwise)
16718 {
16719 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
16720 req->crypto.ciphers_pairwise[0], true);
16721 if (0 > status)
16722 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016723 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016724 "%s: failed to set unicast cipher type", __func__);
16725 return status;
16726 }
16727 }
16728 else
16729 {
16730 /*Reset previous cipher suite to none*/
16731 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
16732 if (0 > status)
16733 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016734 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016735 "%s: failed to set unicast cipher type", __func__);
16736 return status;
16737 }
16738 }
16739
16740 /*set group cipher type*/
16741 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
16742 false);
16743
16744 if (0 > status)
16745 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016746 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070016747 __func__);
16748 return status;
16749 }
16750
Chet Lanctot186b5732013-03-18 10:26:30 -070016751#ifdef WLAN_FEATURE_11W
16752 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
16753#endif
16754
Jeff Johnson295189b2012-06-20 16:38:30 -070016755 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
16756 if (req->ie_len)
16757 {
16758 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
16759 if ( 0 > status)
16760 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016761 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016762 __func__);
16763 return status;
16764 }
16765 }
16766
16767 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016768 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016769 {
16770 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
16771 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
16772 )
16773 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016774 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070016775 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
16776 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016777 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016778 __func__);
16779 return -EOPNOTSUPP;
16780 }
16781 else
16782 {
16783 u8 key_len = req->key_len;
16784 u8 key_idx = req->key_idx;
16785
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016786 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016787 && (CSR_MAX_NUM_KEY > key_idx)
16788 )
16789 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016790 hddLog(VOS_TRACE_LEVEL_INFO,
16791 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016792 __func__, key_idx, key_len);
16793 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016794 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070016795 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016796 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016797 (u8)key_len;
16798 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
16799 }
16800 }
16801 }
16802 }
16803
16804 return status;
16805}
16806
16807/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016808 * FUNCTION: wlan_hdd_try_disconnect
16809 * This function is used to disconnect from previous
16810 * connection
16811 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053016812int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016813{
16814 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016815 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016816 hdd_station_ctx_t *pHddStaCtx;
16817 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016818 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016819
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016820 ret = wlan_hdd_validate_context(pHddCtx);
16821 if (0 != ret)
16822 {
16823 return ret;
16824 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016825 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16826
16827 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
16828
16829 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
16830 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053016831 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016832 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
16833 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053016834 /* Indicate disconnect to SME so that in-progress connection or preauth
16835 * can be aborted
16836 */
16837 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
16838 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016839 spin_lock_bh(&pAdapter->lock_for_active_session);
16840 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16841 {
16842 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16843 }
16844 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053016845 hdd_connSetConnectionState(pHddStaCtx,
16846 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016847 /* Issue disconnect to CSR */
16848 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016849 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016850 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016851 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16852 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
16853 hddLog(LOG1,
16854 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
16855 } else if ( 0 != status ) {
16856 hddLog(LOGE,
16857 FL("csrRoamDisconnect failure, returned %d"),
16858 (int)status );
16859 result = -EINVAL;
16860 goto disconnected;
16861 }
16862 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016863 &pAdapter->disconnect_comp_var,
16864 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016865 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
16866 hddLog(LOGE,
16867 "%s: Failed to disconnect, timed out", __func__);
16868 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016869 }
16870 }
16871 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
16872 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016873 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016874 &pAdapter->disconnect_comp_var,
16875 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016876 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016877 {
16878 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016879 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016880 }
16881 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016882disconnected:
16883 hddLog(LOG1,
16884 FL("Set HDD connState to eConnectionState_NotConnected"));
16885 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16886 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016887}
16888
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016889/**
16890 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16891 * @adapter: Pointer to the HDD adapter
16892 * @req: Pointer to the structure cfg_connect_params receieved from user space
16893 *
16894 * This function will start reassociation if bssid hint, channel hint and
16895 * previous bssid parameters are present in the connect request
16896 *
16897 * Return: success if reassociation is happening
16898 * Error code if reassociation is not permitted or not happening
16899 */
16900#ifdef CFG80211_CONNECT_PREV_BSSID
16901static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16902 struct cfg80211_connect_params *req)
16903{
16904 int status = -EPERM;
16905 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
16906 hddLog(VOS_TRACE_LEVEL_INFO,
16907 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
16908 req->channel_hint->hw_value,
16909 MAC_ADDR_ARRAY(req->bssid_hint));
16910 status = hdd_reassoc(adapter, req->bssid_hint,
16911 req->channel_hint->hw_value,
16912 CONNECT_CMD_USERSPACE);
16913 }
16914 return status;
16915}
16916#else
16917static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16918 struct cfg80211_connect_params *req)
16919{
16920 return -EPERM;
16921}
16922#endif
16923
Abhishek Singhe3beee22017-07-31 15:35:40 +053016924/**
16925 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
16926 * connect in HT20 mode
16927 * @hdd_ctx: hdd context
16928 * @adapter: Pointer to the HDD adapter
16929 * @req: Pointer to the structure cfg_connect_params receieved from user space
16930 *
16931 * This function will check if supplicant has indicated to to connect in HT20
16932 * mode. this is currently applicable only for 2.4Ghz mode only.
16933 * if feature is enabled and supplicant indicate HT20 set
16934 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
16935 *
16936 * Return: void
16937 */
16938#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
16939static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16940 hdd_adapter_t *adapter,
16941 struct cfg80211_connect_params *req)
16942{
16943 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16944 tCsrRoamProfile *roam_profile;
16945
16946 roam_profile = &wext_state->roamProfile;
16947 roam_profile->force_24ghz_in_ht20 = false;
16948 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
16949 !(req->ht_capa.cap_info &
16950 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
16951 roam_profile->force_24ghz_in_ht20 = true;
16952
16953 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
16954 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
16955}
16956#else
16957static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16958 hdd_adapter_t *adapter,
16959 struct cfg80211_connect_params *req)
16960{
16961 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16962 tCsrRoamProfile *roam_profile;
16963
16964 roam_profile = &wext_state->roamProfile;
16965 roam_profile->force_24ghz_in_ht20 = false;
16966}
16967#endif
16968
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016969/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053016970 * FUNCTION: __wlan_hdd_cfg80211_connect
16971 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070016972 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016973static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016974 struct net_device *ndev,
16975 struct cfg80211_connect_params *req
16976 )
16977{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016978 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016979 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053016980#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
16981 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016982 const u8 *bssid_hint = req->bssid_hint;
16983#else
16984 const u8 *bssid_hint = NULL;
16985#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016986 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016987 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053016988 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016989
16990 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016991
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016992 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16993 TRACE_CODE_HDD_CFG80211_CONNECT,
16994 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016995 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016996 "%s: device_mode = %s (%d)", __func__,
16997 hdd_device_modetoString(pAdapter->device_mode),
16998 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016999
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017000 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017001 if (!pHddCtx)
17002 {
17003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17004 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053017005 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017006 }
17007
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017008 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017009 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017010 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017011 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017012 }
17013
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053017014 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
17015 return -EINVAL;
17016
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017017 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
17018 if (0 == status)
17019 return status;
17020
Agarwal Ashish51325b52014-06-16 16:50:49 +053017021
Jeff Johnson295189b2012-06-20 16:38:30 -070017022#ifdef WLAN_BTAMP_FEATURE
17023 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017024 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070017025 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017026 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017027 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080017028 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070017029 }
17030#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017031
17032 //If Device Mode is Station Concurrent Sessions Exit BMps
17033 //P2P Mode will be taken care in Open/close adapter
17034 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053017035 (vos_concurrent_open_sessions_running())) {
17036 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
17037 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017038 }
17039
17040 /*Try disconnecting if already in connected state*/
17041 status = wlan_hdd_try_disconnect(pAdapter);
17042 if ( 0 > status)
17043 {
17044 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17045 " connection"));
17046 return -EALREADY;
17047 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053017048 /* Check for max concurrent connections after doing disconnect if any*/
17049 if (vos_max_concurrent_connections_reached()) {
17050 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17051 return -ECONNREFUSED;
17052 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017053
Jeff Johnson295189b2012-06-20 16:38:30 -070017054 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017055 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070017056
17057 if ( 0 > status)
17058 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017059 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070017060 __func__);
17061 return status;
17062 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053017063
17064 if (pHddCtx->spoofMacAddr.isEnabled)
17065 {
17066 hddLog(VOS_TRACE_LEVEL_INFO,
17067 "%s: MAC Spoofing enabled ", __func__);
17068 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
17069 * to fill TxBds for probe request during SSID scan which may happen
17070 * as part of connect command
17071 */
17072 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
17073 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
17074 if (status != VOS_STATUS_SUCCESS)
17075 return -ECONNREFUSED;
17076 }
17077
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017078 if (req->channel)
17079 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070017080 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017081 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053017082
17083 /* Abort if any scan is going on */
17084 status = wlan_hdd_scan_abort(pAdapter);
17085 if (0 != status)
17086 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
17087
Abhishek Singhe3beee22017-07-31 15:35:40 +053017088 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
17089
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017090 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
17091 req->ssid_len, req->bssid,
17092 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017093
Sushant Kaushikd7083982015-03-18 14:33:24 +053017094 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017095 {
17096 //ReEnable BMPS if disabled
17097 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
17098 (NULL != pHddCtx))
17099 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053017100 if (pHddCtx->hdd_wlan_suspended)
17101 {
17102 hdd_set_pwrparams(pHddCtx);
17103 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017104 //ReEnable Bmps and Imps back
17105 hdd_enable_bmps_imps(pHddCtx);
17106 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053017107 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070017108 return status;
17109 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017110 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017111 EXIT();
17112 return status;
17113}
17114
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017115static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
17116 struct net_device *ndev,
17117 struct cfg80211_connect_params *req)
17118{
17119 int ret;
17120 vos_ssr_protect(__func__);
17121 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
17122 vos_ssr_unprotect(__func__);
17123
17124 return ret;
17125}
Jeff Johnson295189b2012-06-20 16:38:30 -070017126
17127/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017128 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070017129 * This function is used to issue a disconnect request to SME
17130 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017131static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017132 struct net_device *dev,
17133 u16 reason
17134 )
17135{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017136 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017137 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017138 tCsrRoamProfile *pRoamProfile;
17139 hdd_station_ctx_t *pHddStaCtx;
17140 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017141#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017142 tANI_U8 staIdx;
17143#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017144
Jeff Johnson295189b2012-06-20 16:38:30 -070017145 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017146
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017147 if (!pAdapter) {
17148 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17149 return -EINVAL;
17150 }
17151
17152 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17153 if (!pHddStaCtx) {
17154 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
17155 return -EINVAL;
17156 }
17157
17158 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17159 status = wlan_hdd_validate_context(pHddCtx);
17160 if (0 != status)
17161 {
17162 return status;
17163 }
17164
17165 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
17166
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017167 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17168 TRACE_CODE_HDD_CFG80211_DISCONNECT,
17169 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017170 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
17171 __func__, hdd_device_modetoString(pAdapter->device_mode),
17172 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017173
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017174 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
17175 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070017176
Jeff Johnson295189b2012-06-20 16:38:30 -070017177 if (NULL != pRoamProfile)
17178 {
17179 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017180 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
17181 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070017182 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017183 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070017184 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017185 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070017186 switch(reason)
17187 {
17188 case WLAN_REASON_MIC_FAILURE:
17189 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
17190 break;
17191
17192 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
17193 case WLAN_REASON_DISASSOC_AP_BUSY:
17194 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
17195 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
17196 break;
17197
17198 case WLAN_REASON_PREV_AUTH_NOT_VALID:
17199 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053017200 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070017201 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
17202 break;
17203
Jeff Johnson295189b2012-06-20 16:38:30 -070017204 default:
17205 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
17206 break;
17207 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017208 pScanInfo = &pHddCtx->scan_info;
17209 if (pScanInfo->mScanPending)
17210 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017211 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017212 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053017213 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017214 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017215 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053017216 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017217#ifdef FEATURE_WLAN_TDLS
17218 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017219 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017220 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017221 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
17222 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017223 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017224 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017225 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017227 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017228 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017229 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017230 status = sme_DeleteTdlsPeerSta(
17231 WLAN_HDD_GET_HAL_CTX(pAdapter),
17232 pAdapter->sessionId,
17233 mac);
17234 if (status != eHAL_STATUS_SUCCESS) {
17235 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
17236 return -EPERM;
17237 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017238 }
17239 }
17240#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053017241
17242 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
17243 reasonCode,
17244 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017245 status = wlan_hdd_disconnect(pAdapter, reasonCode);
17246 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070017247 {
17248 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017249 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017250 __func__, (int)status );
17251 return -EINVAL;
17252 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017253 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017254 else
17255 {
17256 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
17257 "called while in %d state", __func__,
17258 pHddStaCtx->conn_info.connState);
17259 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017260 }
17261 else
17262 {
17263 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
17264 }
17265
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017266 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017267 return status;
17268}
17269
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017270static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
17271 struct net_device *dev,
17272 u16 reason
17273 )
17274{
17275 int ret;
17276 vos_ssr_protect(__func__);
17277 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
17278 vos_ssr_unprotect(__func__);
17279
17280 return ret;
17281}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017282
Jeff Johnson295189b2012-06-20 16:38:30 -070017283/*
17284 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017285 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070017286 * settings in IBSS mode.
17287 */
17288static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017289 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070017290 struct cfg80211_ibss_params *params
17291 )
17292{
17293 int status = 0;
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017294 tANI_U32 ret;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017295 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070017296 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
17297 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017298
Jeff Johnson295189b2012-06-20 16:38:30 -070017299 ENTER();
17300
17301 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070017302 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070017303
17304 if (params->ie_len && ( NULL != params->ie) )
17305 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017306 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17307 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017308 {
17309 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
17310 encryptionType = eCSR_ENCRYPT_TYPE_AES;
17311 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017312 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017313 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017314 tDot11fIEWPA dot11WPAIE;
17315 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017316 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017317
Wilson Yang00256342013-10-10 23:13:38 -070017318 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017319 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17320 params->ie_len, DOT11F_EID_WPA);
17321 if ( NULL != ie )
17322 {
17323 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
17324 // Unpack the WPA IE
17325 //Skip past the EID byte and length byte - and four byte WiFi OUI
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017326 ret = dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017327 &ie[2+4],
17328 ie[1] - 4,
17329 &dot11WPAIE);
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017330 if (DOT11F_FAILED(ret))
17331 {
17332 hddLog(LOGE,
17333 FL("unpack failed status:(0x%08x)"),
17334 ret);
17335 return -EINVAL;
17336 }
17337
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017338 /*Extract the multicast cipher, the encType for unicast
17339 cipher for wpa-none is none*/
17340 encryptionType =
17341 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
17342 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017343 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017344
Jeff Johnson295189b2012-06-20 16:38:30 -070017345 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
17346
17347 if (0 > status)
17348 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017349 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070017350 __func__);
17351 return status;
17352 }
17353 }
17354
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017355 pWextState->roamProfile.AuthType.authType[0] =
17356 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070017357 eCSR_AUTH_TYPE_OPEN_SYSTEM;
Jeff Johnson295189b2012-06-20 16:38:30 -070017358 if (params->privacy)
17359 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017360 /* Security enabled IBSS, At this time there is no information available
17361 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070017362 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017363 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070017364 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017365 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070017366 *enable privacy bit in beacons */
17367
17368 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
17369 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017370 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17371 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070017372 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
17373 pWextState->roamProfile.EncryptionType.numEntries = 1;
17374 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070017375 return status;
17376}
17377
17378/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017379 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017380 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017381 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017382static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017383 struct net_device *dev,
17384 struct cfg80211_ibss_params *params
17385 )
17386{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017387 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017388 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17389 tCsrRoamProfile *pRoamProfile;
17390 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017391 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17392 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017393 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070017394
17395 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017396
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017397 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17398 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
17399 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017400 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017401 "%s: device_mode = %s (%d)", __func__,
17402 hdd_device_modetoString(pAdapter->device_mode),
17403 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017404
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017405 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017406 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017407 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017408 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017409 }
17410
17411 if (NULL == pWextState)
17412 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017413 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017414 __func__);
17415 return -EIO;
17416 }
17417
Agarwal Ashish51325b52014-06-16 16:50:49 +053017418 if (vos_max_concurrent_connections_reached()) {
17419 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17420 return -ECONNREFUSED;
17421 }
17422
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017423 /*Try disconnecting if already in connected state*/
17424 status = wlan_hdd_try_disconnect(pAdapter);
17425 if ( 0 > status)
17426 {
17427 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17428 " IBSS connection"));
17429 return -EALREADY;
17430 }
17431
Jeff Johnson295189b2012-06-20 16:38:30 -070017432 pRoamProfile = &pWextState->roamProfile;
17433
17434 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
17435 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017436 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017437 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017438 return -EINVAL;
17439 }
17440
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017441 /* BSSID is provided by upper layers hence no need to AUTO generate */
17442 if (NULL != params->bssid) {
17443 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17444 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
17445 hddLog (VOS_TRACE_LEVEL_ERROR,
17446 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17447 return -EIO;
17448 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017449 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017450 }
krunal sonie9002db2013-11-25 14:24:17 -080017451 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
17452 {
17453 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17454 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
17455 {
17456 hddLog (VOS_TRACE_LEVEL_ERROR,
17457 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17458 return -EIO;
17459 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017460
17461 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080017462 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017463 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080017464 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017465
Jeff Johnson295189b2012-06-20 16:38:30 -070017466 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070017467 if (NULL !=
17468#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17469 params->chandef.chan)
17470#else
17471 params->channel)
17472#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017473 {
17474 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017475 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17476 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
17477 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17478 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017479
17480 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017481 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070017482 ieee80211_frequency_to_channel(
17483#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17484 params->chandef.chan->center_freq);
17485#else
17486 params->channel->center_freq);
17487#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017488
17489 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17490 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070017491 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017492 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
17493 __func__);
17494 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070017495 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017496
17497 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017498 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017499 if (channelNum == validChan[indx])
17500 {
17501 break;
17502 }
17503 }
17504 if (indx >= numChans)
17505 {
17506 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017507 __func__, channelNum);
17508 return -EINVAL;
17509 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017510 /* Set the Operational Channel */
17511 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
17512 channelNum);
17513 pRoamProfile->ChannelInfo.numOfChannels = 1;
17514 pHddStaCtx->conn_info.operationChannel = channelNum;
17515 pRoamProfile->ChannelInfo.ChannelList =
17516 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070017517 }
17518
17519 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017520 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070017521 if (status < 0)
17522 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017523 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070017524 __func__);
17525 return status;
17526 }
17527
17528 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017529 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053017530 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017531 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017532
17533 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017534 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017535
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017536 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017537 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017538}
17539
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017540static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17541 struct net_device *dev,
17542 struct cfg80211_ibss_params *params
17543 )
17544{
17545 int ret = 0;
17546
17547 vos_ssr_protect(__func__);
17548 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17549 vos_ssr_unprotect(__func__);
17550
17551 return ret;
17552}
17553
Jeff Johnson295189b2012-06-20 16:38:30 -070017554/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017555 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017556 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017557 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017558static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017559 struct net_device *dev
17560 )
17561{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017562 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017563 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17564 tCsrRoamProfile *pRoamProfile;
17565 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017566 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017567 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017568#ifdef WLAN_FEATURE_RMC
17569 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17570#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017571
17572 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017573
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017574 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17575 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17576 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017577 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017578 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017579 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017580 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017581 }
17582
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017583 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17584 hdd_device_modetoString(pAdapter->device_mode),
17585 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017586 if (NULL == pWextState)
17587 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017588 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017589 __func__);
17590 return -EIO;
17591 }
17592
17593 pRoamProfile = &pWextState->roamProfile;
17594
17595 /* Issue disconnect only if interface type is set to IBSS */
17596 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17597 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017598 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017599 __func__);
17600 return -EINVAL;
17601 }
17602
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017603#ifdef WLAN_FEATURE_RMC
17604 /* Clearing add IE of beacon */
17605 if (ccmCfgSetStr(pHddCtx->hHal,
17606 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17607 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17608 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17609 {
17610 hddLog (VOS_TRACE_LEVEL_ERROR,
17611 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17612 return -EINVAL;
17613 }
17614 if (ccmCfgSetInt(pHddCtx->hHal,
17615 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17616 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17617 {
17618 hddLog (VOS_TRACE_LEVEL_ERROR,
17619 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17620 __func__);
17621 return -EINVAL;
17622 }
17623
17624 // Reset WNI_CFG_PROBE_RSP Flags
17625 wlan_hdd_reset_prob_rspies(pAdapter);
17626
17627 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17628 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17629 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17630 {
17631 hddLog (VOS_TRACE_LEVEL_ERROR,
17632 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17633 __func__);
17634 return -EINVAL;
17635 }
17636#endif
17637
Jeff Johnson295189b2012-06-20 16:38:30 -070017638 /* Issue Disconnect request */
17639 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017640 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17641 pAdapter->sessionId,
17642 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17643 if (!HAL_STATUS_SUCCESS(hal_status)) {
17644 hddLog(LOGE,
17645 FL("sme_RoamDisconnect failed hal_status(%d)"),
17646 hal_status);
17647 return -EAGAIN;
17648 }
17649 status = wait_for_completion_timeout(
17650 &pAdapter->disconnect_comp_var,
17651 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17652 if (!status) {
17653 hddLog(LOGE,
17654 FL("wait on disconnect_comp_var failed"));
17655 return -ETIMEDOUT;
17656 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017657
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017658 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017659 return 0;
17660}
17661
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017662static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17663 struct net_device *dev
17664 )
17665{
17666 int ret = 0;
17667
17668 vos_ssr_protect(__func__);
17669 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17670 vos_ssr_unprotect(__func__);
17671
17672 return ret;
17673}
17674
Jeff Johnson295189b2012-06-20 16:38:30 -070017675/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017676 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017677 * This function is used to set the phy parameters
17678 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17679 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017680static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017681 u32 changed)
17682{
17683 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17684 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017685 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017686
17687 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017688
17689 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017690 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17691 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017692
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017693 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017694 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017695 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017696 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017697 }
17698
Jeff Johnson295189b2012-06-20 16:38:30 -070017699 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17700 {
17701 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17702 WNI_CFG_RTS_THRESHOLD_STAMAX :
17703 wiphy->rts_threshold;
17704
17705 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017706 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017707 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017708 hddLog(VOS_TRACE_LEVEL_ERROR,
17709 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017710 __func__, rts_threshold);
17711 return -EINVAL;
17712 }
17713
17714 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17715 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017716 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017717 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017718 hddLog(VOS_TRACE_LEVEL_ERROR,
17719 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017720 __func__, rts_threshold);
17721 return -EIO;
17722 }
17723
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017724 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017725 rts_threshold);
17726 }
17727
17728 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17729 {
17730 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17731 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17732 wiphy->frag_threshold;
17733
17734 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017735 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017736 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017737 hddLog(VOS_TRACE_LEVEL_ERROR,
17738 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017739 frag_threshold);
17740 return -EINVAL;
17741 }
17742
17743 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
17744 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017745 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017746 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017747 hddLog(VOS_TRACE_LEVEL_ERROR,
17748 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017749 __func__, frag_threshold);
17750 return -EIO;
17751 }
17752
17753 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
17754 frag_threshold);
17755 }
17756
17757 if ((changed & WIPHY_PARAM_RETRY_SHORT)
17758 || (changed & WIPHY_PARAM_RETRY_LONG))
17759 {
17760 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
17761 wiphy->retry_short :
17762 wiphy->retry_long;
17763
17764 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17765 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17766 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017767 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017768 __func__, retry_value);
17769 return -EINVAL;
17770 }
17771
17772 if (changed & WIPHY_PARAM_RETRY_SHORT)
17773 {
17774 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17775 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017776 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017777 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017778 hddLog(VOS_TRACE_LEVEL_ERROR,
17779 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017780 __func__, retry_value);
17781 return -EIO;
17782 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017783 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017784 __func__, retry_value);
17785 }
17786 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17787 {
17788 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17789 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017790 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017791 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017792 hddLog(VOS_TRACE_LEVEL_ERROR,
17793 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017794 __func__, retry_value);
17795 return -EIO;
17796 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017797 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017798 __func__, retry_value);
17799 }
17800 }
17801
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017802 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017803 return 0;
17804}
17805
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017806static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17807 u32 changed)
17808{
17809 int ret;
17810
17811 vos_ssr_protect(__func__);
17812 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17813 vos_ssr_unprotect(__func__);
17814
17815 return ret;
17816}
17817
Jeff Johnson295189b2012-06-20 16:38:30 -070017818/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017819 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017820 * This function is used to set the txpower
17821 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017822static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017823#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17824 struct wireless_dev *wdev,
17825#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017826#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017827 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017828#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017829 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017830#endif
17831 int dbm)
17832{
17833 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017834 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017835 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17836 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017837 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017838
17839 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017840
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017841 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17842 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17843 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017844 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017845 if (0 != status)
17846 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017847 return status;
17848 }
17849
17850 hHal = pHddCtx->hHal;
17851
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017852 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17853 dbm, ccmCfgSetCallback,
17854 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017855 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017856 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017857 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17858 return -EIO;
17859 }
17860
17861 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17862 dbm);
17863
17864 switch(type)
17865 {
17866 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17867 /* Fall through */
17868 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17869 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17870 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017871 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17872 __func__);
17873 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017874 }
17875 break;
17876 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017877 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017878 __func__);
17879 return -EOPNOTSUPP;
17880 break;
17881 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017882 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17883 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017884 return -EIO;
17885 }
17886
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017887 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017888 return 0;
17889}
17890
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017891static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17892#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17893 struct wireless_dev *wdev,
17894#endif
17895#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17896 enum tx_power_setting type,
17897#else
17898 enum nl80211_tx_power_setting type,
17899#endif
17900 int dbm)
17901{
17902 int ret;
17903 vos_ssr_protect(__func__);
17904 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17905#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17906 wdev,
17907#endif
17908#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17909 type,
17910#else
17911 type,
17912#endif
17913 dbm);
17914 vos_ssr_unprotect(__func__);
17915
17916 return ret;
17917}
17918
Jeff Johnson295189b2012-06-20 16:38:30 -070017919/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017920 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017921 * This function is used to read the txpower
17922 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017923static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017924#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17925 struct wireless_dev *wdev,
17926#endif
17927 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070017928{
17929
17930 hdd_adapter_t *pAdapter;
17931 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017932 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017933
Jeff Johnsone7245742012-09-05 17:12:55 -070017934 ENTER();
17935
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017936 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017937 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017938 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017939 *dbm = 0;
17940 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017941 }
17942
Jeff Johnson295189b2012-06-20 16:38:30 -070017943 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
17944 if (NULL == pAdapter)
17945 {
17946 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
17947 return -ENOENT;
17948 }
17949
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017950 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17951 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
17952 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070017953 wlan_hdd_get_classAstats(pAdapter);
17954 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
17955
Jeff Johnsone7245742012-09-05 17:12:55 -070017956 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017957 return 0;
17958}
17959
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017960static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
17961#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17962 struct wireless_dev *wdev,
17963#endif
17964 int *dbm)
17965{
17966 int ret;
17967
17968 vos_ssr_protect(__func__);
17969 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
17970#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17971 wdev,
17972#endif
17973 dbm);
17974 vos_ssr_unprotect(__func__);
17975
17976 return ret;
17977}
17978
Dustin Brown8c1d4092017-07-28 18:08:01 +053017979/*
17980 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
17981 * @stats: summary stats to use as a source
17982 * @info: kernel station_info struct to use as a destination
17983 *
17984 * Return: None
17985 */
17986static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
17987 struct station_info *info)
17988{
17989 int i;
17990
17991 info->rx_packets = stats->rx_frm_cnt;
17992 info->tx_packets = 0;
17993 info->tx_retries = 0;
17994 info->tx_failed = 0;
17995
17996 for (i = 0; i < 4; ++i) {
17997 info->tx_packets += stats->tx_frm_cnt[i];
17998 info->tx_retries += stats->multiple_retry_cnt[i];
17999 info->tx_failed += stats->fail_cnt[i];
18000 }
18001
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018002#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18003 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018004 info->filled |= STATION_INFO_TX_PACKETS |
18005 STATION_INFO_TX_RETRIES |
18006 STATION_INFO_TX_FAILED |
18007 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018008#else
18009 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
18010 BIT(NL80211_STA_INFO_TX_RETRIES) |
18011 BIT(NL80211_STA_INFO_TX_FAILED) |
18012 BIT(NL80211_STA_INFO_RX_PACKETS);
18013#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053018014}
18015
18016/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018017 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
18018 * @adapter: sap adapter pointer
18019 * @staid: station id of the client
18020 * @rssi: rssi value to fill
18021 *
18022 * Return: None
18023 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053018024void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018025wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
18026{
18027 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
18028
18029 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
18030}
18031
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018032#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18033 !defined(WITH_BACKPORTS)
18034static inline void wlan_hdd_fill_station_info_signal(struct station_info
18035 *sinfo)
18036{
18037 sinfo->filled |= STATION_INFO_SIGNAL;
18038}
18039#else
18040static inline void wlan_hdd_fill_station_info_signal(struct station_info
18041 *sinfo)
18042{
18043 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
18044}
18045#endif
18046
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018047/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053018048 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
18049 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018050 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053018051 * @info: kernel station_info struct to populate
18052 *
18053 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
18054 * support "station dump" and "station get" for SAP vdevs, even though they
18055 * aren't technically stations.
18056 *
18057 * Return: errno
18058 */
18059static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018060wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
18061#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18062 const u8* mac,
18063#else
18064 u8* mac,
18065#endif
18066 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018067{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018068 v_MACADDR_t *peerMacAddr;
18069 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018070 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018071 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018072
18073 status = wlan_hdd_get_station_stats(adapter);
18074 if (!VOS_IS_STATUS_SUCCESS(status)) {
18075 hddLog(VOS_TRACE_LEVEL_ERROR,
18076 "Failed to get SAP stats; status:%d", status);
18077 return 0;
18078 }
18079
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018080 peerMacAddr = (v_MACADDR_t *)mac;
18081 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
18082 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
18083 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
18084
18085 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
18086 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018087 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018088 }
18089
Dustin Brown8c1d4092017-07-28 18:08:01 +053018090 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
18091
18092 return 0;
18093}
18094
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018095static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018096#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18097 const u8* mac,
18098#else
18099 u8* mac,
18100#endif
18101 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070018102{
18103 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
18104 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18105 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053018106 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018107
18108 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
18109 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070018110
18111 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
18112 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
18113 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
18114 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
18115 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
18116 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
18117 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018118 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018119 tANI_U16 myRate;
18120 tANI_U16 currentRate = 0;
18121 tANI_U8 maxSpeedMCS = 0;
18122 tANI_U8 maxMCSIdx = 0;
18123 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053018124 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070018125 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018126 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018127
Leo Chang6f8870f2013-03-26 18:11:36 -070018128#ifdef WLAN_FEATURE_11AC
18129 tANI_U32 vht_mcs_map;
18130 eDataRate11ACMaxMcs vhtMaxMcs;
18131#endif /* WLAN_FEATURE_11AC */
18132
Jeff Johnsone7245742012-09-05 17:12:55 -070018133 ENTER();
18134
Dustin Brown8c1d4092017-07-28 18:08:01 +053018135 status = wlan_hdd_validate_context(pHddCtx);
18136 if (0 != status)
18137 {
18138 return status;
18139 }
18140
18141 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018142 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053018143
Jeff Johnson295189b2012-06-20 16:38:30 -070018144 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
18145 (0 == ssidlen))
18146 {
18147 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
18148 " Invalid ssidlen, %d", __func__, ssidlen);
18149 /*To keep GUI happy*/
18150 return 0;
18151 }
18152
Mukul Sharma811205f2014-07-09 21:07:30 +053018153 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
18154 {
18155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18156 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053018157 /* return a cached value */
18158 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053018159 return 0;
18160 }
18161
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053018162 wlan_hdd_get_station_stats(pAdapter);
18163 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018164
Kiet Lam3b17fc82013-09-27 05:24:08 +053018165 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018166 wlan_hdd_get_snr(pAdapter, &snr);
18167 pHddStaCtx->conn_info.signal = sinfo->signal;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018168 pHddStaCtx->cache_conn_info.signal = sinfo->signal;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018169 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018170 pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018171 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053018172
c_hpothu09f19542014-05-30 21:53:31 +053018173 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053018174 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
18175 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053018176 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053018177 {
18178 rate_flags = pAdapter->maxRateFlags;
18179 }
c_hpothu44ff4e02014-05-08 00:13:57 +053018180
Jeff Johnson295189b2012-06-20 16:38:30 -070018181 //convert to the UI units of 100kbps
18182 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
18183
18184#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070018185 pr_info("RSSI %d, RLMS %u, rate %d, rssi high %d, rssi mid %d, rssi low %d, rate_flags 0x%x, MCS %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -070018186 sinfo->signal,
18187 pCfg->reportMaxLinkSpeed,
18188 myRate,
18189 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018190 (int) pCfg->linkSpeedRssiMid,
18191 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070018192 (int) rate_flags,
18193 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070018194#endif //LINKSPEED_DEBUG_ENABLED
18195
Hanumanth Reddy Pothula596b8b32018-05-01 20:17:38 +053018196#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || defined(WITH_BACKPORTS)
18197 /* assume basic BW. anything else will override this later */
18198 sinfo->txrate.bw = RATE_INFO_BW_20;
18199#endif
18200
Jeff Johnson295189b2012-06-20 16:38:30 -070018201 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
18202 {
18203 // we do not want to necessarily report the current speed
18204 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
18205 {
18206 // report the max possible speed
18207 rssidx = 0;
18208 }
18209 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
18210 {
18211 // report the max possible speed with RSSI scaling
18212 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
18213 {
18214 // report the max possible speed
18215 rssidx = 0;
18216 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018217 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070018218 {
18219 // report middle speed
18220 rssidx = 1;
18221 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018222 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
18223 {
18224 // report middle speed
18225 rssidx = 2;
18226 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018227 else
18228 {
18229 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018230 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070018231 }
18232 }
18233 else
18234 {
18235 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
18236 hddLog(VOS_TRACE_LEVEL_ERROR,
18237 "%s: Invalid value for reportMaxLinkSpeed: %u",
18238 __func__, pCfg->reportMaxLinkSpeed);
18239 rssidx = 0;
18240 }
18241
18242 maxRate = 0;
18243
18244 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018245 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
18246 OperationalRates, &ORLeng))
18247 {
18248 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18249 /*To keep GUI happy*/
18250 return 0;
18251 }
18252
Jeff Johnson295189b2012-06-20 16:38:30 -070018253 for (i = 0; i < ORLeng; i++)
18254 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018255 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018256 {
18257 /* Validate Rate Set */
18258 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
18259 {
18260 currentRate = supported_data_rate[j].supported_rate[rssidx];
18261 break;
18262 }
18263 }
18264 /* Update MAX rate */
18265 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18266 }
18267
18268 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018269 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
18270 ExtendedRates, &ERLeng))
18271 {
18272 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18273 /*To keep GUI happy*/
18274 return 0;
18275 }
18276
Jeff Johnson295189b2012-06-20 16:38:30 -070018277 for (i = 0; i < ERLeng; i++)
18278 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018279 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018280 {
18281 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
18282 {
18283 currentRate = supported_data_rate[j].supported_rate[rssidx];
18284 break;
18285 }
18286 }
18287 /* Update MAX rate */
18288 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18289 }
c_hpothu79aab322014-07-14 21:11:01 +053018290
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018291 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053018292 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018293 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053018294 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070018295 {
c_hpothu79aab322014-07-14 21:11:01 +053018296 if (rate_flags & eHAL_TX_RATE_VHT80)
18297 mode = 2;
18298 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
18299 mode = 1;
18300 else
18301 mode = 0;
18302
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018303 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
18304 MCSRates, &MCSLeng))
18305 {
18306 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18307 /*To keep GUI happy*/
18308 return 0;
18309 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018310 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070018311#ifdef WLAN_FEATURE_11AC
18312 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018313 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070018314 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018315 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018316 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070018317 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070018318 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018319 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018320 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018321 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070018322 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018323 maxMCSIdx = 7;
18324 }
18325 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
18326 {
18327 maxMCSIdx = 8;
18328 }
18329 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
18330 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018331 //VHT20 is supporting 0~8
18332 if (rate_flags & eHAL_TX_RATE_VHT20)
18333 maxMCSIdx = 8;
18334 else
18335 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070018336 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018337
c_hpothu79aab322014-07-14 21:11:01 +053018338 if (0 != rssidx)/*check for scaled */
18339 {
18340 //get middle rate MCS index if rssi=1/2
18341 for (i=0; i <= maxMCSIdx; i++)
18342 {
18343 if (sinfo->signal <= rssiMcsTbl[mode][i])
18344 {
18345 maxMCSIdx = i;
18346 break;
18347 }
18348 }
18349 }
18350
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018351 if (rate_flags & eHAL_TX_RATE_VHT80)
18352 {
18353 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
18354 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
18355 }
18356 else if (rate_flags & eHAL_TX_RATE_VHT40)
18357 {
18358 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
18359 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
18360 }
18361 else if (rate_flags & eHAL_TX_RATE_VHT20)
18362 {
18363 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
18364 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
18365 }
18366
Leo Chang6f8870f2013-03-26 18:11:36 -070018367 maxSpeedMCS = 1;
18368 if (currentRate > maxRate)
18369 {
18370 maxRate = currentRate;
18371 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018372
Leo Chang6f8870f2013-03-26 18:11:36 -070018373 }
18374 else
18375#endif /* WLAN_FEATURE_11AC */
18376 {
18377 if (rate_flags & eHAL_TX_RATE_HT40)
18378 {
18379 rateFlag |= 1;
18380 }
18381 if (rate_flags & eHAL_TX_RATE_SGI)
18382 {
18383 rateFlag |= 2;
18384 }
18385
Girish Gowli01abcee2014-07-31 20:18:55 +053018386 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053018387 if (rssidx == 1 || rssidx == 2)
18388 {
18389 //get middle rate MCS index if rssi=1/2
18390 for (i=0; i <= 7; i++)
18391 {
18392 if (sinfo->signal <= rssiMcsTbl[mode][i])
18393 {
18394 temp = i+1;
18395 break;
18396 }
18397 }
18398 }
c_hpothu79aab322014-07-14 21:11:01 +053018399
18400 for (i = 0; i < MCSLeng; i++)
18401 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018402 for (j = 0; j < temp; j++)
18403 {
18404 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
18405 {
18406 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018407 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018408 break;
18409 }
18410 }
18411 if ((j < temp) && (currentRate > maxRate))
18412 {
18413 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070018414 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018415 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018416 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018417 }
18418 }
18419
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018420 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
18421 {
18422 maxRate = myRate;
18423 maxSpeedMCS = 1;
18424 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18425 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018426 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053018427 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070018428 {
18429 maxRate = myRate;
18430 if (rate_flags & eHAL_TX_RATE_LEGACY)
18431 {
18432 maxSpeedMCS = 0;
18433 }
18434 else
18435 {
18436 maxSpeedMCS = 1;
18437 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18438 }
18439 }
18440
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018441 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070018442 {
18443 sinfo->txrate.legacy = maxRate;
18444#ifdef LINKSPEED_DEBUG_ENABLED
18445 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
18446#endif //LINKSPEED_DEBUG_ENABLED
18447 }
18448 else
18449 {
18450 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070018451#ifdef WLAN_FEATURE_11AC
18452 sinfo->txrate.nss = 1;
18453 if (rate_flags & eHAL_TX_RATE_VHT80)
18454 {
18455 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018456#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18457 defined(WITH_BACKPORTS)
18458 sinfo->txrate.bw = RATE_INFO_BW_80;
18459#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018460 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018461#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018462 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018463 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070018464 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018465 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018466#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18467 defined(WITH_BACKPORTS)
18468 sinfo->txrate.bw = RATE_INFO_BW_40;
18469#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018470 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018471#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018472 }
18473 else if (rate_flags & eHAL_TX_RATE_VHT20)
18474 {
18475 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18476 }
18477#endif /* WLAN_FEATURE_11AC */
18478 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
18479 {
18480 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18481 if (rate_flags & eHAL_TX_RATE_HT40)
18482 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018483#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18484 defined(WITH_BACKPORTS)
18485 sinfo->txrate.bw = RATE_INFO_BW_40;
18486#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018487 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018488#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018489 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018490 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018491 if (rate_flags & eHAL_TX_RATE_SGI)
18492 {
18493 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18494 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018495
Jeff Johnson295189b2012-06-20 16:38:30 -070018496#ifdef LINKSPEED_DEBUG_ENABLED
18497 pr_info("Reporting MCS rate %d flags %x\n",
18498 sinfo->txrate.mcs,
18499 sinfo->txrate.flags );
18500#endif //LINKSPEED_DEBUG_ENABLED
18501 }
18502 }
18503 else
18504 {
18505 // report current rate instead of max rate
18506
18507 if (rate_flags & eHAL_TX_RATE_LEGACY)
18508 {
18509 //provide to the UI in units of 100kbps
18510 sinfo->txrate.legacy = myRate;
18511#ifdef LINKSPEED_DEBUG_ENABLED
18512 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
18513#endif //LINKSPEED_DEBUG_ENABLED
18514 }
18515 else
18516 {
18517 //must be MCS
18518 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018519#ifdef WLAN_FEATURE_11AC
18520 sinfo->txrate.nss = 1;
18521 if (rate_flags & eHAL_TX_RATE_VHT80)
18522 {
18523 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18524 }
18525 else
18526#endif /* WLAN_FEATURE_11AC */
18527 {
18528 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18529 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018530 if (rate_flags & eHAL_TX_RATE_SGI)
18531 {
18532 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18533 }
18534 if (rate_flags & eHAL_TX_RATE_HT40)
18535 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018536#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18537 defined(WITH_BACKPORTS)
18538 sinfo->txrate.bw = RATE_INFO_BW_40;
18539#else
Jeff Johnson295189b2012-06-20 16:38:30 -070018540 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018541#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018542 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018543#ifdef WLAN_FEATURE_11AC
18544 else if (rate_flags & eHAL_TX_RATE_VHT80)
18545 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018546#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18547 defined(WITH_BACKPORTS)
18548 sinfo->txrate.bw = RATE_INFO_BW_80;
18549#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018550 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018551#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018552 }
18553#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018554#ifdef LINKSPEED_DEBUG_ENABLED
18555 pr_info("Reporting actual MCS rate %d flags %x\n",
18556 sinfo->txrate.mcs,
18557 sinfo->txrate.flags );
18558#endif //LINKSPEED_DEBUG_ENABLED
18559 }
18560 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018561
18562#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18563 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018564 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018565#else
18566 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18567#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018568
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018569 sinfo->tx_packets =
18570 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18571 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18572 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18573 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18574
18575 sinfo->tx_retries =
18576 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18577 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18578 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18579 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18580
18581 sinfo->tx_failed =
18582 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18583 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18584 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18585 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18586
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018587#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18588 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018589 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018590 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018591 STATION_INFO_TX_PACKETS |
18592 STATION_INFO_TX_RETRIES |
18593 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018594#else
18595 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18596 BIT(NL80211_STA_INFO_TX_PACKETS) |
18597 BIT(NL80211_STA_INFO_TX_RETRIES) |
18598 BIT(NL80211_STA_INFO_TX_FAILED);
18599#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018600
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018601 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018602
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018603 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18604 &sinfo->txrate, sizeof(sinfo->txrate));
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018605 vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate,
18606 &sinfo->txrate, sizeof(sinfo->txrate));
18607
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018608 if (rate_flags & eHAL_TX_RATE_LEGACY)
18609 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18610 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18611 sinfo->rx_packets);
18612 else
18613 hddLog(LOG1,
18614 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18615 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18616 sinfo->tx_packets, sinfo->rx_packets);
18617
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018618 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18619 TRACE_CODE_HDD_CFG80211_GET_STA,
18620 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018621 EXIT();
18622 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018623}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018624#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18625static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18626 const u8* mac, struct station_info *sinfo)
18627#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018628static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18629 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018630#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018631{
18632 int ret;
18633
18634 vos_ssr_protect(__func__);
18635 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18636 vos_ssr_unprotect(__func__);
18637
18638 return ret;
18639}
18640
18641static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018642 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018643{
18644 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018645 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018646 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018647 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018648
Jeff Johnsone7245742012-09-05 17:12:55 -070018649 ENTER();
18650
Jeff Johnson295189b2012-06-20 16:38:30 -070018651 if (NULL == pAdapter)
18652 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018653 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018654 return -ENODEV;
18655 }
18656
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018657 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18658 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18659 pAdapter->sessionId, timeout));
18660
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018661 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018662 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018663 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018664 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018665 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018666 }
18667
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018668 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
18669 (TRUE == pHddCtx->hdd_wlan_suspended) &&
18670 (pHddCtx->cfg_ini->fhostArpOffload) &&
18671 (eConnectionState_Associated ==
18672 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
18673 {
Amar Singhald53568e2013-09-26 11:03:45 -070018674
18675 hddLog(VOS_TRACE_LEVEL_INFO,
18676 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053018677 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018678 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18679 {
18680 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018681 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018682 __func__, vos_status);
18683 }
18684 }
18685
Jeff Johnson295189b2012-06-20 16:38:30 -070018686 /**The get power cmd from the supplicant gets updated by the nl only
18687 *on successful execution of the function call
18688 *we are oppositely mapped w.r.t mode in the driver
18689 **/
18690 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
18691
18692 if (VOS_STATUS_E_FAILURE == vos_status)
18693 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018694 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18695 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018696 return -EINVAL;
18697 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018698 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018699 return 0;
18700}
18701
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018702static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
18703 struct net_device *dev, bool mode, int timeout)
18704{
18705 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018706
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018707 vos_ssr_protect(__func__);
18708 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
18709 vos_ssr_unprotect(__func__);
18710
18711 return ret;
18712}
Sushant Kaushik084f6592015-09-10 13:11:56 +053018713
Jeff Johnson295189b2012-06-20 16:38:30 -070018714#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018715static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
18716 struct net_device *netdev,
18717 u8 key_index)
18718{
18719 ENTER();
18720 return 0;
18721}
18722
Jeff Johnson295189b2012-06-20 16:38:30 -070018723static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018724 struct net_device *netdev,
18725 u8 key_index)
18726{
18727 int ret;
18728 vos_ssr_protect(__func__);
18729 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
18730 vos_ssr_unprotect(__func__);
18731 return ret;
18732}
18733#endif //LINUX_VERSION_CODE
18734
18735#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18736static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18737 struct net_device *dev,
18738 struct ieee80211_txq_params *params)
18739{
18740 ENTER();
18741 return 0;
18742}
18743#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18744static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18745 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018746{
Jeff Johnsone7245742012-09-05 17:12:55 -070018747 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070018748 return 0;
18749}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018750#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070018751
18752#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18753static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018754 struct net_device *dev,
18755 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018756{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018757 int ret;
18758
18759 vos_ssr_protect(__func__);
18760 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
18761 vos_ssr_unprotect(__func__);
18762 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018763}
18764#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18765static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
18766 struct ieee80211_txq_params *params)
18767{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018768 int ret;
18769
18770 vos_ssr_protect(__func__);
18771 ret = __wlan_hdd_set_txq_params(wiphy, params);
18772 vos_ssr_unprotect(__func__);
18773 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018774}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018775#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018776
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018777static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018778 struct net_device *dev,
18779 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070018780{
18781 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018782 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018783 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018784 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018785 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018786 v_CONTEXT_t pVosContext = NULL;
18787 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018788
Jeff Johnsone7245742012-09-05 17:12:55 -070018789 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018790
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018791 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070018792 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018793 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018794 return -EINVAL;
18795 }
18796
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018797 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18798 TRACE_CODE_HDD_CFG80211_DEL_STA,
18799 pAdapter->sessionId, pAdapter->device_mode));
18800
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018801 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18802 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018803 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018804 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018805 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018806 }
18807
Jeff Johnson295189b2012-06-20 16:38:30 -070018808 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018809 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018810 )
18811 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018812 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
18813 pSapCtx = VOS_GET_SAP_CB(pVosContext);
18814 if(pSapCtx == NULL){
18815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18816 FL("psapCtx is NULL"));
18817 return -ENOENT;
18818 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053018819 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
18820 {
18821 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
18822 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
18823 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
18824 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018825 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070018826 {
18827 v_U16_t i;
18828 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
18829 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018830 if ((pSapCtx->aStaInfo[i].isUsed) &&
18831 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070018832 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018833 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018834 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018835 ETHER_ADDR_LEN);
18836
Jeff Johnson295189b2012-06-20 16:38:30 -070018837 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018838 "%s: Delete STA with MAC::"
18839 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018840 __func__,
18841 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18842 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018843 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018844 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018845 }
18846 }
18847 }
18848 else
18849 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018850
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018851 vos_status = hdd_softap_GetStaId(pAdapter,
18852 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018853 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18854 {
18855 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018856 "%s: Skip this DEL STA as this is not used::"
18857 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018858 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018859 return -ENOENT;
18860 }
18861
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018862 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018863 {
18864 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018865 "%s: Skip this DEL STA as deauth is in progress::"
18866 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018867 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018868 return -ENOENT;
18869 }
18870
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018871 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018872
Jeff Johnson295189b2012-06-20 16:38:30 -070018873 hddLog(VOS_TRACE_LEVEL_INFO,
18874 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018875 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018876 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018877 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018878
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018879 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018880 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18881 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018882 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018883 hddLog(VOS_TRACE_LEVEL_INFO,
18884 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018885 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018886 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018887 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018888 return -ENOENT;
18889 }
18890
Jeff Johnson295189b2012-06-20 16:38:30 -070018891 }
18892 }
18893
18894 EXIT();
18895
18896 return 0;
18897}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018898
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018899#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018900int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018901 struct net_device *dev,
18902 struct station_del_parameters *param)
18903#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018904#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018905int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018906 struct net_device *dev, const u8 *mac)
18907#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018908int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018909 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018910#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018911#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018912{
18913 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018914 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018915
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018916 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018917
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018918#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018919 if (NULL == param) {
18920 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018921 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018922 return -EINVAL;
18923 }
18924
18925 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
18926 param->subtype, &delStaParams);
18927
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018928#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053018929 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018930 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018931#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018932 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
18933
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018934 vos_ssr_unprotect(__func__);
18935
18936 return ret;
18937}
18938
18939static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018940 struct net_device *dev,
18941#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18942 const u8 *mac,
18943#else
18944 u8 *mac,
18945#endif
18946 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018947{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018948 hdd_adapter_t *pAdapter;
18949 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018950 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018951#ifdef FEATURE_WLAN_TDLS
18952 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018953
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018954 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018955
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018956 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18957 if (NULL == pAdapter)
18958 {
18959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18960 "%s: Adapter is NULL",__func__);
18961 return -EINVAL;
18962 }
18963 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18964 status = wlan_hdd_validate_context(pHddCtx);
18965 if (0 != status)
18966 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018967 return status;
18968 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018969
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018970 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18971 TRACE_CODE_HDD_CFG80211_ADD_STA,
18972 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018973 mask = params->sta_flags_mask;
18974
18975 set = params->sta_flags_set;
18976
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018977 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018978 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
18979 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018980
18981 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
18982 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080018983 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018984 }
18985 }
18986#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018987 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018988 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018989}
18990
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018991#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18992static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18993 struct net_device *dev, const u8 *mac,
18994 struct station_parameters *params)
18995#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018996static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18997 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018998#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018999{
19000 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019001
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019002 vos_ssr_protect(__func__);
19003 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
19004 vos_ssr_unprotect(__func__);
19005
19006 return ret;
19007}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019008#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070019009
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019010static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070019011 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019012{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019013 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19014 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019015 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019016 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019017 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019018 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070019019
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019020 ENTER();
19021
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019022 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019023 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019024 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019025 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019026 return -EINVAL;
19027 }
19028
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019029 if (!pmksa) {
19030 hddLog(LOGE, FL("pmksa is NULL"));
19031 return -EINVAL;
19032 }
19033
19034 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070019035 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019036 pmksa->bssid, pmksa->pmkid);
19037 return -EINVAL;
19038 }
19039
19040 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
19041 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19042
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019043 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19044 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019045 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019046 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019047 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019048 }
19049
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019050 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019051 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19052
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019053 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
19054 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019055
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019056 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019057 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019058 &pmk_id, 1, FALSE);
19059
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019060 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19061 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
19062 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019063
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019064 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019065 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019066}
19067
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019068static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
19069 struct cfg80211_pmksa *pmksa)
19070{
19071 int ret;
19072
19073 vos_ssr_protect(__func__);
19074 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
19075 vos_ssr_unprotect(__func__);
19076
19077 return ret;
19078}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019079
Wilson Yang6507c4e2013-10-01 20:11:19 -070019080
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019081static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070019082 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019083{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019084 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19085 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019086 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019087 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019088
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019089 ENTER();
19090
Wilson Yang6507c4e2013-10-01 20:11:19 -070019091 /* Validate pAdapter */
19092 if (NULL == pAdapter)
19093 {
19094 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
19095 return -EINVAL;
19096 }
19097
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019098 if (!pmksa) {
19099 hddLog(LOGE, FL("pmksa is NULL"));
19100 return -EINVAL;
19101 }
19102
19103 if (!pmksa->bssid) {
19104 hddLog(LOGE, FL("pmksa->bssid is NULL"));
19105 return -EINVAL;
19106 }
19107
Kiet Lam98c46a12014-10-31 15:34:57 -070019108 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
19109 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19110
Wilson Yang6507c4e2013-10-01 20:11:19 -070019111 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19112 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019113 if (0 != status)
19114 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019115 return status;
19116 }
19117
19118 /*Retrieve halHandle*/
19119 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19120
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019121 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19122 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
19123 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019124 /* Delete the PMKID CSR cache */
19125 if (eHAL_STATUS_SUCCESS !=
19126 sme_RoamDelPMKIDfromCache(halHandle,
19127 pAdapter->sessionId, pmksa->bssid, FALSE)) {
19128 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
19129 MAC_ADDR_ARRAY(pmksa->bssid));
19130 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019131 }
19132
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019133 EXIT();
19134 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019135}
19136
Wilson Yang6507c4e2013-10-01 20:11:19 -070019137
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019138static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
19139 struct cfg80211_pmksa *pmksa)
19140{
19141 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019142
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019143 vos_ssr_protect(__func__);
19144 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
19145 vos_ssr_unprotect(__func__);
19146
19147 return ret;
19148
19149}
19150
19151static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019152{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019153 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19154 tHalHandle halHandle;
19155 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019156 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019157
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019158 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070019159
19160 /* Validate pAdapter */
19161 if (NULL == pAdapter)
19162 {
19163 hddLog(VOS_TRACE_LEVEL_ERROR,
19164 "%s: Invalid Adapter" ,__func__);
19165 return -EINVAL;
19166 }
19167
19168 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19169 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019170 if (0 != status)
19171 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019172 return status;
19173 }
19174
19175 /*Retrieve halHandle*/
19176 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19177
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019178 /* Flush the PMKID cache in CSR */
19179 if (eHAL_STATUS_SUCCESS !=
19180 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
19181 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
19182 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019183 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019184 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080019185 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019186}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019187
19188static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
19189{
19190 int ret;
19191
19192 vos_ssr_protect(__func__);
19193 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
19194 vos_ssr_unprotect(__func__);
19195
19196 return ret;
19197}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019198#endif
19199
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019200#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019201static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19202 struct net_device *dev,
19203 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019204{
19205 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19206 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019207 hdd_context_t *pHddCtx;
19208 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019209
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019210 ENTER();
19211
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019212 if (NULL == pAdapter)
19213 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019214 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019215 return -ENODEV;
19216 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019217 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19218 ret = wlan_hdd_validate_context(pHddCtx);
19219 if (0 != ret)
19220 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019221 return ret;
19222 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019223 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019224 if (NULL == pHddStaCtx)
19225 {
19226 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
19227 return -EINVAL;
19228 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019229
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019230 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19231 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
19232 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019233 // Added for debug on reception of Re-assoc Req.
19234 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
19235 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019236 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019237 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080019238 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019239 }
19240
19241#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080019242 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019243 ftie->ie_len);
19244#endif
19245
19246 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053019247 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
19248 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019249 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019250
19251 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019252 return 0;
19253}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019254
19255static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19256 struct net_device *dev,
19257 struct cfg80211_update_ft_ies_params *ftie)
19258{
19259 int ret;
19260
19261 vos_ssr_protect(__func__);
19262 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
19263 vos_ssr_unprotect(__func__);
19264
19265 return ret;
19266}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019267#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019268
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019269#ifdef FEATURE_WLAN_SCAN_PNO
19270
19271void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
19272 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
19273{
19274 int ret;
19275 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
19276 hdd_context_t *pHddCtx;
19277
Nirav Shah80830bf2013-12-31 16:35:12 +053019278 ENTER();
19279
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019280 if (NULL == pAdapter)
19281 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019283 "%s: HDD adapter is Null", __func__);
19284 return ;
19285 }
19286
19287 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19288 if (NULL == pHddCtx)
19289 {
19290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19291 "%s: HDD context is Null!!!", __func__);
19292 return ;
19293 }
19294
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019295 spin_lock(&pHddCtx->schedScan_lock);
19296 if (TRUE == pHddCtx->isWiphySuspended)
19297 {
19298 pHddCtx->isSchedScanUpdatePending = TRUE;
19299 spin_unlock(&pHddCtx->schedScan_lock);
19300 hddLog(VOS_TRACE_LEVEL_INFO,
19301 "%s: Update cfg80211 scan database after it resume", __func__);
19302 return ;
19303 }
19304 spin_unlock(&pHddCtx->schedScan_lock);
19305
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019306 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
19307
19308 if (0 > ret)
19309 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053019310 else
19311 {
19312 /* Acquire wakelock to handle the case where APP's tries to suspend
19313 * immediatly after the driver gets connect request(i.e after pno)
19314 * from supplicant, this result in app's is suspending and not able
19315 * to process the connect request to AP */
19316 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
19317 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019318 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019319 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19320 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019321}
19322
19323/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019324 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019325 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019326 */
19327static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
19328{
19329 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
19330 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019331 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019332 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19333 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053019334
19335 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
19336 {
19337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19338 "%s: PNO is allowed only in STA interface", __func__);
19339 return eHAL_STATUS_FAILURE;
19340 }
19341
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019342 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
19343
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019344 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053019345 * active sessions. PNO is allowed only in case when sap session
19346 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019347 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019348 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
19349 {
19350 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019351 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019352
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019353 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
19354 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
19355 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
19356 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053019357 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
19358 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053019359 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019360 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019361 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019362 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019363 }
19364 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19365 pAdapterNode = pNext;
19366 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019367 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019368}
19369
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019370void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
19371{
19372 hdd_adapter_t *pAdapter = callbackContext;
19373 hdd_context_t *pHddCtx;
19374
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019375 ENTER();
19376
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019377 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
19378 {
19379 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19380 FL("Invalid adapter or adapter has invalid magic"));
19381 return;
19382 }
19383
19384 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19385 if (0 != wlan_hdd_validate_context(pHddCtx))
19386 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019387 return;
19388 }
19389
c_hpothub53c45d2014-08-18 16:53:14 +053019390 if (VOS_STATUS_SUCCESS != status)
19391 {
19392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019393 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053019394 pHddCtx->isPnoEnable = FALSE;
19395 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019396
19397 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
19398 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019399 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019400}
19401
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019402#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
19403 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
19404/**
19405 * hdd_config_sched_scan_plan() - configures the sched scan plans
19406 * from the framework.
19407 * @pno_req: pointer to PNO scan request
19408 * @request: pointer to scan request from framework
19409 *
19410 * Return: None
19411 */
19412static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
19413 struct cfg80211_sched_scan_request *request,
19414 hdd_context_t *hdd_ctx)
19415{
19416 v_U32_t i = 0;
19417
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019418 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019419 for (i = 0; i < request->n_scan_plans; i++)
19420 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019421 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
19422 request->scan_plans[i].iterations;
19423 pno_req->scanTimers.aTimerValues[i].uTimerValue =
19424 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019425 }
19426}
19427#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019428static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019429 struct cfg80211_sched_scan_request *request,
19430 hdd_context_t *hdd_ctx)
19431{
19432 v_U32_t i, temp_int;
19433 /* Driver gets only one time interval which is hardcoded in
19434 * supplicant for 10000ms. Taking power consumption into account 6
19435 * timers will be used, Timervalue is increased exponentially
19436 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
19437 * timer is configurable through INI param gPNOScanTimerRepeatValue.
19438 * If it is set to 0 only one timer will be used and PNO scan cycle
19439 * will be repeated after each interval specified by supplicant
19440 * till PNO is disabled.
19441 */
19442 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019443 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019444 HDD_PNO_SCAN_TIMERS_SET_ONE;
19445 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019446 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019447 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
19448
19449 temp_int = (request->interval)/1000;
19450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19451 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
19452 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019453 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019454 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019455 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019456 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019457 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019458 temp_int *= 2;
19459 }
19460 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019461 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019462}
19463#endif
19464
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019465/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019466 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
19467 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019468 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019469static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019470 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19471{
19472 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019473 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019474 hdd_context_t *pHddCtx;
19475 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019476 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053019477 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
19478 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019479 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
19480 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019481 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019482 hdd_config_t *pConfig = NULL;
19483 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019484
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019485 ENTER();
19486
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019487 if (NULL == pAdapter)
19488 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019489 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019490 "%s: HDD adapter is Null", __func__);
19491 return -ENODEV;
19492 }
19493
19494 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019495 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019496
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019497 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019498 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019499 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019500 }
19501
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019502 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019503 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19504 if (NULL == hHal)
19505 {
19506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19507 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019508 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019509 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019510 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19511 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
19512 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019513 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053019514 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019515 {
19516 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19517 "%s: aborting the existing scan is unsuccessfull", __func__);
19518 return -EBUSY;
19519 }
19520
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019521 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019522 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019524 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019525 return -EBUSY;
19526 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019527
c_hpothu37f21312014-04-09 21:49:54 +053019528 if (TRUE == pHddCtx->isPnoEnable)
19529 {
19530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19531 FL("already PNO is enabled"));
19532 return -EBUSY;
19533 }
c_hpothu225aa7c2014-10-22 17:45:13 +053019534
19535 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
19536 {
19537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19538 "%s: abort ROC failed ", __func__);
19539 return -EBUSY;
19540 }
19541
c_hpothu37f21312014-04-09 21:49:54 +053019542 pHddCtx->isPnoEnable = TRUE;
19543
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019544 pnoRequest.enable = 1; /*Enable PNO */
19545 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019546
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019547 if (( !pnoRequest.ucNetworksCount ) ||
19548 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019549 {
19550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019551 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019552 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019553 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019554 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019555 goto error;
19556 }
19557
19558 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
19559 {
19560 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019561 "%s: Incorrect number of channels %d",
19562 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019563 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019564 goto error;
19565 }
19566
19567 /* Framework provides one set of channels(all)
19568 * common for all saved profile */
19569 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
19570 channels_allowed, &num_channels_allowed))
19571 {
19572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19573 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019574 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019575 goto error;
19576 }
19577 /* Checking each channel against allowed channel list */
19578 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053019579 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019580 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019581 char chList [(request->n_channels*5)+1];
19582 int len;
19583 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019584 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019585 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019586 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019587 if (request->channels[i]->hw_value == channels_allowed[indx])
19588 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019589 if ((!pConfig->enableDFSPnoChnlScan) &&
19590 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
19591 {
19592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19593 "%s : Dropping DFS channel : %d",
19594 __func__,channels_allowed[indx]);
19595 num_ignore_dfs_ch++;
19596 break;
19597 }
19598
Nirav Shah80830bf2013-12-31 16:35:12 +053019599 valid_ch[num_ch++] = request->channels[i]->hw_value;
19600 len += snprintf(chList+len, 5, "%d ",
19601 request->channels[i]->hw_value);
19602 break ;
19603 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019604 }
19605 }
Nirav Shah80830bf2013-12-31 16:35:12 +053019606 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019607
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019608 /*If all channels are DFS and dropped, then ignore the PNO request*/
19609 if (num_ignore_dfs_ch == request->n_channels)
19610 {
19611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19612 "%s : All requested channels are DFS channels", __func__);
19613 ret = -EINVAL;
19614 goto error;
19615 }
19616 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019617
19618 pnoRequest.aNetworks =
19619 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19620 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019621 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019622 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19623 FL("failed to allocate memory aNetworks %u"),
19624 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19625 goto error;
19626 }
19627 vos_mem_zero(pnoRequest.aNetworks,
19628 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19629
19630 /* Filling per profile params */
19631 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
19632 {
19633 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019634 request->match_sets[i].ssid.ssid_len;
19635
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019636 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
19637 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019638 {
19639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019640 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019641 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019642 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019643 goto error;
19644 }
19645
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019646 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019647 request->match_sets[i].ssid.ssid,
19648 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19650 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019651 i, pnoRequest.aNetworks[i].ssId.ssId);
19652 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
19653 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
19654 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019655
19656 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019657 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
19658 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019659
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019660 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019661 }
19662
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019663 for (i = 0; i < request->n_ssids; i++)
19664 {
19665 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019666 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019667 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019668 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019669 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019670 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019671 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019672 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019673 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019674 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019675 break;
19676 }
19677 j++;
19678 }
19679 }
19680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19681 "Number of hidden networks being Configured = %d",
19682 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080019684 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019685
19686 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19687 if (pnoRequest.p24GProbeTemplate == NULL)
19688 {
19689 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19690 FL("failed to allocate memory p24GProbeTemplate %u"),
19691 SIR_PNO_MAX_PB_REQ_SIZE);
19692 goto error;
19693 }
19694
19695 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19696 if (pnoRequest.p5GProbeTemplate == NULL)
19697 {
19698 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19699 FL("failed to allocate memory p5GProbeTemplate %u"),
19700 SIR_PNO_MAX_PB_REQ_SIZE);
19701 goto error;
19702 }
19703
19704 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19705 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19706
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053019707 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
19708 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019709 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019710 pnoRequest.us24GProbeTemplateLen = request->ie_len;
19711 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
19712 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019713
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019714 pnoRequest.us5GProbeTemplateLen = request->ie_len;
19715 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
19716 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019717 }
19718
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019719 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053019720
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019721 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019722
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019723 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019724 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19725 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019726 pAdapter->pno_req_status = 0;
19727
Nirav Shah80830bf2013-12-31 16:35:12 +053019728 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19729 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019730 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
19731 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053019732
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019733 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019734 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019735 hdd_cfg80211_sched_scan_done_callback, pAdapter);
19736 if (eHAL_STATUS_SUCCESS != status)
19737 {
19738 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019739 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019740 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019741 goto error;
19742 }
19743
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019744 ret = wait_for_completion_timeout(
19745 &pAdapter->pno_comp_var,
19746 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19747 if (0 >= ret)
19748 {
19749 // Did not receive the response for PNO enable in time.
19750 // Assuming the PNO enable was success.
19751 // Returning error from here, because we timeout, results
19752 // in side effect of Wifi (Wifi Setting) not to work.
19753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19754 FL("Timed out waiting for PNO to be Enabled"));
19755 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019756 }
19757
19758 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053019759 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019760
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019761error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19763 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053019764 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019765 if (pnoRequest.aNetworks)
19766 vos_mem_free(pnoRequest.aNetworks);
19767 if (pnoRequest.p24GProbeTemplate)
19768 vos_mem_free(pnoRequest.p24GProbeTemplate);
19769 if (pnoRequest.p5GProbeTemplate)
19770 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019771
19772 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019773 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019774}
19775
19776/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019777 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
19778 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019779 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019780static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
19781 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19782{
19783 int ret;
19784
19785 vos_ssr_protect(__func__);
19786 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
19787 vos_ssr_unprotect(__func__);
19788
19789 return ret;
19790}
19791
19792/*
19793 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
19794 * Function to disable PNO
19795 */
19796static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019797 struct net_device *dev)
19798{
19799 eHalStatus status = eHAL_STATUS_FAILURE;
19800 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19801 hdd_context_t *pHddCtx;
19802 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019803 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019804 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019805
19806 ENTER();
19807
19808 if (NULL == pAdapter)
19809 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019811 "%s: HDD adapter is Null", __func__);
19812 return -ENODEV;
19813 }
19814
19815 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019816
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019817 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019818 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019820 "%s: HDD context is Null", __func__);
19821 return -ENODEV;
19822 }
19823
19824 /* The return 0 is intentional when isLogpInProgress and
19825 * isLoadUnloadInProgress. We did observe a crash due to a return of
19826 * failure in sched_scan_stop , especially for a case where the unload
19827 * of the happens at the same time. The function __cfg80211_stop_sched_scan
19828 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
19829 * success. If it returns a failure , then its next invocation due to the
19830 * clean up of the second interface will have the dev pointer corresponding
19831 * to the first one leading to a crash.
19832 */
19833 if (pHddCtx->isLogpInProgress)
19834 {
19835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19836 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019837 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019838 return ret;
19839 }
19840
Mihir Shete18156292014-03-11 15:38:30 +053019841 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019842 {
19843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19844 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19845 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019846 }
19847
19848 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19849 if (NULL == hHal)
19850 {
19851 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19852 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019853 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019854 }
19855
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019856 pnoRequest.enable = 0; /* Disable PNO */
19857 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019858
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019859 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19860 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19861 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019862
19863 INIT_COMPLETION(pAdapter->pno_comp_var);
19864 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19865 pnoRequest.callbackContext = pAdapter;
19866 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019867 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019868 pAdapter->sessionId,
19869 NULL, pAdapter);
19870 if (eHAL_STATUS_SUCCESS != status)
19871 {
19872 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19873 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019874 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019875 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019876 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019877 ret = wait_for_completion_timeout(
19878 &pAdapter->pno_comp_var,
19879 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19880 if (0 >= ret)
19881 {
19882 // Did not receive the response for PNO disable in time.
19883 // Assuming the PNO disable was success.
19884 // Returning error from here, because we timeout, results
19885 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019887 FL("Timed out waiting for PNO to be disabled"));
19888 ret = 0;
19889 }
19890
19891 ret = pAdapter->pno_req_status;
19892 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019893
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019894error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019895 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019896 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019897
19898 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019899 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019900}
19901
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019902/*
19903 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19904 * NL interface to disable PNO
19905 */
19906static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19907 struct net_device *dev)
19908{
19909 int ret;
19910
19911 vos_ssr_protect(__func__);
19912 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19913 vos_ssr_unprotect(__func__);
19914
19915 return ret;
19916}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019917#endif /*FEATURE_WLAN_SCAN_PNO*/
19918
19919
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019920#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019921#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019922static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19923 struct net_device *dev,
19924 u8 *peer, u8 action_code,
19925 u8 dialog_token,
19926 u16 status_code, u32 peer_capability,
19927 const u8 *buf, size_t len)
19928#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019929#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
19930 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019931static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19932 struct net_device *dev,
19933 const u8 *peer, u8 action_code,
19934 u8 dialog_token, u16 status_code,
19935 u32 peer_capability, bool initiator,
19936 const u8 *buf, size_t len)
19937#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19938static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19939 struct net_device *dev,
19940 const u8 *peer, u8 action_code,
19941 u8 dialog_token, u16 status_code,
19942 u32 peer_capability, const u8 *buf,
19943 size_t len)
19944#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19945static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19946 struct net_device *dev,
19947 u8 *peer, u8 action_code,
19948 u8 dialog_token,
19949 u16 status_code, u32 peer_capability,
19950 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019951#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019952static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19953 struct net_device *dev,
19954 u8 *peer, u8 action_code,
19955 u8 dialog_token,
19956 u16 status_code, const u8 *buf,
19957 size_t len)
19958#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019959#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019960{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019961 hdd_adapter_t *pAdapter;
19962 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019963 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070019964 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080019965 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070019966 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019967 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019968 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019969#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019970 u32 peer_capability = 0;
19971#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019972 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019973 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019974 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019975
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019976 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19977 if (NULL == pAdapter)
19978 {
19979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19980 "%s: Adapter is NULL",__func__);
19981 return -EINVAL;
19982 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019983 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19984 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
19985 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019986
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019987 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019988 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019989 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019990 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019991 "Invalid arguments");
19992 return -EINVAL;
19993 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019994
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019995 if (pHddCtx->isLogpInProgress)
19996 {
19997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19998 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053019999 wlan_hdd_tdls_set_link_status(pAdapter,
20000 peer,
20001 eTDLS_LINK_IDLE,
20002 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020003 return -EBUSY;
20004 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020005
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020006 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
20007 {
20008 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20009 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
20010 return -EAGAIN;
20011 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020012
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020013 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
20014 if (!pHddTdlsCtx) {
20015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20016 "%s: pHddTdlsCtx not valid.", __func__);
Hanumanth Reddy Pothula36dfa522018-03-12 16:42:08 +053020017 return -EINVAL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020018 }
20019
Hoonki Lee27511902013-03-14 18:19:06 -070020020 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020021 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020022 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020023 "%s: TDLS mode is disabled OR not enabled in FW."
20024 MAC_ADDRESS_STR " action %d declined.",
20025 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020026 return -ENOTSUPP;
20027 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020028
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020029 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20030
20031 if( NULL == pHddStaCtx )
20032 {
20033 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20034 "%s: HDD station context NULL ",__func__);
20035 return -EINVAL;
20036 }
20037
20038 /* STA should be connected and authenticated
20039 * before sending any TDLS frames
20040 */
20041 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
20042 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
20043 {
20044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20045 "STA is not connected or unauthenticated. "
20046 "connState %u, uIsAuthenticated %u",
20047 pHddStaCtx->conn_info.connState,
20048 pHddStaCtx->conn_info.uIsAuthenticated);
20049 return -EAGAIN;
20050 }
20051
Hoonki Lee27511902013-03-14 18:19:06 -070020052 /* other than teardown frame, other mgmt frames are not sent if disabled */
20053 if (SIR_MAC_TDLS_TEARDOWN != action_code)
20054 {
20055 /* if tdls_mode is disabled to respond to peer's request */
20056 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
20057 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020059 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020060 " TDLS mode is disabled. action %d declined.",
20061 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070020062
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020063 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070020064 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053020065
20066 if (vos_max_concurrent_connections_reached())
20067 {
20068 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
20069 return -EINVAL;
20070 }
Hoonki Lee27511902013-03-14 18:19:06 -070020071 }
20072
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020073 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
20074 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053020075 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020076 {
20077 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020078 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020079 " TDLS setup is ongoing. action %d declined.",
20080 __func__, MAC_ADDR_ARRAY(peer), action_code);
20081 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020082 }
20083 }
20084
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020085 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
20086 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080020087 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020088 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20089 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020090 {
20091 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
20092 we return error code at 'add_station()'. Hence we have this
20093 check again in addtion to add_station().
20094 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020095 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020096 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20098 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020099 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
20100 __func__, MAC_ADDR_ARRAY(peer), action_code,
20101 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053020102 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080020103 }
20104 else
20105 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020106 /* maximum reached. tweak to send error code to peer and return
20107 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020108 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20110 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020111 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
20112 __func__, MAC_ADDR_ARRAY(peer), status_code,
20113 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070020114 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020115 /* fall through to send setup resp with failure status
20116 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020117 }
20118 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020119 else
20120 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020121 mutex_lock(&pHddCtx->tdls_lock);
20122 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020123 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020124 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020125 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020127 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
20128 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020129 return -EPERM;
20130 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020131 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020132 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020133 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020134
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020136 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020137 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
20138 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020139
Hoonki Leea34dd892013-02-05 22:56:02 -080020140 /*Except teardown responder will not be used so just make 0*/
20141 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020142 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080020143 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020144
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020145 mutex_lock(&pHddCtx->tdls_lock);
20146 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020147
20148 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
20149 responder = pTdlsPeer->is_responder;
20150 else
Hoonki Leea34dd892013-02-05 22:56:02 -080020151 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020153 "%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 -070020154 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
20155 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020156 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020157 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080020158 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020159 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020160 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020161
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020162 /* Discard TDLS setup if peer is removed by user app */
20163 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
20164 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20165 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
20166 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
20167
20168 mutex_lock(&pHddCtx->tdls_lock);
20169 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20170 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
20171 mutex_unlock(&pHddCtx->tdls_lock);
20172 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
20173 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
20174 MAC_ADDR_ARRAY(peer), action_code);
20175 return -EINVAL;
20176 }
20177 mutex_unlock(&pHddCtx->tdls_lock);
20178 }
20179
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020180 /* For explicit trigger of DIS_REQ come out of BMPS for
20181 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070020182 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053020183 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020184 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
20185 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070020186 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020187 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020189 "%s: Sending frame action_code %u.Disable BMPS", __func__,
20190 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020191 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
20192 if (status != VOS_STATUS_SUCCESS) {
20193 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020194 } else {
20195 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020196 }
Hoonki Lee14621352013-04-16 17:51:19 -070020197 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020198 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020199 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020200 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
20201 }
20202 }
Hoonki Lee14621352013-04-16 17:51:19 -070020203 }
20204
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020205 /* make sure doesn't call send_mgmt() while it is pending */
20206 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
20207 {
20208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080020209 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020210 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020211 ret = -EBUSY;
20212 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020213 }
20214
20215 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020216 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
20217
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020218 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
20219 pAdapter->sessionId, peer, action_code, dialog_token,
20220 status_code, peer_capability, (tANI_U8 *)buf, len,
20221 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020222
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020223 if (VOS_STATUS_SUCCESS != status)
20224 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020225 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20226 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020227 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020228 ret = -EINVAL;
20229 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020230 }
20231
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020232 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20233 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
20234 WAIT_TIME_TDLS_MGMT);
20235
Hoonki Leed37cbb32013-04-20 00:31:14 -070020236 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
20237 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
20238
20239 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020240 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070020241 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070020242 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070020243 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020244 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080020245
20246 if (pHddCtx->isLogpInProgress)
20247 {
20248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20249 "%s: LOGP in Progress. Ignore!!!", __func__);
20250 return -EAGAIN;
20251 }
Abhishek Singh837adf22015-10-01 17:37:37 +053020252 if (rc <= 0)
20253 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
20254 WLAN_LOG_INDICATOR_HOST_DRIVER,
20255 WLAN_LOG_REASON_HDD_TIME_OUT,
20256 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080020257
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020258 ret = -EINVAL;
20259 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020260 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020261 else
20262 {
20263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20264 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
20265 __func__, rc, pAdapter->mgmtTxCompletionStatus);
20266 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020267
Gopichand Nakkala05922802013-03-14 12:23:19 -070020268 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070020269 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020270 ret = max_sta_failed;
20271 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070020272 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020273
Hoonki Leea34dd892013-02-05 22:56:02 -080020274 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
20275 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020276 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020277 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20278 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020279 }
20280 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
20281 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020282 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020283 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20284 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020285 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020286
20287 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020288
20289tx_failed:
20290 /* add_station will be called before sending TDLS_SETUP_REQ and
20291 * TDLS_SETUP_RSP and as part of add_station driver will enable
20292 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
20293 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
20294 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
20295 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
20296 */
20297
20298 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20299 (SIR_MAC_TDLS_SETUP_RSP == action_code))
20300 wlan_hdd_tdls_check_bmps(pAdapter);
20301 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020302}
20303
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020304#if TDLS_MGMT_VERSION2
20305static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20306 u8 *peer, u8 action_code, u8 dialog_token,
20307 u16 status_code, u32 peer_capability,
20308 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020309#else /* TDLS_MGMT_VERSION2 */
20310#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20311static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20312 struct net_device *dev,
20313 const u8 *peer, u8 action_code,
20314 u8 dialog_token, u16 status_code,
20315 u32 peer_capability, bool initiator,
20316 const u8 *buf, size_t len)
20317#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20318static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20319 struct net_device *dev,
20320 const u8 *peer, u8 action_code,
20321 u8 dialog_token, u16 status_code,
20322 u32 peer_capability, const u8 *buf,
20323 size_t len)
20324#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20325static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20326 struct net_device *dev,
20327 u8 *peer, u8 action_code,
20328 u8 dialog_token,
20329 u16 status_code, u32 peer_capability,
20330 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020331#else
20332static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20333 u8 *peer, u8 action_code, u8 dialog_token,
20334 u16 status_code, const u8 *buf, size_t len)
20335#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020336#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020337{
20338 int ret;
20339
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020340 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020341#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020342 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20343 dialog_token, status_code,
20344 peer_capability, buf, len);
20345#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020346#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20347 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020348 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20349 dialog_token, status_code,
20350 peer_capability, initiator,
20351 buf, len);
20352#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20353 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20354 dialog_token, status_code,
20355 peer_capability, buf, len);
20356#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20357 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20358 dialog_token, status_code,
20359 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020360#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020361 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20362 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020363#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020364#endif
20365 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020366
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020367 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020368}
Atul Mittal115287b2014-07-08 13:26:33 +053020369
20370int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020371#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20372 const u8 *peer,
20373#else
Atul Mittal115287b2014-07-08 13:26:33 +053020374 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020375#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020376 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053020377 cfg80211_exttdls_callback callback)
20378{
20379
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020380 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053020381 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020382 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053020383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20384 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
20385 __func__, MAC_ADDR_ARRAY(peer));
20386
20387 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20388 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20389
20390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020391 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20392 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20393 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020394 return -ENOTSUPP;
20395 }
20396
20397 /* To cater the requirement of establishing the TDLS link
20398 * irrespective of the data traffic , get an entry of TDLS peer.
20399 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020400 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020401 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
20402 if (pTdlsPeer == NULL) {
20403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20404 "%s: peer " MAC_ADDRESS_STR " not existing",
20405 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020406 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020407 return -EINVAL;
20408 }
20409
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020410 /* check FW TDLS Off Channel capability */
20411 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020412 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020413 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020414 {
20415 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
20416 pTdlsPeer->peerParams.global_operating_class =
20417 tdls_peer_params->global_operating_class;
20418 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
20419 pTdlsPeer->peerParams.min_bandwidth_kbps =
20420 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020421 /* check configured channel is valid, non dfs and
20422 * not current operating channel */
20423 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
20424 tdls_peer_params->channel)) &&
20425 (pHddStaCtx) &&
20426 (tdls_peer_params->channel !=
20427 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020428 {
20429 pTdlsPeer->isOffChannelConfigured = TRUE;
20430 }
20431 else
20432 {
20433 pTdlsPeer->isOffChannelConfigured = FALSE;
20434 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20435 "%s: Configured Tdls Off Channel is not valid", __func__);
20436
20437 }
20438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020439 "%s: tdls_off_channel %d isOffChannelConfigured %d "
20440 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020441 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020442 pTdlsPeer->isOffChannelConfigured,
20443 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020444 }
20445 else
20446 {
20447 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020448 "%s: TDLS off channel FW capability %d, "
20449 "host capab %d or Invalid TDLS Peer Params", __func__,
20450 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
20451 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020452 }
20453
Atul Mittal115287b2014-07-08 13:26:33 +053020454 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
20455
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020456 mutex_unlock(&pHddCtx->tdls_lock);
20457
Atul Mittal115287b2014-07-08 13:26:33 +053020458 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20459 " %s TDLS Add Force Peer Failed",
20460 __func__);
20461 return -EINVAL;
20462 }
20463 /*EXT TDLS*/
20464
20465 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020466 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020467 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20468 " %s TDLS set callback Failed",
20469 __func__);
20470 return -EINVAL;
20471 }
20472
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020473 mutex_unlock(&pHddCtx->tdls_lock);
20474
Atul Mittal115287b2014-07-08 13:26:33 +053020475 return(0);
20476
20477}
20478
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020479int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
20480#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20481 const u8 *peer
20482#else
20483 u8 *peer
20484#endif
20485)
Atul Mittal115287b2014-07-08 13:26:33 +053020486{
20487
20488 hddTdlsPeer_t *pTdlsPeer;
20489 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020490
Atul Mittal115287b2014-07-08 13:26:33 +053020491 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20492 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
20493 __func__, MAC_ADDR_ARRAY(peer));
20494
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020495 if (0 != wlan_hdd_validate_context(pHddCtx)) {
20496 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
20497 return -EINVAL;
20498 }
20499
Atul Mittal115287b2014-07-08 13:26:33 +053020500 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20501 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20502
20503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020504 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20505 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20506 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020507 return -ENOTSUPP;
20508 }
20509
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020510 mutex_lock(&pHddCtx->tdls_lock);
20511 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053020512
20513 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020514 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020515 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020516 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053020517 __func__, MAC_ADDR_ARRAY(peer));
20518 return -EINVAL;
20519 }
20520 else {
20521 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
20522 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020523 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
20524 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020525 /* if channel switch is configured, reset
20526 the channel for this peer */
20527 if (TRUE == pTdlsPeer->isOffChannelConfigured)
20528 {
20529 pTdlsPeer->peerParams.channel = 0;
20530 pTdlsPeer->isOffChannelConfigured = FALSE;
20531 }
Atul Mittal115287b2014-07-08 13:26:33 +053020532 }
20533
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020534 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020535 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020536 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053020537 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020538 }
Atul Mittal115287b2014-07-08 13:26:33 +053020539
20540 /*EXT TDLS*/
20541
20542 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020543 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20545 " %s TDLS set callback Failed",
20546 __func__);
20547 return -EINVAL;
20548 }
Atul Mittal115287b2014-07-08 13:26:33 +053020549
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020550 mutex_unlock(&pHddCtx->tdls_lock);
20551
20552 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053020553}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020554static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020555#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20556 const u8 *peer,
20557#else
20558 u8 *peer,
20559#endif
20560 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020561{
20562 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20563 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020564 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020565 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020566
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020567 ENTER();
20568
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020569 if (!pAdapter) {
20570 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
20571 return -EINVAL;
20572 }
20573
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020574 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20575 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
20576 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020577 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020578 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070020580 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020581 return -EINVAL;
20582 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020583
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020584 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020585 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020586 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020587 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020588 }
20589
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020590
20591 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020592 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020593 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020594 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020595 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
20596 "Cannot process TDLS commands",
20597 pHddCtx->cfg_ini->fEnableTDLSSupport,
20598 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020599 return -ENOTSUPP;
20600 }
20601
20602 switch (oper) {
20603 case NL80211_TDLS_ENABLE_LINK:
20604 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020605 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020606 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053020607 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
20608 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053020609 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020610 tANI_U16 numCurrTdlsPeers = 0;
20611 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020612 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020613 tSirMacAddr peerMac;
20614 int channel;
20615 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020616
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20618 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
20619 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020620
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020621 mutex_lock(&pHddCtx->tdls_lock);
20622 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020623 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053020624 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020625 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020626 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20627 " (oper %d) not exsting. ignored",
20628 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20629 return -EINVAL;
20630 }
20631
20632 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20633 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20634 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20635 "NL80211_TDLS_ENABLE_LINK");
20636
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020637 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
20638 {
20639 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
20640 MAC_ADDRESS_STR " failed",
20641 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020642 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020643 return -EINVAL;
20644 }
20645
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020646 /* before starting tdls connection, set tdls
20647 * off channel established status to default value */
20648 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020649
20650 mutex_unlock(&pHddCtx->tdls_lock);
20651
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053020652 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020653 /* TDLS Off Channel, Disable tdls channel switch,
20654 when there are more than one tdls link */
20655 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053020656 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020657 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020658 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020659 /* get connected peer and send disable tdls off chan */
20660 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020661 if ((connPeer) &&
20662 (connPeer->isOffChannelSupported == TRUE) &&
20663 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020664 {
20665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20666 "%s: More then one peer connected, Disable "
20667 "TDLS channel switch", __func__);
20668
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020669 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020670 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
20671 channel = connPeer->peerParams.channel;
20672
20673 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020674
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020675 ret = sme_SendTdlsChanSwitchReq(
20676 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020677 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020678 peerMac,
20679 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020680 TDLS_OFF_CHANNEL_BW_OFFSET,
20681 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020682 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020683 hddLog(VOS_TRACE_LEVEL_ERROR,
20684 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020685 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020686 }
20687 else
20688 {
20689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20690 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020691 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020692 "isOffChannelConfigured %d",
20693 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020694 (connPeer ? (connPeer->isOffChannelSupported)
20695 : -1),
20696 (connPeer ? (connPeer->isOffChannelConfigured)
20697 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020698 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020699 }
20700 }
20701
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020702 mutex_lock(&pHddCtx->tdls_lock);
20703 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20704 if ( NULL == pTdlsPeer ) {
20705 mutex_unlock(&pHddCtx->tdls_lock);
20706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20707 "%s: " MAC_ADDRESS_STR
20708 " (oper %d) peer got freed in other context. ignored",
20709 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20710 return -EINVAL;
20711 }
20712 peer_status = pTdlsPeer->link_status;
20713 mutex_unlock(&pHddCtx->tdls_lock);
20714
20715 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020716 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020717 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053020718
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020719 if (0 != wlan_hdd_tdls_get_link_establish_params(
20720 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020721 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020722 return -EINVAL;
20723 }
20724 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020725
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020726 ret = sme_SendTdlsLinkEstablishParams(
20727 WLAN_HDD_GET_HAL_CTX(pAdapter),
20728 pAdapter->sessionId, peer,
20729 &tdlsLinkEstablishParams);
20730 if (ret != VOS_STATUS_SUCCESS) {
20731 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
20732 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020733 /* Send TDLS peer UAPSD capabilities to the firmware and
20734 * register with the TL on after the response for this operation
20735 * is received .
20736 */
20737 ret = wait_for_completion_interruptible_timeout(
20738 &pAdapter->tdls_link_establish_req_comp,
20739 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053020740
20741 mutex_lock(&pHddCtx->tdls_lock);
20742 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20743 if ( NULL == pTdlsPeer ) {
20744 mutex_unlock(&pHddCtx->tdls_lock);
20745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20746 "%s %d: " MAC_ADDRESS_STR
20747 " (oper %d) peer got freed in other context. ignored",
20748 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
20749 (int)oper);
20750 return -EINVAL;
20751 }
20752 peer_status = pTdlsPeer->link_status;
20753 mutex_unlock(&pHddCtx->tdls_lock);
20754
20755 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020756 {
20757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020758 FL("Link Establish Request Failed Status %ld"),
20759 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020760 return -EINVAL;
20761 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020762 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020763
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020764 mutex_lock(&pHddCtx->tdls_lock);
20765 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20766 if ( NULL == pTdlsPeer ) {
20767 mutex_unlock(&pHddCtx->tdls_lock);
20768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20769 "%s: " MAC_ADDRESS_STR
20770 " (oper %d) peer got freed in other context. ignored",
20771 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20772 return -EINVAL;
20773 }
20774
Atul Mittal115287b2014-07-08 13:26:33 +053020775 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20776 eTDLS_LINK_CONNECTED,
20777 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020778 staDesc.ucSTAId = pTdlsPeer->staId;
20779 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053020780
20781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20782 "%s: tdlsLinkEstablishParams of peer "
20783 MAC_ADDRESS_STR "uapsdQueues: %d"
20784 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
20785 "isResponder: %d peerstaId: %d",
20786 __func__,
20787 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
20788 tdlsLinkEstablishParams.uapsdQueues,
20789 tdlsLinkEstablishParams.qos,
20790 tdlsLinkEstablishParams.maxSp,
20791 tdlsLinkEstablishParams.isBufSta,
20792 tdlsLinkEstablishParams.isOffChannelSupported,
20793 tdlsLinkEstablishParams.isResponder,
20794 pTdlsPeer->staId);
20795
20796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20797 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
20798 __func__,
20799 staDesc.ucSTAId,
20800 staDesc.ucQosEnabled);
20801
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020802 ret = WLANTL_UpdateTdlsSTAClient(
20803 pHddCtx->pvosContext,
20804 &staDesc);
20805 if (ret != VOS_STATUS_SUCCESS) {
20806 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
20807 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053020808
Gopichand Nakkala471708b2013-06-04 20:03:01 +053020809 /* Mark TDLS client Authenticated .*/
20810 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
20811 pTdlsPeer->staId,
20812 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020813 if (VOS_STATUS_SUCCESS == status)
20814 {
Hoonki Lee14621352013-04-16 17:51:19 -070020815 if (pTdlsPeer->is_responder == 0)
20816 {
20817 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020818 tdlsConnInfo_t *tdlsInfo;
20819
20820 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
20821
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020822 if (!vos_timer_is_initialized(
20823 &pTdlsPeer->initiatorWaitTimeoutTimer))
20824 {
20825 /* Initialize initiator wait callback */
20826 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020827 &pTdlsPeer->initiatorWaitTimeoutTimer,
20828 VOS_TIMER_TYPE_SW,
20829 wlan_hdd_tdls_initiator_wait_cb,
20830 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020831 }
Hoonki Lee14621352013-04-16 17:51:19 -070020832 wlan_hdd_tdls_timer_restart(pAdapter,
20833 &pTdlsPeer->initiatorWaitTimeoutTimer,
20834 WAIT_TIME_TDLS_INITIATOR);
20835 /* suspend initiator TX until it receives direct packet from the
20836 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020837 ret = WLANTL_SuspendDataTx(
20838 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20839 &staId, NULL);
20840 if (ret != VOS_STATUS_SUCCESS) {
20841 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20842 }
Hoonki Lee14621352013-04-16 17:51:19 -070020843 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020844
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020845 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020846 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020847 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020848 suppChannelLen =
20849 tdlsLinkEstablishParams.supportedChannelsLen;
20850
20851 if ((suppChannelLen > 0) &&
20852 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20853 {
20854 tANI_U8 suppPeerChannel = 0;
20855 int i = 0;
20856 for (i = 0U; i < suppChannelLen; i++)
20857 {
20858 suppPeerChannel =
20859 tdlsLinkEstablishParams.supportedChannels[i];
20860
20861 pTdlsPeer->isOffChannelSupported = FALSE;
20862 if (suppPeerChannel ==
20863 pTdlsPeer->peerParams.channel)
20864 {
20865 pTdlsPeer->isOffChannelSupported = TRUE;
20866 break;
20867 }
20868 }
20869 }
20870 else
20871 {
20872 pTdlsPeer->isOffChannelSupported = FALSE;
20873 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020874 }
20875 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20876 "%s: TDLS channel switch request for channel "
20877 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020878 "%d isOffChannelSupported %d", __func__,
20879 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020880 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020881 suppChannelLen,
20882 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020883
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020884 /* TDLS Off Channel, Enable tdls channel switch,
20885 when their is only one tdls link and it supports */
20886 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20887 if ((numCurrTdlsPeers == 1) &&
20888 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20889 (TRUE == pTdlsPeer->isOffChannelConfigured))
20890 {
20891 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20892 "%s: Send TDLS channel switch request for channel %d",
20893 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020894
20895 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020896 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20897 channel = pTdlsPeer->peerParams.channel;
20898
20899 mutex_unlock(&pHddCtx->tdls_lock);
20900
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020901 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20902 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020903 peerMac,
20904 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020905 TDLS_OFF_CHANNEL_BW_OFFSET,
20906 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020907 if (ret != VOS_STATUS_SUCCESS) {
20908 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20909 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020910 }
20911 else
20912 {
20913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20914 "%s: TDLS channel switch request not sent"
20915 " numCurrTdlsPeers %d "
20916 "isOffChannelSupported %d "
20917 "isOffChannelConfigured %d",
20918 __func__, numCurrTdlsPeers,
20919 pTdlsPeer->isOffChannelSupported,
20920 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020921 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020922 }
20923
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020924 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020925 else
20926 mutex_unlock(&pHddCtx->tdls_lock);
20927
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020928 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020929
20930 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020931 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
20932 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020933 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020934 int ac;
20935 uint8 ucAc[4] = { WLANTL_AC_VO,
20936 WLANTL_AC_VI,
20937 WLANTL_AC_BK,
20938 WLANTL_AC_BE };
20939 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
20940 for(ac=0; ac < 4; ac++)
20941 {
20942 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20943 pTdlsPeer->staId, ucAc[ac],
20944 tlTid[ac], tlTid[ac], 0, 0,
20945 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020946 if (status != VOS_STATUS_SUCCESS) {
20947 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
20948 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020949 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020950 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020951 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020952
Bhargav Shah66896792015-10-01 18:17:37 +053020953 /* stop TCP delack timer if TDLS is enable */
20954 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20955 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053020956 hdd_wlan_tdls_enable_link_event(peer,
20957 pTdlsPeer->isOffChannelSupported,
20958 pTdlsPeer->isOffChannelConfigured,
20959 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020960 }
20961 break;
20962 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080020963 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020964 tANI_U16 numCurrTdlsPeers = 0;
20965 hddTdlsPeer_t *connPeer = NULL;
20966
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20968 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
20969 __func__, MAC_ADDR_ARRAY(peer));
20970
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020971 mutex_lock(&pHddCtx->tdls_lock);
20972 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020973
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020974
Sunil Dutt41de4e22013-11-14 18:09:02 +053020975 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020976 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020977 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20978 " (oper %d) not exsting. ignored",
20979 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20980 return -EINVAL;
20981 }
20982
20983 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20984 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20985 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20986 "NL80211_TDLS_DISABLE_LINK");
20987
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020988 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080020989 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020990 long status;
20991
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020992 /* set tdls off channel status to false for this peer */
20993 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053020994 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20995 eTDLS_LINK_TEARING,
20996 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
20997 eTDLS_LINK_UNSPECIFIED:
20998 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020999 mutex_unlock(&pHddCtx->tdls_lock);
21000
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021001 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
21002
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021003 status = sme_DeleteTdlsPeerSta(
21004 WLAN_HDD_GET_HAL_CTX(pAdapter),
21005 pAdapter->sessionId, peer );
21006 if (status != VOS_STATUS_SUCCESS) {
21007 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
21008 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021009
21010 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
21011 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021012
21013 mutex_lock(&pHddCtx->tdls_lock);
21014 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21015 if ( NULL == pTdlsPeer ) {
21016 mutex_unlock(&pHddCtx->tdls_lock);
21017 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21018 " peer was freed in other context",
21019 __func__, MAC_ADDR_ARRAY(peer));
21020 return -EINVAL;
21021 }
21022
Atul Mittal271a7652014-09-12 13:18:22 +053021023 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053021024 eTDLS_LINK_IDLE,
21025 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021026 mutex_unlock(&pHddCtx->tdls_lock);
21027
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021028 if (status <= 0)
21029 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21031 "%s: Del station failed status %ld",
21032 __func__, status);
21033 return -EPERM;
21034 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021035
21036 /* TDLS Off Channel, Enable tdls channel switch,
21037 when their is only one tdls link and it supports */
21038 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
21039 if (numCurrTdlsPeers == 1)
21040 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021041 tSirMacAddr peerMac;
21042 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021043
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021044 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021045 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021046
21047 if (connPeer == NULL) {
21048 mutex_unlock(&pHddCtx->tdls_lock);
21049 hddLog(VOS_TRACE_LEVEL_ERROR,
21050 "%s connPeer is NULL", __func__);
21051 return -EINVAL;
21052 }
21053
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021054 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
21055 channel = connPeer->peerParams.channel;
21056
21057 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21058 "%s: TDLS channel switch "
21059 "isOffChannelSupported %d "
21060 "isOffChannelConfigured %d "
21061 "isOffChannelEstablished %d",
21062 __func__,
21063 (connPeer ? connPeer->isOffChannelSupported : -1),
21064 (connPeer ? connPeer->isOffChannelConfigured : -1),
21065 (connPeer ? connPeer->isOffChannelEstablished : -1));
21066
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021067 if ((connPeer) &&
21068 (connPeer->isOffChannelSupported == TRUE) &&
21069 (connPeer->isOffChannelConfigured == TRUE))
21070 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053021071 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021072 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021073 status = sme_SendTdlsChanSwitchReq(
21074 WLAN_HDD_GET_HAL_CTX(pAdapter),
21075 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021076 peerMac,
21077 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021078 TDLS_OFF_CHANNEL_BW_OFFSET,
21079 TDLS_CHANNEL_SWITCH_ENABLE);
21080 if (status != VOS_STATUS_SUCCESS) {
21081 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
21082 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021083 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021084 else
21085 mutex_unlock(&pHddCtx->tdls_lock);
21086 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021087 else
21088 {
21089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21090 "%s: TDLS channel switch request not sent "
21091 "numCurrTdlsPeers %d ",
21092 __func__, numCurrTdlsPeers);
21093 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021094 }
21095 else
21096 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021097 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21099 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080021100 }
Bhargav Shah66896792015-10-01 18:17:37 +053021101 if (numCurrTdlsPeers == 0) {
21102 /* start TCP delack timer if TDLS is disable */
21103 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21104 hdd_manage_delack_timer(pHddCtx);
21105 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021106 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021107 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021108 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021109 {
Atul Mittal115287b2014-07-08 13:26:33 +053021110 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021111
Atul Mittal115287b2014-07-08 13:26:33 +053021112 if (0 != status)
21113 {
21114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021115 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053021116 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021117 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053021118 break;
21119 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021120 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021121 {
Atul Mittal115287b2014-07-08 13:26:33 +053021122 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
21123 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021124 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053021125 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021126
Atul Mittal115287b2014-07-08 13:26:33 +053021127 if (0 != status)
21128 {
21129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021130 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053021131 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053021132 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053021133 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021134 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021135 case NL80211_TDLS_DISCOVERY_REQ:
21136 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021138 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021139 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021140 return -ENOTSUPP;
21141 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21143 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021144 return -ENOTSUPP;
21145 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021146
21147 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021148 return 0;
21149}
Chilam NG571c65a2013-01-19 12:27:36 +053021150
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021151static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021152#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
21153 const u8 *peer,
21154#else
21155 u8 *peer,
21156#endif
21157 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021158{
21159 int ret;
21160
21161 vos_ssr_protect(__func__);
21162 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
21163 vos_ssr_unprotect(__func__);
21164
21165 return ret;
21166}
21167
Chilam NG571c65a2013-01-19 12:27:36 +053021168int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
21169 struct net_device *dev, u8 *peer)
21170{
Arif Hussaina7c8e412013-11-20 11:06:42 -080021171 hddLog(VOS_TRACE_LEVEL_INFO,
21172 "tdls send discover req: "MAC_ADDRESS_STR,
21173 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021174#if TDLS_MGMT_VERSION2
21175 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21176 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21177#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021178#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
21179 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21180 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
21181#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
21182 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21183 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21184#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
21185 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21186 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21187#else
Chilam NG571c65a2013-01-19 12:27:36 +053021188 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21189 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021190#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021191#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053021192}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021193#endif
21194
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021195#ifdef WLAN_FEATURE_GTK_OFFLOAD
21196/*
21197 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
21198 * Callback rountine called upon receiving response for
21199 * get offload info
21200 */
21201void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
21202 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
21203{
21204
21205 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021206 tANI_U8 tempReplayCounter[8];
21207 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021208
21209 ENTER();
21210
21211 if (NULL == pAdapter)
21212 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053021213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021214 "%s: HDD adapter is Null", __func__);
21215 return ;
21216 }
21217
21218 if (NULL == pGtkOffloadGetInfoRsp)
21219 {
21220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21221 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
21222 return ;
21223 }
21224
21225 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
21226 {
21227 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21228 "%s: wlan Failed to get replay counter value",
21229 __func__);
21230 return ;
21231 }
21232
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021233 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21234 /* Update replay counter */
21235 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
21236 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21237
21238 {
21239 /* changing from little to big endian since supplicant
21240 * works on big endian format
21241 */
21242 int i;
21243 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21244
21245 for (i = 0; i < 8; i++)
21246 {
21247 tempReplayCounter[7-i] = (tANI_U8)p[i];
21248 }
21249 }
21250
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021251 /* Update replay counter to NL */
21252 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021253 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021254}
21255
21256/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021257 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021258 * This function is used to offload GTK rekeying job to the firmware.
21259 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021260int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021261 struct cfg80211_gtk_rekey_data *data)
21262{
21263 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21264 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21265 hdd_station_ctx_t *pHddStaCtx;
21266 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021267 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021268 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021269 eHalStatus status = eHAL_STATUS_FAILURE;
21270
21271 ENTER();
21272
21273 if (NULL == pAdapter)
21274 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053021275 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021276 "%s: HDD adapter is Null", __func__);
21277 return -ENODEV;
21278 }
21279
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053021280 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21281 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
21282 pAdapter->sessionId, pAdapter->device_mode));
21283
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021284 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021285 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021286 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021287 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021288 }
21289
21290 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21291 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
21292 if (NULL == hHal)
21293 {
21294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21295 "%s: HAL context is Null!!!", __func__);
21296 return -EAGAIN;
21297 }
21298
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021299 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
21300 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
21301 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
21302 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021303 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021304 {
21305 /* changing from big to little endian since driver
21306 * works on little endian format
21307 */
21308 tANI_U8 *p =
21309 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
21310 int i;
21311
21312 for (i = 0; i < 8; i++)
21313 {
21314 p[7-i] = data->replay_ctr[i];
21315 }
21316 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021317
21318 if (TRUE == pHddCtx->hdd_wlan_suspended)
21319 {
21320 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021321 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
21322 sizeof (tSirGtkOffloadParams));
21323 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021324 pAdapter->sessionId);
21325
21326 if (eHAL_STATUS_SUCCESS != status)
21327 {
21328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21329 "%s: sme_SetGTKOffload failed, returned %d",
21330 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021331
21332 /* Need to clear any trace of key value in the memory.
21333 * Thus zero out the memory even though it is local
21334 * variable.
21335 */
21336 vos_mem_zero(&hddGtkOffloadReqParams,
21337 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021338 return status;
21339 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21341 "%s: sme_SetGTKOffload successfull", __func__);
21342 }
21343 else
21344 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021345 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21346 "%s: wlan not suspended GTKOffload request is stored",
21347 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021348 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021349
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021350 /* Need to clear any trace of key value in the memory.
21351 * Thus zero out the memory even though it is local
21352 * variable.
21353 */
21354 vos_mem_zero(&hddGtkOffloadReqParams,
21355 sizeof(hddGtkOffloadReqParams));
21356
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021357 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021358 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021359}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021360
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021361int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
21362 struct cfg80211_gtk_rekey_data *data)
21363{
21364 int ret;
21365
21366 vos_ssr_protect(__func__);
21367 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
21368 vos_ssr_unprotect(__func__);
21369
21370 return ret;
21371}
21372#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021373/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021374 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021375 * This function is used to set access control policy
21376 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021377static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21378 struct net_device *dev,
21379 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021380{
21381 int i;
21382 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21383 hdd_hostapd_state_t *pHostapdState;
21384 tsap_Config_t *pConfig;
21385 v_CONTEXT_t pVosContext = NULL;
21386 hdd_context_t *pHddCtx;
21387 int status;
21388
21389 ENTER();
21390
21391 if (NULL == pAdapter)
21392 {
21393 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21394 "%s: HDD adapter is Null", __func__);
21395 return -ENODEV;
21396 }
21397
21398 if (NULL == params)
21399 {
21400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21401 "%s: params is Null", __func__);
21402 return -EINVAL;
21403 }
21404
21405 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21406 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021407 if (0 != status)
21408 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021409 return status;
21410 }
21411
21412 pVosContext = pHddCtx->pvosContext;
21413 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
21414
21415 if (NULL == pHostapdState)
21416 {
21417 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21418 "%s: pHostapdState is Null", __func__);
21419 return -EINVAL;
21420 }
21421
21422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
21423 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021424 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21425 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
21426 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021427
21428 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
21429 {
21430 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
21431
21432 /* default value */
21433 pConfig->num_accept_mac = 0;
21434 pConfig->num_deny_mac = 0;
21435
21436 /**
21437 * access control policy
21438 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
21439 * listed in hostapd.deny file.
21440 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
21441 * listed in hostapd.accept file.
21442 */
21443 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
21444 {
21445 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
21446 }
21447 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
21448 {
21449 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
21450 }
21451 else
21452 {
21453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21454 "%s:Acl Policy : %d is not supported",
21455 __func__, params->acl_policy);
21456 return -ENOTSUPP;
21457 }
21458
21459 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
21460 {
21461 pConfig->num_accept_mac = params->n_acl_entries;
21462 for (i = 0; i < params->n_acl_entries; i++)
21463 {
21464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21465 "** Add ACL MAC entry %i in WhiletList :"
21466 MAC_ADDRESS_STR, i,
21467 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21468
21469 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
21470 sizeof(qcmacaddr));
21471 }
21472 }
21473 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
21474 {
21475 pConfig->num_deny_mac = params->n_acl_entries;
21476 for (i = 0; i < params->n_acl_entries; i++)
21477 {
21478 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21479 "** Add ACL MAC entry %i in BlackList :"
21480 MAC_ADDRESS_STR, i,
21481 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21482
21483 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
21484 sizeof(qcmacaddr));
21485 }
21486 }
21487
21488 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
21489 {
21490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21491 "%s: SAP Set Mac Acl fail", __func__);
21492 return -EINVAL;
21493 }
21494 }
21495 else
21496 {
21497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053021498 "%s: Invalid device_mode = %s (%d)",
21499 __func__, hdd_device_modetoString(pAdapter->device_mode),
21500 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021501 return -EINVAL;
21502 }
21503
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021504 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021505 return 0;
21506}
21507
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021508static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21509 struct net_device *dev,
21510 const struct cfg80211_acl_data *params)
21511{
21512 int ret;
21513 vos_ssr_protect(__func__);
21514 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
21515 vos_ssr_unprotect(__func__);
21516
21517 return ret;
21518}
21519
Leo Chang9056f462013-08-01 19:21:11 -070021520#ifdef WLAN_NL80211_TESTMODE
21521#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070021522void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070021523(
21524 void *pAdapter,
21525 void *indCont
21526)
21527{
Leo Changd9df8aa2013-09-26 13:32:26 -070021528 tSirLPHBInd *lphbInd;
21529 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053021530 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070021531
21532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021533 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070021534
c_hpothu73f35e62014-04-18 13:40:08 +053021535 if (pAdapter == NULL)
21536 {
21537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21538 "%s: pAdapter is NULL\n",__func__);
21539 return;
21540 }
21541
Leo Chang9056f462013-08-01 19:21:11 -070021542 if (NULL == indCont)
21543 {
21544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021545 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070021546 return;
21547 }
21548
c_hpothu73f35e62014-04-18 13:40:08 +053021549 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070021550 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070021551 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053021552 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070021553 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070021554 GFP_ATOMIC);
21555 if (!skb)
21556 {
21557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21558 "LPHB timeout, NL buffer alloc fail");
21559 return;
21560 }
21561
Leo Changac3ba772013-10-07 09:47:04 -070021562 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070021563 {
21564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21565 "WLAN_HDD_TM_ATTR_CMD put fail");
21566 goto nla_put_failure;
21567 }
Leo Changac3ba772013-10-07 09:47:04 -070021568 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070021569 {
21570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21571 "WLAN_HDD_TM_ATTR_TYPE put fail");
21572 goto nla_put_failure;
21573 }
Leo Changac3ba772013-10-07 09:47:04 -070021574 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070021575 sizeof(tSirLPHBInd), lphbInd))
21576 {
21577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21578 "WLAN_HDD_TM_ATTR_DATA put fail");
21579 goto nla_put_failure;
21580 }
Leo Chang9056f462013-08-01 19:21:11 -070021581 cfg80211_testmode_event(skb, GFP_ATOMIC);
21582 return;
21583
21584nla_put_failure:
21585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21586 "NLA Put fail");
21587 kfree_skb(skb);
21588
21589 return;
21590}
21591#endif /* FEATURE_WLAN_LPHB */
21592
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021593static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070021594{
21595 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
21596 int err = 0;
21597#ifdef FEATURE_WLAN_LPHB
21598 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070021599 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021600
21601 ENTER();
21602
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021603 err = wlan_hdd_validate_context(pHddCtx);
21604 if (0 != err)
21605 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021606 return err;
21607 }
Leo Chang9056f462013-08-01 19:21:11 -070021608#endif /* FEATURE_WLAN_LPHB */
21609
21610 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
21611 if (err)
21612 {
21613 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21614 "%s Testmode INV ATTR", __func__);
21615 return err;
21616 }
21617
21618 if (!tb[WLAN_HDD_TM_ATTR_CMD])
21619 {
21620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21621 "%s Testmode INV CMD", __func__);
21622 return -EINVAL;
21623 }
21624
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021625 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21626 TRACE_CODE_HDD_CFG80211_TESTMODE,
21627 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070021628 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
21629 {
21630#ifdef FEATURE_WLAN_LPHB
21631 /* Low Power Heartbeat configuration request */
21632 case WLAN_HDD_TM_CMD_WLAN_HB:
21633 {
21634 int buf_len;
21635 void *buf;
21636 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080021637 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070021638
21639 if (!tb[WLAN_HDD_TM_ATTR_DATA])
21640 {
21641 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21642 "%s Testmode INV DATA", __func__);
21643 return -EINVAL;
21644 }
21645
21646 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
21647 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080021648
Manjeet Singh3c577442017-02-10 19:03:38 +053021649 if (buf_len > sizeof(*hb_params)) {
21650 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
21651 buf_len);
21652 return -ERANGE;
21653 }
21654
Amar Singhal05852702014-02-04 14:40:00 -080021655 hb_params_temp =(tSirLPHBReq *)buf;
21656 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
21657 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
21658 return -EINVAL;
21659
Leo Chang9056f462013-08-01 19:21:11 -070021660 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
21661 if (NULL == hb_params)
21662 {
21663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21664 "%s Request Buffer Alloc Fail", __func__);
21665 return -EINVAL;
21666 }
21667
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053021668 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070021669 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070021670 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
21671 hb_params,
21672 wlan_hdd_cfg80211_lphb_ind_handler);
21673 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070021674 {
Leo Changd9df8aa2013-09-26 13:32:26 -070021675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21676 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070021677 vos_mem_free(hb_params);
21678 }
Leo Chang9056f462013-08-01 19:21:11 -070021679 return 0;
21680 }
21681#endif /* FEATURE_WLAN_LPHB */
21682 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21684 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070021685 return -EOPNOTSUPP;
21686 }
21687
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021688 EXIT();
21689 return err;
Leo Chang9056f462013-08-01 19:21:11 -070021690}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021691
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053021692static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
21693#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
21694 struct wireless_dev *wdev,
21695#endif
21696 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021697{
21698 int ret;
21699
21700 vos_ssr_protect(__func__);
21701 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
21702 vos_ssr_unprotect(__func__);
21703
21704 return ret;
21705}
Leo Chang9056f462013-08-01 19:21:11 -070021706#endif /* CONFIG_NL80211_TESTMODE */
21707
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021708extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021709static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021710 struct net_device *dev,
21711 int idx, struct survey_info *survey)
21712{
21713 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21714 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053021715 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021716 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053021717 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021718 v_S7_t snr,rssi;
21719 int status, i, j, filled = 0;
21720
21721 ENTER();
21722
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021723 if (NULL == pAdapter)
21724 {
21725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21726 "%s: HDD adapter is Null", __func__);
21727 return -ENODEV;
21728 }
21729
21730 if (NULL == wiphy)
21731 {
21732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21733 "%s: wiphy is Null", __func__);
21734 return -ENODEV;
21735 }
21736
21737 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21738 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021739 if (0 != status)
21740 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021741 return status;
21742 }
21743
Mihir Sheted9072e02013-08-21 17:02:29 +053021744 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21745
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021746 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053021747 0 != pAdapter->survey_idx ||
21748 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021749 {
21750 /* The survey dump ops when implemented completely is expected to
21751 * return a survey of all channels and the ops is called by the
21752 * kernel with incremental values of the argument 'idx' till it
21753 * returns -ENONET. But we can only support the survey for the
21754 * operating channel for now. survey_idx is used to track
21755 * that the ops is called only once and then return -ENONET for
21756 * the next iteration
21757 */
21758 pAdapter->survey_idx = 0;
21759 return -ENONET;
21760 }
21761
Mukul Sharma9d5233b2015-06-11 20:28:20 +053021762 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
21763 {
21764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21765 "%s: Roaming in progress, hence return ", __func__);
21766 return -ENONET;
21767 }
21768
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021769 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
21770
21771 wlan_hdd_get_snr(pAdapter, &snr);
21772 wlan_hdd_get_rssi(pAdapter, &rssi);
21773
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021774 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21775 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
21776 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021777 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
21778 hdd_wlan_get_freq(channel, &freq);
21779
21780
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053021781 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021782 {
21783 if (NULL == wiphy->bands[i])
21784 {
21785 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
21786 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
21787 continue;
21788 }
21789
21790 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
21791 {
21792 struct ieee80211_supported_band *band = wiphy->bands[i];
21793
21794 if (band->channels[j].center_freq == (v_U16_t)freq)
21795 {
21796 survey->channel = &band->channels[j];
21797 /* The Rx BDs contain SNR values in dB for the received frames
21798 * while the supplicant expects noise. So we calculate and
21799 * return the value of noise (dBm)
21800 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
21801 */
21802 survey->noise = rssi - snr;
21803 survey->filled = SURVEY_INFO_NOISE_DBM;
21804 filled = 1;
21805 }
21806 }
21807 }
21808
21809 if (filled)
21810 pAdapter->survey_idx = 1;
21811 else
21812 {
21813 pAdapter->survey_idx = 0;
21814 return -ENONET;
21815 }
21816
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021817 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021818 return 0;
21819}
21820
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021821static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
21822 struct net_device *dev,
21823 int idx, struct survey_info *survey)
21824{
21825 int ret;
21826
21827 vos_ssr_protect(__func__);
21828 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
21829 vos_ssr_unprotect(__func__);
21830
21831 return ret;
21832}
21833
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021834/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021835 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021836 * this is called when cfg80211 driver resume
21837 * driver updates latest sched_scan scan result(if any) to cfg80211 database
21838 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021839int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021840{
21841 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21842 hdd_adapter_t *pAdapter;
21843 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21844 VOS_STATUS status = VOS_STATUS_SUCCESS;
21845
21846 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021847
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021848 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021849 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021850 return 0;
21851 }
21852
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021853 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21854 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021855
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021856 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021857 {
21858 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21859 "%s: Resume SoftAP", __func__);
21860 hdd_set_wlan_suspend_mode(false);
21861 }
21862
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021863 spin_lock(&pHddCtx->schedScan_lock);
21864 pHddCtx->isWiphySuspended = FALSE;
21865 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21866 {
21867 spin_unlock(&pHddCtx->schedScan_lock);
21868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21869 "%s: Return resume is not due to PNO indication", __func__);
21870 return 0;
21871 }
21872 // Reset flag to avoid updatating cfg80211 data old results again
21873 pHddCtx->isSchedScanUpdatePending = FALSE;
21874 spin_unlock(&pHddCtx->schedScan_lock);
21875
21876 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21877
21878 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21879 {
21880 pAdapter = pAdapterNode->pAdapter;
21881 if ( (NULL != pAdapter) &&
21882 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21883 {
21884 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021885 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21887 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021888 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021889 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021890 {
21891 /* Acquire wakelock to handle the case where APP's tries to
21892 * suspend immediately after updating the scan results. Whis
21893 * results in app's is in suspended state and not able to
21894 * process the connect request to AP
21895 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021896 hdd_prevent_suspend_timeout(2000,
21897 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021898 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021899 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021900
21901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21902 "%s : cfg80211 scan result database updated", __func__);
21903
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021904 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021905 return 0;
21906
21907 }
21908 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21909 pAdapterNode = pNext;
21910 }
21911
21912 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21913 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021914 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021915 return 0;
21916}
21917
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021918int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21919{
21920 int ret;
21921
21922 vos_ssr_protect(__func__);
21923 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
21924 vos_ssr_unprotect(__func__);
21925
21926 return ret;
21927}
21928
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021929/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021930 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021931 * this is called when cfg80211 driver suspends
21932 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021933int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021934 struct cfg80211_wowlan *wow)
21935{
21936 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021937 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021938
21939 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021940
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021941 ret = wlan_hdd_validate_context(pHddCtx);
21942 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021943 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021944 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021945 }
21946
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021947 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21949 "%s: Suspend SoftAP", __func__);
21950 hdd_set_wlan_suspend_mode(true);
21951 }
21952
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021953
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021954 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21955 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
21956 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021957 pHddCtx->isWiphySuspended = TRUE;
21958
21959 EXIT();
21960
21961 return 0;
21962}
21963
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021964int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
21965 struct cfg80211_wowlan *wow)
21966{
21967 int ret;
21968
21969 vos_ssr_protect(__func__);
21970 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
21971 vos_ssr_unprotect(__func__);
21972
21973 return ret;
21974}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021975
21976#ifdef FEATURE_OEM_DATA_SUPPORT
21977static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021978 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021979{
21980 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21981
21982 ENTER();
21983
21984 if (wlan_hdd_validate_context(pHddCtx)) {
21985 return;
21986 }
21987 if (!pMsg)
21988 {
21989 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
21990 return;
21991 }
21992
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021993 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021994
21995 EXIT();
21996 return;
21997
21998}
21999
22000void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022001 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022002{
22003 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22004
22005 ENTER();
22006
22007 if (wlan_hdd_validate_context(pHddCtx)) {
22008 return;
22009 }
22010
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022011 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022012
22013 switch(evType) {
22014 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022015 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022016 break;
22017 default:
22018 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
22019 break;
22020 }
22021 EXIT();
22022}
22023#endif
22024
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022025#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22026 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022027/**
22028 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
22029 * @wiphy: Pointer to wiphy
22030 * @wdev: Pointer to wireless device structure
22031 *
22032 * This function is used to abort an ongoing scan
22033 *
22034 * Return: None
22035 */
22036static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22037 struct wireless_dev *wdev)
22038{
22039 struct net_device *dev = wdev->netdev;
22040 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22041 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
22042 int ret;
22043
22044 ENTER();
22045
22046 if (NULL == adapter) {
22047 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
22048 return;
22049 }
22050
22051 ret = wlan_hdd_validate_context(hdd_ctx);
22052 if (0 != ret)
22053 return;
22054
22055 wlan_hdd_scan_abort(adapter);
22056
22057 return;
22058}
22059
22060/**
22061 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
22062 * @wiphy: Pointer to wiphy
22063 * @wdev: Pointer to wireless device structure
22064 *
22065 * Return: None
22066 */
22067void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22068 struct wireless_dev *wdev)
22069{
22070 vos_ssr_protect(__func__);
22071 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
22072 vos_ssr_unprotect(__func__);
22073
22074 return;
22075}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022076#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022077
Abhishek Singh936c6932017-11-07 17:28:23 +053022078#ifdef CHANNEL_SWITCH_SUPPORTED
22079/**
22080 * __wlan_hdd_cfg80211_channel_switch()- function to switch
22081 * channel in SAP/GO
22082 * @wiphy: wiphy pointer
22083 * @dev: dev pointer.
22084 * @csa_params: Change channel params
22085 *
22086 * This function is called to switch channel in SAP/GO
22087 *
22088 * Return: 0 if success else return non zero
22089 */
22090static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22091 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22092{
22093 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22094 hdd_context_t *hdd_ctx;
22095 uint8_t channel;
22096 int ret;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022097 ptSapContext sap_ctx;
Abhishek Singh936c6932017-11-07 17:28:23 +053022098 v_CONTEXT_t vos_ctx;
22099
22100 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
22101
22102 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
22103 ret = wlan_hdd_validate_context(hdd_ctx);
22104 if (ret)
22105 return ret;
22106
22107 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
22108 if (!vos_ctx) {
22109 hddLog(LOGE, FL("Vos ctx is null"));
22110 return -EINVAL;
22111 }
22112
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022113 if (WLAN_HDD_SOFTAP != adapter->device_mode)
Abhishek Singh936c6932017-11-07 17:28:23 +053022114 return -ENOTSUPP;
22115
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022116 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
22117 if (!sap_ctx) {
22118 hddLog(LOGE, FL("sap_ctx is NULL"));
22119 return -EINVAL;
22120 }
22121
22122 ret = wlansap_chk_n_set_chan_change_in_progress(sap_ctx);
22123 if (ret)
22124 return ret;
22125
22126 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
22127
Abhishek Singh936c6932017-11-07 17:28:23 +053022128 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053022129 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053022130
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022131 if (ret) {
22132 wlansap_reset_chan_change_in_progress(sap_ctx);
22133 complete(&sap_ctx->ecsa_info.chan_switch_comp);
22134 }
22135
Abhishek Singh936c6932017-11-07 17:28:23 +053022136 return ret;
22137}
22138
22139/**
22140 * wlan_hdd_cfg80211_channel_switch()- function to switch
22141 * channel in SAP/GO
22142 * @wiphy: wiphy pointer
22143 * @dev: dev pointer.
22144 * @csa_params: Change channel params
22145 *
22146 * This function is called to switch channel in SAP/GO
22147 *
22148 * Return: 0 if success else return non zero
22149 */
22150static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22151 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22152{
22153 int ret;
22154
22155 vos_ssr_protect(__func__);
22156 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
22157 vos_ssr_unprotect(__func__);
22158
22159 return ret;
22160}
22161#endif
22162
Jeff Johnson295189b2012-06-20 16:38:30 -070022163/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053022164static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070022165{
22166 .add_virtual_intf = wlan_hdd_add_virtual_intf,
22167 .del_virtual_intf = wlan_hdd_del_virtual_intf,
22168 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
22169 .change_station = wlan_hdd_change_station,
22170#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
22171 .add_beacon = wlan_hdd_cfg80211_add_beacon,
22172 .del_beacon = wlan_hdd_cfg80211_del_beacon,
22173 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022174#else
22175 .start_ap = wlan_hdd_cfg80211_start_ap,
22176 .change_beacon = wlan_hdd_cfg80211_change_beacon,
22177 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070022178#endif
22179 .change_bss = wlan_hdd_cfg80211_change_bss,
22180 .add_key = wlan_hdd_cfg80211_add_key,
22181 .get_key = wlan_hdd_cfg80211_get_key,
22182 .del_key = wlan_hdd_cfg80211_del_key,
22183 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022184#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070022185 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022186#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022187 .scan = wlan_hdd_cfg80211_scan,
22188 .connect = wlan_hdd_cfg80211_connect,
22189 .disconnect = wlan_hdd_cfg80211_disconnect,
22190 .join_ibss = wlan_hdd_cfg80211_join_ibss,
22191 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
22192 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
22193 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
22194 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070022195 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
22196 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053022197 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070022198#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
22199 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
22200 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
22201 .set_txq_params = wlan_hdd_set_txq_params,
22202#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022203 .get_station = wlan_hdd_cfg80211_get_station,
22204 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
22205 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022206 .add_station = wlan_hdd_cfg80211_add_station,
22207#ifdef FEATURE_WLAN_LFR
22208 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
22209 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
22210 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
22211#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070022212#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
22213 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
22214#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080022215#ifdef FEATURE_WLAN_TDLS
22216 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
22217 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
22218#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053022219#ifdef WLAN_FEATURE_GTK_OFFLOAD
22220 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
22221#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053022222#ifdef FEATURE_WLAN_SCAN_PNO
22223 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
22224 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
22225#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022226 .resume = wlan_hdd_cfg80211_resume_wlan,
22227 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053022228 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070022229#ifdef WLAN_NL80211_TESTMODE
22230 .testmode_cmd = wlan_hdd_cfg80211_testmode,
22231#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022232 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022233#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22234 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022235 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022236#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053022237#ifdef CHANNEL_SWITCH_SUPPORTED
22238 .channel_switch = wlan_hdd_cfg80211_channel_switch,
22239#endif
22240
Jeff Johnson295189b2012-06-20 16:38:30 -070022241};
22242