blob: 05a6b0920a8a5e73384b0a5c98da4eb66443e496 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05302 * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053066#include <linux/etherdevice.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067#include <wlan_hdd_includes.h>
68#include <net/arp.h>
69#include <net/cfg80211.h>
70#include <linux/wireless.h>
71#include <wlan_hdd_wowl.h>
72#include <aniGlobal.h>
73#include "ccmApi.h"
74#include "sirParams.h"
75#include "dot11f.h"
76#include "wlan_hdd_assoc.h"
77#include "wlan_hdd_wext.h"
78#include "sme_Api.h"
79#include "wlan_hdd_p2p.h"
80#include "wlan_hdd_cfg80211.h"
81#include "wlan_hdd_hostapd.h"
82#include "sapInternal.h"
83#include "wlan_hdd_softap_tx_rx.h"
84#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053085#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053086#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053087#include "wlan_hdd_trace.h"
88#include "vos_types.h"
89#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070090#ifdef WLAN_BTAMP_FEATURE
91#include "bap_hdd_misc.h"
92#endif
93#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080094#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053095#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053096#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053097#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070098#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053099#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +0530100#include "wlan_logging_sock_svc.h"
Agrawal Ashishcfe83282016-09-29 13:03:45 +0530101#include "wlan_hdd_misc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530102
Jeff Johnson295189b2012-06-20 16:38:30 -0700103
104#define g_mode_rates_size (12)
105#define a_mode_rates_size (8)
106#define FREQ_BASE_80211G (2407)
107#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700108#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530109#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800111 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700112
113#define HDD2GHZCHAN(freq, chan, flag) { \
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530114 .band = HDD_NL80211_BAND_2GHZ, \
Jeff Johnson295189b2012-06-20 16:38:30 -0700115 .center_freq = (freq), \
116 .hw_value = (chan),\
117 .flags = (flag), \
118 .max_antenna_gain = 0 ,\
119 .max_power = 30, \
120}
121
122#define HDD5GHZCHAN(freq, chan, flag) { \
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530123 .band = HDD_NL80211_BAND_5GHZ, \
Jeff Johnson295189b2012-06-20 16:38:30 -0700124 .center_freq = (freq), \
125 .hw_value = (chan),\
126 .flags = (flag), \
127 .max_antenna_gain = 0 ,\
128 .max_power = 30, \
129}
130
131#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
132{\
133 .bitrate = rate, \
134 .hw_value = rate_id, \
135 .flags = flag, \
136}
137
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530138#ifdef WLAN_FEATURE_VOWIFI_11R
139#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
140#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
141#endif
142
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530143#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530144#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530145
Sunil Duttc69bccb2014-05-26 21:30:20 +0530146#ifdef WLAN_FEATURE_LINK_LAYER_STATS
147/*
148 * Used to allocate the size of 4096 for the link layer stats.
149 * The size of 4096 is considered assuming that all data per
150 * respective event fit with in the limit.Please take a call
151 * on the limit based on the data requirements on link layer
152 * statistics.
153 */
154#define LL_STATS_EVENT_BUF_SIZE 4096
155#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530156#ifdef WLAN_FEATURE_EXTSCAN
157/*
158 * Used to allocate the size of 4096 for the EXTScan NL data.
159 * The size of 4096 is considered assuming that all data per
160 * respective event fit with in the limit.Please take a call
161 * on the limit based on the data requirements.
162 */
163
164#define EXTSCAN_EVENT_BUF_SIZE 4096
165#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
166#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530167
Atul Mittal115287b2014-07-08 13:26:33 +0530168/*EXT TDLS*/
169/*
170 * Used to allocate the size of 4096 for the TDLS.
171 * The size of 4096 is considered assuming that all data per
172 * respective event fit with in the limit.Please take a call
173 * on the limit based on the data requirements on link layer
174 * statistics.
175 */
176#define EXTTDLS_EVENT_BUF_SIZE 4096
177
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530178/*
179 * Values for Mac spoofing feature
180 *
181 */
182#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
183#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
184#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530185#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
186
Anurag Chouhan343af7e2016-12-16 13:11:19 +0530187/*
188 * max_sched_scan_plans defined to 10
189 */
190#define MAX_SCHED_SCAN_PLANS 10
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530191
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530192static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700193{
194 WLAN_CIPHER_SUITE_WEP40,
195 WLAN_CIPHER_SUITE_WEP104,
196 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800197#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700198#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
199 WLAN_CIPHER_SUITE_KRK,
200 WLAN_CIPHER_SUITE_CCMP,
201#else
202 WLAN_CIPHER_SUITE_CCMP,
203#endif
204#ifdef FEATURE_WLAN_WAPI
205 WLAN_CIPHER_SUITE_SMS4,
206#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700207#ifdef WLAN_FEATURE_11W
208 WLAN_CIPHER_SUITE_AES_CMAC,
209#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700210};
211
Agrawal Ashish97dec502015-11-26 20:20:58 +0530212const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530213{
Jeff Johnson295189b2012-06-20 16:38:30 -0700214 HDD2GHZCHAN(2412, 1, 0) ,
215 HDD2GHZCHAN(2417, 2, 0) ,
216 HDD2GHZCHAN(2422, 3, 0) ,
217 HDD2GHZCHAN(2427, 4, 0) ,
218 HDD2GHZCHAN(2432, 5, 0) ,
219 HDD2GHZCHAN(2437, 6, 0) ,
220 HDD2GHZCHAN(2442, 7, 0) ,
221 HDD2GHZCHAN(2447, 8, 0) ,
222 HDD2GHZCHAN(2452, 9, 0) ,
223 HDD2GHZCHAN(2457, 10, 0) ,
224 HDD2GHZCHAN(2462, 11, 0) ,
225 HDD2GHZCHAN(2467, 12, 0) ,
226 HDD2GHZCHAN(2472, 13, 0) ,
227 HDD2GHZCHAN(2484, 14, 0) ,
228};
229
Agrawal Ashish97dec502015-11-26 20:20:58 +0530230const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700231{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700232 HDD5GHZCHAN(4920, 240, 0) ,
233 HDD5GHZCHAN(4940, 244, 0) ,
234 HDD5GHZCHAN(4960, 248, 0) ,
235 HDD5GHZCHAN(4980, 252, 0) ,
236 HDD5GHZCHAN(5040, 208, 0) ,
237 HDD5GHZCHAN(5060, 212, 0) ,
238 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 HDD5GHZCHAN(5180, 36, 0) ,
240 HDD5GHZCHAN(5200, 40, 0) ,
241 HDD5GHZCHAN(5220, 44, 0) ,
242 HDD5GHZCHAN(5240, 48, 0) ,
243 HDD5GHZCHAN(5260, 52, 0) ,
244 HDD5GHZCHAN(5280, 56, 0) ,
245 HDD5GHZCHAN(5300, 60, 0) ,
246 HDD5GHZCHAN(5320, 64, 0) ,
247 HDD5GHZCHAN(5500,100, 0) ,
248 HDD5GHZCHAN(5520,104, 0) ,
249 HDD5GHZCHAN(5540,108, 0) ,
250 HDD5GHZCHAN(5560,112, 0) ,
251 HDD5GHZCHAN(5580,116, 0) ,
252 HDD5GHZCHAN(5600,120, 0) ,
253 HDD5GHZCHAN(5620,124, 0) ,
254 HDD5GHZCHAN(5640,128, 0) ,
255 HDD5GHZCHAN(5660,132, 0) ,
256 HDD5GHZCHAN(5680,136, 0) ,
257 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800258#ifdef FEATURE_WLAN_CH144
259 HDD5GHZCHAN(5720,144, 0) ,
260#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 HDD5GHZCHAN(5745,149, 0) ,
262 HDD5GHZCHAN(5765,153, 0) ,
263 HDD5GHZCHAN(5785,157, 0) ,
264 HDD5GHZCHAN(5805,161, 0) ,
265 HDD5GHZCHAN(5825,165, 0) ,
266};
267
268static struct ieee80211_rate g_mode_rates[] =
269{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530270 HDD_G_MODE_RATETAB(10, 0x1, 0),
271 HDD_G_MODE_RATETAB(20, 0x2, 0),
272 HDD_G_MODE_RATETAB(55, 0x4, 0),
273 HDD_G_MODE_RATETAB(110, 0x8, 0),
274 HDD_G_MODE_RATETAB(60, 0x10, 0),
275 HDD_G_MODE_RATETAB(90, 0x20, 0),
276 HDD_G_MODE_RATETAB(120, 0x40, 0),
277 HDD_G_MODE_RATETAB(180, 0x80, 0),
278 HDD_G_MODE_RATETAB(240, 0x100, 0),
279 HDD_G_MODE_RATETAB(360, 0x200, 0),
280 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530282};
Jeff Johnson295189b2012-06-20 16:38:30 -0700283
284static struct ieee80211_rate a_mode_rates[] =
285{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530286 HDD_G_MODE_RATETAB(60, 0x10, 0),
287 HDD_G_MODE_RATETAB(90, 0x20, 0),
288 HDD_G_MODE_RATETAB(120, 0x40, 0),
289 HDD_G_MODE_RATETAB(180, 0x80, 0),
290 HDD_G_MODE_RATETAB(240, 0x100, 0),
291 HDD_G_MODE_RATETAB(360, 0x200, 0),
292 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 HDD_G_MODE_RATETAB(540, 0x800, 0),
294};
295
296static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
297{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530298 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700299 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530300 .band = HDD_NL80211_BAND_2GHZ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700301 .bitrates = g_mode_rates,
302 .n_bitrates = g_mode_rates_size,
303 .ht_cap.ht_supported = 1,
304 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
305 | IEEE80211_HT_CAP_GRN_FLD
306 | IEEE80211_HT_CAP_DSSSCCK40
307 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
308 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
309 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
310 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
311 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
312 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
313};
314
Jeff Johnson295189b2012-06-20 16:38:30 -0700315static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
316{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530317 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700318 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530319 .band = HDD_NL80211_BAND_5GHZ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700320 .bitrates = a_mode_rates,
321 .n_bitrates = a_mode_rates_size,
322 .ht_cap.ht_supported = 1,
323 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
324 | IEEE80211_HT_CAP_GRN_FLD
325 | IEEE80211_HT_CAP_DSSSCCK40
326 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
327 | IEEE80211_HT_CAP_SGI_40
328 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
329 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
330 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
331 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
332 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
333 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
334};
335
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530336/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700337 TX/RX direction for each kind of interface */
338static const struct ieee80211_txrx_stypes
339wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
340 [NL80211_IFTYPE_STATION] = {
341 .tx = 0xffff,
342 .rx = BIT(SIR_MAC_MGMT_ACTION) |
343 BIT(SIR_MAC_MGMT_PROBE_REQ),
344 },
345 [NL80211_IFTYPE_AP] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
348 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
349 BIT(SIR_MAC_MGMT_PROBE_REQ) |
350 BIT(SIR_MAC_MGMT_DISASSOC) |
351 BIT(SIR_MAC_MGMT_AUTH) |
352 BIT(SIR_MAC_MGMT_DEAUTH) |
353 BIT(SIR_MAC_MGMT_ACTION),
354 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700355 [NL80211_IFTYPE_ADHOC] = {
356 .tx = 0xffff,
357 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
358 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
359 BIT(SIR_MAC_MGMT_PROBE_REQ) |
360 BIT(SIR_MAC_MGMT_DISASSOC) |
361 BIT(SIR_MAC_MGMT_AUTH) |
362 BIT(SIR_MAC_MGMT_DEAUTH) |
363 BIT(SIR_MAC_MGMT_ACTION),
364 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700365 [NL80211_IFTYPE_P2P_CLIENT] = {
366 .tx = 0xffff,
367 .rx = BIT(SIR_MAC_MGMT_ACTION) |
368 BIT(SIR_MAC_MGMT_PROBE_REQ),
369 },
370 [NL80211_IFTYPE_P2P_GO] = {
371 /* This is also same as for SoftAP */
372 .tx = 0xffff,
373 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
374 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
375 BIT(SIR_MAC_MGMT_PROBE_REQ) |
376 BIT(SIR_MAC_MGMT_DISASSOC) |
377 BIT(SIR_MAC_MGMT_AUTH) |
378 BIT(SIR_MAC_MGMT_DEAUTH) |
379 BIT(SIR_MAC_MGMT_ACTION),
380 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700381};
382
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800383#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800384static const struct ieee80211_iface_limit
385wlan_hdd_iface_limit[] = {
386 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800387 /* max = 3 ; Our driver create two interfaces during driver init
388 * wlan0 and p2p0 interfaces. p2p0 is considered as station
389 * interface until a group is formed. In JB architecture, once the
390 * group is formed, interface type of p2p0 is changed to P2P GO or
391 * Client.
392 * When supplicant remove the group, it first issue a set interface
393 * cmd to change the mode back to Station. In JB this works fine as
394 * we advertize two station type interface during driver init.
395 * Some vendors create separate interface for P2P GO/Client,
396 * after group formation(Third one). But while group remove
397 * supplicant first tries to change the mode(3rd interface) to STATION
398 * But as we advertized only two sta type interfaces nl80211 was
399 * returning error for the third one which was leading to failure in
400 * delete interface. Ideally while removing the group, supplicant
401 * should not try to change the 3rd interface mode to Station type.
402 * Till we get a fix in wpa_supplicant, we advertize max STA
403 * interface type to 3
404 */
405 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800406 .types = BIT(NL80211_IFTYPE_STATION),
407 },
408 {
409 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700410 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 },
412 {
413 .max = 1,
414 .types = BIT(NL80211_IFTYPE_P2P_GO) |
415 BIT(NL80211_IFTYPE_P2P_CLIENT),
416 },
417};
418
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530419/* interface limits for sta + monitor SCC */
420static const struct ieee80211_iface_limit
421wlan_hdd_iface_sta_mon_limit[] = {
422 {
423 .max = 1,
424 .types = BIT(NL80211_IFTYPE_STATION),
425 },
426 {
427 .max = 1, /* Monitor interface */
428 .types = BIT(NL80211_IFTYPE_MONITOR),
429 },
430};
431
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800432/* By default, only single channel concurrency is allowed */
433static struct ieee80211_iface_combination
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530434wlan_hdd_iface_combination[] = {
435 {
436 .limits = wlan_hdd_iface_limit,
437 .num_different_channels = 1,
438 /*
439 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
440 * and p2p0 interfaces during driver init
441 * Some vendors create separate interface for P2P operations.
442 * wlan0: STA interface
443 * p2p0: P2P Device interface, action frames goes
444 * through this interface.
445 * p2p-xx: P2P interface, After GO negotiation this interface is
446 * created for p2p operations(GO/CLIENT interface).
447 */
448 .max_interfaces = WLAN_MAX_INTERFACES,
449 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
450 .beacon_int_infra_match = false,
451 },
452 {
453 .limits = wlan_hdd_iface_sta_mon_limit,
454 .num_different_channels = 1,
455 .max_interfaces = WLAN_STA_AND_MON_INTERFACES,
456 .n_limits = ARRAY_SIZE(wlan_hdd_iface_sta_mon_limit),
457 .beacon_int_infra_match = false,
458 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800459};
460#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800461
Jeff Johnson295189b2012-06-20 16:38:30 -0700462static struct cfg80211_ops wlan_hdd_cfg80211_ops;
463
464/* Data rate 100KBPS based on IE Index */
465struct index_data_rate_type
466{
467 v_U8_t beacon_rate_index;
468 v_U16_t supported_rate[4];
469};
470
471/* 11B, 11G Rate table include Basic rate and Extended rate
472 The IDX field is the rate index
473 The HI field is the rate when RSSI is strong or being ignored
474 (in this case we report actual rate)
475 The MID field is the rate when RSSI is moderate
476 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
477 The LO field is the rate when RSSI is low
478 (in this case we don't report rates, actual current rate used)
479 */
480static const struct
481{
482 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700483 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700484} supported_data_rate[] =
485{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700486/* IDX HI HM LM LO (RSSI-based index */
487 {2, { 10, 10, 10, 0}},
488 {4, { 20, 20, 10, 0}},
489 {11, { 55, 20, 10, 0}},
490 {12, { 60, 55, 20, 0}},
491 {18, { 90, 55, 20, 0}},
492 {22, {110, 55, 20, 0}},
493 {24, {120, 90, 60, 0}},
494 {36, {180, 120, 60, 0}},
495 {44, {220, 180, 60, 0}},
496 {48, {240, 180, 90, 0}},
497 {66, {330, 180, 90, 0}},
498 {72, {360, 240, 90, 0}},
499 {96, {480, 240, 120, 0}},
500 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700501};
502
503/* MCS Based rate table */
504static struct index_data_rate_type supported_mcs_rate[] =
505{
506/* MCS L20 L40 S20 S40 */
507 {0, {65, 135, 72, 150}},
508 {1, {130, 270, 144, 300}},
509 {2, {195, 405, 217, 450}},
510 {3, {260, 540, 289, 600}},
511 {4, {390, 810, 433, 900}},
512 {5, {520, 1080, 578, 1200}},
513 {6, {585, 1215, 650, 1350}},
514 {7, {650, 1350, 722, 1500}}
515};
516
Leo Chang6f8870f2013-03-26 18:11:36 -0700517#ifdef WLAN_FEATURE_11AC
518
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530519#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700520
521struct index_vht_data_rate_type
522{
523 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530524 v_U16_t supported_VHT80_rate[2];
525 v_U16_t supported_VHT40_rate[2];
526 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700527};
528
529typedef enum
530{
531 DATA_RATE_11AC_MAX_MCS_7,
532 DATA_RATE_11AC_MAX_MCS_8,
533 DATA_RATE_11AC_MAX_MCS_9,
534 DATA_RATE_11AC_MAX_MCS_NA
535} eDataRate11ACMaxMcs;
536
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530537/* SSID broadcast type */
538typedef enum eSSIDBcastType
539{
540 eBCAST_UNKNOWN = 0,
541 eBCAST_NORMAL = 1,
542 eBCAST_HIDDEN = 2,
543} tSSIDBcastType;
544
Leo Chang6f8870f2013-03-26 18:11:36 -0700545/* MCS Based VHT rate table */
546static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
547{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530548/* MCS L80 S80 L40 S40 L20 S40*/
549 {0, {293, 325}, {135, 150}, {65, 72}},
550 {1, {585, 650}, {270, 300}, {130, 144}},
551 {2, {878, 975}, {405, 450}, {195, 217}},
552 {3, {1170, 1300}, {540, 600}, {260, 289}},
553 {4, {1755, 1950}, {810, 900}, {390, 433}},
554 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
555 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
556 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
557 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
558 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700559};
560#endif /* WLAN_FEATURE_11AC */
561
c_hpothu79aab322014-07-14 21:11:01 +0530562/*array index points to MCS and array value points respective rssi*/
563static int rssiMcsTbl[][10] =
564{
565/*MCS 0 1 2 3 4 5 6 7 8 9*/
566 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
567 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
568 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
569};
570
Jeff Johnson295189b2012-06-20 16:38:30 -0700571extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530572#ifdef FEATURE_WLAN_SCAN_PNO
573static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
574#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700575
Leo Chang9056f462013-08-01 19:21:11 -0700576#ifdef WLAN_NL80211_TESTMODE
577enum wlan_hdd_tm_attr
578{
579 WLAN_HDD_TM_ATTR_INVALID = 0,
580 WLAN_HDD_TM_ATTR_CMD = 1,
581 WLAN_HDD_TM_ATTR_DATA = 2,
582 WLAN_HDD_TM_ATTR_TYPE = 3,
583 /* keep last */
584 WLAN_HDD_TM_ATTR_AFTER_LAST,
585 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
586};
587
588enum wlan_hdd_tm_cmd
589{
590 WLAN_HDD_TM_CMD_WLAN_HB = 1,
591};
592
593#define WLAN_HDD_TM_DATA_MAX_LEN 5000
594
595static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
596{
597 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
598 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
599 .len = WLAN_HDD_TM_DATA_MAX_LEN },
600};
601#endif /* WLAN_NL80211_TESTMODE */
602
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800603#ifdef FEATURE_WLAN_CH_AVOID
604/*
605 * FUNCTION: wlan_hdd_send_avoid_freq_event
606 * This is called when wlan driver needs to send vendor specific
607 * avoid frequency range event to userspace
608 */
609int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
610 tHddAvoidFreqList *pAvoidFreqList)
611{
612 struct sk_buff *vendor_event;
613
614 ENTER();
615
616 if (!pHddCtx)
617 {
618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
619 "%s: HDD context is null", __func__);
620 return -1;
621 }
622
623 if (!pAvoidFreqList)
624 {
625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
626 "%s: pAvoidFreqList is null", __func__);
627 return -1;
628 }
629
630 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530631#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
632 NULL,
633#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800634 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530635 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800636 GFP_KERNEL);
637 if (!vendor_event)
638 {
639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
640 "%s: cfg80211_vendor_event_alloc failed", __func__);
641 return -1;
642 }
643
644 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
645 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
646
647 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
648
649 EXIT();
650 return 0;
651}
652#endif /* FEATURE_WLAN_CH_AVOID */
653
Srinivas Dasari030bad32015-02-18 23:23:54 +0530654/*
655 * FUNCTION: __wlan_hdd_cfg80211_nan_request
656 * This is called when wlan driver needs to send vendor specific
657 * nan request event.
658 */
659static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
660 struct wireless_dev *wdev,
661 const void *data, int data_len)
662{
663 tNanRequestReq nan_req;
664 VOS_STATUS status;
665 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530666 struct net_device *dev = wdev->netdev;
667 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
668 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530669 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
670
671 if (0 == data_len)
672 {
673 hddLog(VOS_TRACE_LEVEL_ERROR,
674 FL("NAN - Invalid Request, length = 0"));
675 return ret_val;
676 }
677
678 if (NULL == data)
679 {
680 hddLog(VOS_TRACE_LEVEL_ERROR,
681 FL("NAN - Invalid Request, data is NULL"));
682 return ret_val;
683 }
684
685 status = wlan_hdd_validate_context(pHddCtx);
686 if (0 != status)
687 {
688 hddLog(VOS_TRACE_LEVEL_ERROR,
689 FL("HDD context is not valid"));
690 return -EINVAL;
691 }
692
693 hddLog(LOG1, FL("Received NAN command"));
694 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
695 (tANI_U8 *)data, data_len);
696
697 /* check the NAN Capability */
698 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
699 {
700 hddLog(VOS_TRACE_LEVEL_ERROR,
701 FL("NAN is not supported by Firmware"));
702 return -EINVAL;
703 }
704
705 nan_req.request_data_len = data_len;
706 nan_req.request_data = data;
707
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530708 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530709 if (VOS_STATUS_SUCCESS == status)
710 {
711 ret_val = 0;
712 }
713 return ret_val;
714}
715
716/*
717 * FUNCTION: wlan_hdd_cfg80211_nan_request
718 * Wrapper to protect the nan vendor command from ssr
719 */
720static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
721 struct wireless_dev *wdev,
722 const void *data, int data_len)
723{
724 int ret;
725
726 vos_ssr_protect(__func__);
727 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
728 vos_ssr_unprotect(__func__);
729
730 return ret;
731}
732
733/*
734 * FUNCTION: wlan_hdd_cfg80211_nan_callback
735 * This is a callback function and it gets called
736 * when we need to report nan response event to
737 * upper layers.
738 */
739static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
740{
741 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
742 struct sk_buff *vendor_event;
743 int status;
744 tSirNanEvent *data;
745
746 ENTER();
747 if (NULL == msg)
748 {
749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
750 FL(" msg received here is null"));
751 return;
752 }
753 data = msg;
754
755 status = wlan_hdd_validate_context(pHddCtx);
756
757 if (0 != status)
758 {
759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
760 FL("HDD context is not valid"));
761 return;
762 }
763
764 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530765#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
766 NULL,
767#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530768 data->event_data_len +
769 NLMSG_HDRLEN,
770 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
771 GFP_KERNEL);
772
773 if (!vendor_event)
774 {
775 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
776 FL("cfg80211_vendor_event_alloc failed"));
777 return;
778 }
779 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
780 data->event_data_len, data->event_data))
781 {
782 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
783 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
784 kfree_skb(vendor_event);
785 return;
786 }
787 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
788 EXIT();
789}
790
791/*
792 * FUNCTION: wlan_hdd_cfg80211_nan_init
793 * This function is called to register the callback to sme layer
794 */
795inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
796{
797 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
798}
799
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530800/*
801 * define short names for the global vendor params
802 * used by __wlan_hdd_cfg80211_get_station_cmd()
803 */
804#define STATION_INVALID \
805 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
806#define STATION_INFO \
807 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
808#define STATION_ASSOC_FAIL_REASON \
809 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +0530810#define STATION_REMOTE \
811 QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530812#define STATION_MAX \
813 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
814
815static const struct nla_policy
816hdd_get_station_policy[STATION_MAX + 1] = {
817 [STATION_INFO] = {.type = NLA_FLAG},
818 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
819};
820
821/**
822 * hdd_get_station_assoc_fail() - Handle get station assoc fail
823 * @hdd_ctx: HDD context within host driver
824 * @wdev: wireless device
825 *
826 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
827 * Validate cmd attributes and send the station info to upper layers.
828 *
829 * Return: Success(0) or reason code for failure
830 */
831static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
832 hdd_adapter_t *adapter)
833{
834 struct sk_buff *skb = NULL;
835 uint32_t nl_buf_len;
836 hdd_station_ctx_t *hdd_sta_ctx;
837
838 nl_buf_len = NLMSG_HDRLEN;
839 nl_buf_len += sizeof(uint32_t);
840 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
841
842 if (!skb) {
843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
844 return -ENOMEM;
845 }
846
847 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
848
849 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
850 hdd_sta_ctx->conn_info.assoc_status_code)) {
851 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
852 goto fail;
853 }
854 return cfg80211_vendor_cmd_reply(skb);
855fail:
856 if (skb)
857 kfree_skb(skb);
858 return -EINVAL;
859}
860
861/**
862 * hdd_map_auth_type() - transform auth type specific to
863 * vendor command
864 * @auth_type: csr auth type
865 *
866 * Return: Success(0) or reason code for failure
867 */
868static int hdd_convert_auth_type(uint32_t auth_type)
869{
870 uint32_t ret_val;
871
872 switch (auth_type) {
873 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
874 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
875 break;
876 case eCSR_AUTH_TYPE_SHARED_KEY:
877 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
878 break;
879 case eCSR_AUTH_TYPE_WPA:
880 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
881 break;
882 case eCSR_AUTH_TYPE_WPA_PSK:
883 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
884 break;
885 case eCSR_AUTH_TYPE_AUTOSWITCH:
886 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
887 break;
888 case eCSR_AUTH_TYPE_WPA_NONE:
889 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
890 break;
891 case eCSR_AUTH_TYPE_RSN:
892 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
893 break;
894 case eCSR_AUTH_TYPE_RSN_PSK:
895 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
896 break;
897 case eCSR_AUTH_TYPE_FT_RSN:
898 ret_val = QCA_WLAN_AUTH_TYPE_FT;
899 break;
900 case eCSR_AUTH_TYPE_FT_RSN_PSK:
901 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
902 break;
903 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
904 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
905 break;
906 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
907 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
908 break;
909#ifdef FEATURE_WLAN_ESE
910 case eCSR_AUTH_TYPE_CCKM_WPA:
911 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
912 break;
913 case eCSR_AUTH_TYPE_CCKM_RSN:
914 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
915 break;
916#endif
917 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
918 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
919 break;
920 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
921 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
922 break;
923 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
924 case eCSR_AUTH_TYPE_FAILED:
925 case eCSR_AUTH_TYPE_NONE:
926 default:
927 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
928 break;
929 }
930 return ret_val;
931}
932
933/**
934 * hdd_map_dot_11_mode() - transform dot11mode type specific to
935 * vendor command
936 * @dot11mode: dot11mode
937 *
938 * Return: Success(0) or reason code for failure
939 */
940static int hdd_convert_dot11mode(uint32_t dot11mode)
941{
942 uint32_t ret_val;
943
944 switch (dot11mode) {
945 case eCSR_CFG_DOT11_MODE_11A:
946 ret_val = QCA_WLAN_802_11_MODE_11A;
947 break;
948 case eCSR_CFG_DOT11_MODE_11B:
949 ret_val = QCA_WLAN_802_11_MODE_11B;
950 break;
951 case eCSR_CFG_DOT11_MODE_11G:
952 ret_val = QCA_WLAN_802_11_MODE_11G;
953 break;
954 case eCSR_CFG_DOT11_MODE_11N:
955 ret_val = QCA_WLAN_802_11_MODE_11N;
956 break;
957 case eCSR_CFG_DOT11_MODE_11AC:
958 ret_val = QCA_WLAN_802_11_MODE_11AC;
959 break;
960 case eCSR_CFG_DOT11_MODE_AUTO:
961 case eCSR_CFG_DOT11_MODE_ABG:
962 default:
963 ret_val = QCA_WLAN_802_11_MODE_INVALID;
964 }
965 return ret_val;
966}
967
968/**
969 * hdd_add_tx_bitrate() - add tx bitrate attribute
970 * @skb: pointer to sk buff
971 * @hdd_sta_ctx: pointer to hdd station context
972 * @idx: attribute index
973 *
974 * Return: Success(0) or reason code for failure
975 */
976static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
977 hdd_station_ctx_t *hdd_sta_ctx,
978 int idx)
979{
980 struct nlattr *nla_attr;
981 uint32_t bitrate, bitrate_compat;
982
983 nla_attr = nla_nest_start(skb, idx);
984 if (!nla_attr)
985 goto fail;
986 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
987 bitrate = cfg80211_calculate_bitrate(&hdd_sta_ctx->conn_info.txrate);
988
989 /* report 16-bit bitrate only if we can */
990 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
991 if (bitrate > 0 &&
992 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
993 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
994 goto fail;
995 }
996 if (bitrate_compat > 0 &&
997 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
999 goto fail;
1000 }
1001 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1002 hdd_sta_ctx->conn_info.txrate.nss)) {
1003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1004 goto fail;
1005 }
1006 nla_nest_end(skb, nla_attr);
1007 return 0;
1008fail:
1009 return -EINVAL;
1010}
1011
1012/**
1013 * hdd_add_sta_info() - add station info attribute
1014 * @skb: pointer to sk buff
1015 * @hdd_sta_ctx: pointer to hdd station context
1016 * @idx: attribute index
1017 *
1018 * Return: Success(0) or reason code for failure
1019 */
1020static int32_t hdd_add_sta_info(struct sk_buff *skb,
1021 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1022{
1023 struct nlattr *nla_attr;
1024
1025 nla_attr = nla_nest_start(skb, idx);
1026 if (!nla_attr)
1027 goto fail;
1028 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
1029 (hdd_sta_ctx->conn_info.signal + 100))) {
1030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1031 goto fail;
1032 }
1033 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1034 goto fail;
1035 nla_nest_end(skb, nla_attr);
1036 return 0;
1037fail:
1038 return -EINVAL;
1039}
1040
1041/**
1042 * hdd_add_survey_info() - add survey info attribute
1043 * @skb: pointer to sk buff
1044 * @hdd_sta_ctx: pointer to hdd station context
1045 * @idx: attribute index
1046 *
1047 * Return: Success(0) or reason code for failure
1048 */
1049static int32_t hdd_add_survey_info(struct sk_buff *skb,
1050 hdd_station_ctx_t *hdd_sta_ctx,
1051 int idx)
1052{
1053 struct nlattr *nla_attr;
1054
1055 nla_attr = nla_nest_start(skb, idx);
1056 if (!nla_attr)
1057 goto fail;
1058 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1059 hdd_sta_ctx->conn_info.freq) ||
1060 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
1061 (hdd_sta_ctx->conn_info.noise + 100))) {
1062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1063 goto fail;
1064 }
1065 nla_nest_end(skb, nla_attr);
1066 return 0;
1067fail:
1068 return -EINVAL;
1069}
1070
1071/**
1072 * hdd_add_link_standard_info() - add link info attribute
1073 * @skb: pointer to sk buff
1074 * @hdd_sta_ctx: pointer to hdd station context
1075 * @idx: attribute index
1076 *
1077 * Return: Success(0) or reason code for failure
1078 */
1079static int32_t
1080hdd_add_link_standard_info(struct sk_buff *skb,
1081 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1082{
1083 struct nlattr *nla_attr;
1084
1085 nla_attr = nla_nest_start(skb, idx);
1086 if (!nla_attr)
1087 goto fail;
1088 if (nla_put(skb,
1089 NL80211_ATTR_SSID,
1090 hdd_sta_ctx->conn_info.SSID.SSID.length,
1091 hdd_sta_ctx->conn_info.SSID.SSID.ssId)) {
1092 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1093 goto fail;
1094 }
1095 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1096 goto fail;
1097 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1098 goto fail;
1099 nla_nest_end(skb, nla_attr);
1100 return 0;
1101fail:
1102 return -EINVAL;
1103}
1104
1105/**
1106 * hdd_add_ap_standard_info() - add ap info attribute
1107 * @skb: pointer to sk buff
1108 * @hdd_sta_ctx: pointer to hdd station context
1109 * @idx: attribute index
1110 *
1111 * Return: Success(0) or reason code for failure
1112 */
1113static int32_t
1114hdd_add_ap_standard_info(struct sk_buff *skb,
1115 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1116{
1117 struct nlattr *nla_attr;
1118
1119 nla_attr = nla_nest_start(skb, idx);
1120 if (!nla_attr)
1121 goto fail;
1122 if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
1123 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1124 sizeof(hdd_sta_ctx->conn_info.vht_caps),
1125 &hdd_sta_ctx->conn_info.vht_caps)) {
1126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1127 goto fail;
1128 }
1129 if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
1130 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1131 sizeof(hdd_sta_ctx->conn_info.ht_caps),
1132 &hdd_sta_ctx->conn_info.ht_caps)) {
1133 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1134 goto fail;
1135 }
1136 nla_nest_end(skb, nla_attr);
1137 return 0;
1138fail:
1139 return -EINVAL;
1140}
1141
1142/**
1143 * hdd_get_station_info() - send BSS information to supplicant
1144 * @hdd_ctx: pointer to hdd context
1145 * @adapter: pointer to adapter
1146 *
1147 * Return: 0 if success else error status
1148 */
1149static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1150 hdd_adapter_t *adapter)
1151{
1152 struct sk_buff *skb = NULL;
1153 uint8_t *tmp_hs20 = NULL;
1154 uint32_t nl_buf_len;
1155 hdd_station_ctx_t *hdd_sta_ctx;
1156
1157 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1158
1159 nl_buf_len = NLMSG_HDRLEN;
1160 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.SSID.SSID.length) +
1161 sizeof(hdd_sta_ctx->conn_info.freq) +
1162 sizeof(hdd_sta_ctx->conn_info.noise) +
1163 sizeof(hdd_sta_ctx->conn_info.signal) +
1164 (sizeof(uint32_t) * 2) +
1165 sizeof(hdd_sta_ctx->conn_info.txrate.nss) +
1166 sizeof(hdd_sta_ctx->conn_info.roam_count) +
1167 sizeof(hdd_sta_ctx->conn_info.authType) +
1168 sizeof(hdd_sta_ctx->conn_info.dot11Mode);
1169 if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
1170 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_caps);
1171 if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
1172 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_caps);
1173 if (hdd_sta_ctx->conn_info.conn_flag.hs20_present) {
1174 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->conn_info.hs20vendor_ie);
1175 nl_buf_len += (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) -
1176 1);
1177 }
1178 if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
1179 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_operation);
1180 if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
1181 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_operation);
1182
1183
1184 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1185 if (!skb) {
1186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1187 __func__, __LINE__);
1188 return -ENOMEM;
1189 }
1190
1191 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1192 LINK_INFO_STANDARD_NL80211_ATTR)) {
1193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1194 goto fail;
1195 }
1196 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1197 AP_INFO_STANDARD_NL80211_ATTR)) {
1198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1199 goto fail;
1200 }
1201 if (nla_put_u32(skb, INFO_ROAM_COUNT,
1202 hdd_sta_ctx->conn_info.roam_count) ||
1203 nla_put_u32(skb, INFO_AKM,
1204 hdd_convert_auth_type(
1205 hdd_sta_ctx->conn_info.authType)) ||
1206 nla_put_u32(skb, WLAN802_11_MODE,
1207 hdd_convert_dot11mode(
1208 hdd_sta_ctx->conn_info.dot11Mode))) {
1209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1210 goto fail;
1211 }
1212 if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
1213 if (nla_put(skb, HT_OPERATION,
1214 (sizeof(hdd_sta_ctx->conn_info.ht_operation)),
1215 &hdd_sta_ctx->conn_info.ht_operation)) {
1216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1217 goto fail;
1218 }
1219 if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
1220 if (nla_put(skb, VHT_OPERATION,
1221 (sizeof(hdd_sta_ctx->conn_info.vht_operation)),
1222 &hdd_sta_ctx->conn_info.vht_operation)) {
1223 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1224 goto fail;
1225 }
1226 if (hdd_sta_ctx->conn_info.conn_flag.hs20_present)
1227 if (nla_put(skb, AP_INFO_HS20_INDICATION,
1228 (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) - 1),
1229 tmp_hs20 + 1)) {
1230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1231 goto fail;
1232 }
1233
1234 return cfg80211_vendor_cmd_reply(skb);
1235fail:
1236 if (skb)
1237 kfree_skb(skb);
1238 return -EINVAL;
1239}
1240
1241/**
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301242 * hdd_add_survey_info_sap_get_len - get data length used in
1243 * hdd_add_survey_info_sap()
1244 *
1245 * This function calculates the data length used in hdd_add_survey_info_sap()
1246 *
1247 * Return: total data length used in hdd_add_survey_info_sap()
1248 */
1249static uint32_t hdd_add_survey_info_sap_get_len(void)
1250{
1251 return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
1252}
1253
1254/**
1255 * hdd_add_survey_info - add survey info attribute
1256 * @skb: pointer to response skb buffer
1257 * @stainfo: station information
1258 * @idx: attribute type index for nla_next_start()
1259 *
1260 * This function adds survey info attribute to response skb buffer
1261 *
1262 * Return : 0 on success and errno on failure
1263 */
1264static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
1265 struct hdd_cache_sta_info *stainfo,
1266 int idx)
1267{
1268 struct nlattr *nla_attr;
1269
1270 nla_attr = nla_nest_start(skb, idx);
1271 if (!nla_attr)
1272 goto fail;
1273 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1274 stainfo->freq)) {
1275 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1276 FL("put fail"));
1277 goto fail;
1278 }
1279 nla_nest_end(skb, nla_attr);
1280 return 0;
1281fail:
1282 return -EINVAL;
1283}
1284
1285/**
1286 * hdd_add_tx_bitrate_sap_get_len - get data length used in
1287 * hdd_add_tx_bitrate_sap()
1288 *
1289 * This function calculates the data length used in hdd_add_tx_bitrate_sap()
1290 *
1291 * Return: total data length used in hdd_add_tx_bitrate_sap()
1292 */
1293static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
1294{
1295 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
1296}
1297
1298/**
1299 * hdd_add_tx_bitrate_sap - add vht nss info attribute
1300 * @skb: pointer to response skb buffer
1301 * @stainfo: station information
1302 * @idx: attribute type index for nla_next_start()
1303 *
1304 * This function adds vht nss attribute to response skb buffer
1305 *
1306 * Return : 0 on success and errno on failure
1307 */
1308static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
1309 struct hdd_cache_sta_info *stainfo,
1310 int idx)
1311{
1312 struct nlattr *nla_attr;
1313
1314 nla_attr = nla_nest_start(skb, idx);
1315 if (!nla_attr)
1316 goto fail;
1317
1318 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1319 stainfo->nss)) {
1320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1321 FL("put fail"));
1322 goto fail;
1323 }
1324 nla_nest_end(skb, nla_attr);
1325 return 0;
1326fail:
1327 return -EINVAL;
1328}
1329
1330/**
1331 * hdd_add_sta_info_sap_get_len - get data length used in
1332 * hdd_add_sta_info_sap()
1333 *
1334 * This function calculates the data length used in hdd_add_sta_info_sap()
1335 *
1336 * Return: total data length used in hdd_add_sta_info_sap()
1337 */
1338static uint32_t hdd_add_sta_info_sap_get_len(void)
1339{
1340 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
1341 hdd_add_tx_bitrate_sap_get_len());
1342}
1343
1344/**
1345 * hdd_add_sta_info_sap - add sta signal info attribute
1346 * @skb: pointer to response skb buffer
1347 * @rssi: peer rssi value
1348 * @stainfo: station information
1349 * @idx: attribute type index for nla_next_start()
1350 *
1351 * This function adds sta signal attribute to response skb buffer
1352 *
1353 * Return : 0 on success and errno on failure
1354 */
1355static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
1356 struct hdd_cache_sta_info *stainfo, int idx)
1357{
1358 struct nlattr *nla_attr;
1359
1360 nla_attr = nla_nest_start(skb, idx);
1361 if (!nla_attr)
1362 goto fail;
1363
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05301364 /* upperlayer expects positive rssi value */
1365 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, (rssi + 96))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301366 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1367 FL("put fail"));
1368 goto fail;
1369 }
1370 if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE)) {
1371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1372 FL("put fail"));
1373 goto fail;
1374 }
1375
1376 nla_nest_end(skb, nla_attr);
1377 return 0;
1378fail:
1379 return -EINVAL;
1380}
1381
1382/**
1383 * hdd_add_link_standard_info_sap_get_len - get data length used in
1384 * hdd_add_link_standard_info_sap()
1385 *
1386 * This function calculates the data length used in
1387 * hdd_add_link_standard_info_sap()
1388 *
1389 * Return: total data length used in hdd_add_link_standard_info_sap()
1390 */
1391static uint32_t hdd_add_link_standard_info_sap_get_len(void)
1392{
1393 return ((NLA_HDRLEN) +
1394 hdd_add_survey_info_sap_get_len() +
1395 hdd_add_sta_info_sap_get_len() +
1396 (sizeof(uint32_t) + NLA_HDRLEN));
1397}
1398
1399/**
1400 * hdd_add_link_standard_info_sap - add add link info attribut
1401 * @skb: pointer to response skb buffer
1402 * @stainfo: station information
1403 * @idx: attribute type index for nla_next_start()
1404 *
1405 * This function adds link info attribut to response skb buffer
1406 *
1407 * Return : 0 on success and errno on failure
1408 */
1409static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
1410 struct hdd_cache_sta_info *stainfo,
1411 int idx)
1412{
1413 struct nlattr *nla_attr;
1414
1415 nla_attr = nla_nest_start(skb, idx);
1416 if (!nla_attr)
1417 goto fail;
1418 if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
1419 goto fail;
1420 if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
1421 goto fail;
1422
1423 if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
1424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1425 FL("put fail"));
1426 goto fail;
1427 }
1428
1429 nla_nest_end(skb, nla_attr);
1430 return 0;
1431fail:
1432 return -EINVAL;
1433}
1434
1435/**
1436 * hdd_add_ap_standard_info_sap_get_len - get data length used in
1437 * hdd_add_ap_standard_info_sap()
1438 * @stainfo: station information
1439 *
1440 * This function calculates the data length used in
1441 * hdd_add_ap_standard_info_sap()
1442 *
1443 * Return: total data length used in hdd_add_ap_standard_info_sap()
1444 */
1445static uint32_t hdd_add_ap_standard_info_sap_get_len(
1446 struct hdd_cache_sta_info *stainfo)
1447{
1448 uint32_t len;
1449
1450 len = NLA_HDRLEN;
1451 if (stainfo->vht_present)
1452 len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
1453 if (stainfo->ht_present)
1454 len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
1455
1456 return len;
1457}
1458
1459/**
1460 * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
1461 * @skb: pointer to response skb buffer
1462 * @stainfo: station information
1463 * @idx: attribute type index for nla_next_start()
1464 *
1465 * This function adds HT and VHT info attributes to response skb buffer
1466 *
1467 * Return : 0 on success and errno on failure
1468 */
1469static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
1470 struct hdd_cache_sta_info *stainfo,
1471 int idx)
1472{
1473 struct nlattr *nla_attr;
1474
1475 nla_attr = nla_nest_start(skb, idx);
1476 if (!nla_attr)
1477 goto fail;
1478
1479 if (stainfo->vht_present) {
1480 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1481 sizeof(stainfo->vht_caps),
1482 &stainfo->vht_caps)) {
1483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1484 FL("put fail"));
1485 goto fail;
1486 }
1487 }
1488 if (stainfo->ht_present) {
1489 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1490 sizeof(stainfo->ht_caps),
1491 &stainfo->ht_caps)) {
1492 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1493 FL("put fail"));
1494 goto fail;
1495 }
1496 }
1497 nla_nest_end(skb, nla_attr);
1498 return 0;
1499fail:
1500 return -EINVAL;
1501}
1502
1503/**
1504 * hdd_decode_ch_width - decode channel band width based
1505 * @ch_width: encoded enum value holding channel band width
1506 *
1507 * This function decodes channel band width from the given encoded enum value.
1508 *
1509 * Returns: decoded channel band width.
1510 */
1511static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
1512{
1513 switch (ch_width) {
1514 case 0:
1515 return 20;
1516 case 1:
1517 return 40;
1518 case 2:
1519 return 80;
1520 default:
1521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1522 "invalid enum: %d", ch_width);
1523 return 20;
1524 }
1525}
1526
1527/**
1528 * hdd_get_cached_station_remote() - get cached(deleted) peer's info
1529 * @hdd_ctx: hdd context
1530 * @adapter: hostapd interface
1531 * @mac_addr: mac address of requested peer
1532 *
1533 * This function collect and indicate the cached(deleted) peer's info
1534 *
1535 * Return: 0 on success, otherwise error value
1536 */
1537static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx,
1538 hdd_adapter_t *adapter,
1539 v_MACADDR_t mac_addr)
1540{
1541 struct hdd_cache_sta_info *stainfo;
1542 struct sk_buff *skb = NULL;
1543 uint32_t nl_buf_len;
1544 uint8_t cw;
1545 ptSapContext sap_ctx;
1546 v_CONTEXT_t vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
1547
1548 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
1549 if(sap_ctx == NULL){
1550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1551 FL("psapCtx is NULL"));
1552 return -ENOENT;
1553 }
1554
1555 stainfo = hdd_get_cache_stainfo(sap_ctx->cache_sta_info,
1556 mac_addr.bytes);
1557 if (!stainfo) {
1558 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1559 "peer " MAC_ADDRESS_STR " not found",
1560 MAC_ADDR_ARRAY(mac_addr.bytes));
1561 return -EINVAL;
1562 }
1563 if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE) {
1564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1565 "peer " MAC_ADDRESS_STR " is in connected state",
1566 MAC_ADDR_ARRAY(mac_addr.bytes));
1567 return -EINVAL;
1568 }
1569
1570
1571 nl_buf_len = NLMSG_HDRLEN + hdd_add_link_standard_info_sap_get_len() +
1572 hdd_add_ap_standard_info_sap_get_len(stainfo) +
1573 (sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
1574 (sizeof(cw) + NLA_HDRLEN) +
1575 (sizeof(stainfo->rx_rate) + NLA_HDRLEN);
1576
1577 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1578 if (!skb) {
1579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "cfg80211_vendor_cmd_alloc_reply_skb failed");
1580 return -ENOMEM;
1581 }
1582
1583 if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
1584 LINK_INFO_STANDARD_NL80211_ATTR)) {
1585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "link standard put fail");
1586 goto fail;
1587 }
1588
1589 if (hdd_add_ap_standard_info_sap(skb, stainfo,
1590 AP_INFO_STANDARD_NL80211_ATTR)) {
1591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ap standard put fail");
1592 goto fail;
1593 }
1594
1595 /* upper layer expects decoded channel BW */
1596 cw = hdd_decode_ch_width(stainfo->ch_width);
1597 if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE, stainfo->dot11_mode) ||
1598 nla_put_u8(skb, REMOTE_CH_WIDTH, cw)) {
1599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "remote ch put fail");
1600 goto fail;
1601 }
Hanumanth Reddy Pothula504fe152018-01-02 20:41:03 +05301602 if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, (stainfo->rx_rate * 100))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "rx rate put fail");
1604 goto fail;
1605 }
1606
1607 vos_mem_zero(stainfo, sizeof(*stainfo));
1608
1609 return cfg80211_vendor_cmd_reply(skb);
1610fail:
1611 if (skb)
1612 kfree_skb(skb);
1613
1614 return -EINVAL;
1615}
1616
1617/**
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301618 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1619 * @wiphy: corestack handler
1620 * @wdev: wireless device
1621 * @data: data
1622 * @data_len: data length
1623 *
1624 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1625 * Validate cmd attributes and send the station info to upper layers.
1626 *
1627 * Return: Success(0) or reason code for failure
1628 */
1629static int32_t
1630__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1631 struct wireless_dev *wdev,
1632 const void *data,
1633 int data_len)
1634{
1635 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1636 struct net_device *dev = wdev->netdev;
1637 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1638 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1639 int32_t status;
1640
1641 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1642 if (VOS_FTM_MODE == hdd_get_conparam()) {
1643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1644 status = -EPERM;
1645 goto out;
1646 }
1647
1648 status = wlan_hdd_validate_context(hdd_ctx);
1649 if (0 != status)
1650 goto out;
1651
1652
1653 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1654 data, data_len, NULL);
1655 if (status) {
1656 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1657 goto out;
1658 }
1659
1660 /* Parse and fetch Command Type*/
1661 if (tb[STATION_INFO]) {
1662 status = hdd_get_station_info(hdd_ctx, adapter);
1663 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1664 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301665 } else if (tb[STATION_REMOTE]) {
1666 v_MACADDR_t mac_addr;
1667
1668 if (adapter->device_mode != WLAN_HDD_SOFTAP &&
1669 adapter->device_mode != WLAN_HDD_P2P_GO) {
1670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"invalid device_mode:%d",
1671 adapter->device_mode);
1672 status = -EINVAL;
1673 goto out;
1674 }
1675
1676 nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
1677 VOS_MAC_ADDRESS_LEN);
1678
1679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "STATION_REMOTE "MAC_ADDRESS_STR"",
1680 MAC_ADDR_ARRAY(mac_addr.bytes));
1681
1682 status = hdd_get_cached_station_remote(hdd_ctx, adapter,
1683 mac_addr);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301684 } else {
1685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1686 status = -EINVAL;
1687 goto out;
1688 }
1689 EXIT();
1690out:
1691 return status;
1692}
1693
1694/**
1695 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1696 * @wiphy: corestack handler
1697 * @wdev: wireless device
1698 * @data: data
1699 * @data_len: data length
1700 *
1701 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1702 * Validate cmd attributes and send the station info to upper layers.
1703 *
1704 * Return: Success(0) or reason code for failure
1705 */
1706static int32_t
1707hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1708 struct wireless_dev *wdev,
1709 const void *data,
1710 int data_len)
1711{
1712 int ret;
1713
1714 vos_ssr_protect(__func__);
1715 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1716 vos_ssr_unprotect(__func__);
1717
1718 return ret;
1719}
1720
1721/*
1722 * undef short names defined for get station command
1723 * used by __wlan_hdd_cfg80211_get_station_cmd()
1724 */
1725#undef STATION_INVALID
1726#undef STATION_INFO
1727#undef STATION_ASSOC_FAIL_REASON
1728#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301729
Sunil Duttc69bccb2014-05-26 21:30:20 +05301730#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1731
1732static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1733 struct sk_buff *vendor_event)
1734{
1735 if (nla_put_u8(vendor_event,
1736 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1737 stats->rate.preamble) ||
1738 nla_put_u8(vendor_event,
1739 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1740 stats->rate.nss) ||
1741 nla_put_u8(vendor_event,
1742 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1743 stats->rate.bw) ||
1744 nla_put_u8(vendor_event,
1745 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1746 stats->rate.rateMcsIdx) ||
1747 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1748 stats->rate.bitrate ) ||
1749 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1750 stats->txMpdu ) ||
1751 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1752 stats->rxMpdu ) ||
1753 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1754 stats->mpduLost ) ||
1755 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1756 stats->retries) ||
1757 nla_put_u32(vendor_event,
1758 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1759 stats->retriesShort ) ||
1760 nla_put_u32(vendor_event,
1761 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1762 stats->retriesLong))
1763 {
1764 hddLog(VOS_TRACE_LEVEL_ERROR,
1765 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1766 return FALSE;
1767 }
1768 return TRUE;
1769}
1770
1771static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1772 struct sk_buff *vendor_event)
1773{
1774 u32 i = 0;
1775 struct nlattr *rateInfo;
1776 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1777 stats->type) ||
1778 nla_put(vendor_event,
1779 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1780 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1781 nla_put_u32(vendor_event,
1782 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1783 stats->capabilities) ||
1784 nla_put_u32(vendor_event,
1785 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1786 stats->numRate))
1787 {
1788 hddLog(VOS_TRACE_LEVEL_ERROR,
1789 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1790 goto error;
1791 }
1792
1793 rateInfo = nla_nest_start(vendor_event,
1794 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301795 if(!rateInfo)
1796 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301797 for (i = 0; i < stats->numRate; i++)
1798 {
1799 struct nlattr *rates;
1800 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1801 stats->rateStats +
1802 (i * sizeof(tSirWifiRateStat)));
1803 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301804 if(!rates)
1805 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301806
1807 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1808 {
1809 hddLog(VOS_TRACE_LEVEL_ERROR,
1810 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1811 return FALSE;
1812 }
1813 nla_nest_end(vendor_event, rates);
1814 }
1815 nla_nest_end(vendor_event, rateInfo);
1816
1817 return TRUE;
1818error:
1819 return FALSE;
1820}
1821
1822static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1823 struct sk_buff *vendor_event)
1824{
1825 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1826 stats->ac ) ||
1827 nla_put_u32(vendor_event,
1828 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1829 stats->txMpdu ) ||
1830 nla_put_u32(vendor_event,
1831 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1832 stats->rxMpdu ) ||
1833 nla_put_u32(vendor_event,
1834 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1835 stats->txMcast ) ||
1836 nla_put_u32(vendor_event,
1837 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1838 stats->rxMcast ) ||
1839 nla_put_u32(vendor_event,
1840 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1841 stats->rxAmpdu ) ||
1842 nla_put_u32(vendor_event,
1843 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1844 stats->txAmpdu ) ||
1845 nla_put_u32(vendor_event,
1846 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1847 stats->mpduLost )||
1848 nla_put_u32(vendor_event,
1849 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1850 stats->retries ) ||
1851 nla_put_u32(vendor_event,
1852 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1853 stats->retriesShort ) ||
1854 nla_put_u32(vendor_event,
1855 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1856 stats->retriesLong ) ||
1857 nla_put_u32(vendor_event,
1858 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1859 stats->contentionTimeMin ) ||
1860 nla_put_u32(vendor_event,
1861 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1862 stats->contentionTimeMax ) ||
1863 nla_put_u32(vendor_event,
1864 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1865 stats->contentionTimeAvg ) ||
1866 nla_put_u32(vendor_event,
1867 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1868 stats->contentionNumSamples ))
1869 {
1870 hddLog(VOS_TRACE_LEVEL_ERROR,
1871 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1872 return FALSE;
1873 }
1874 return TRUE;
1875}
1876
1877static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1878 struct sk_buff *vendor_event)
1879{
Dino Myclec8f3f332014-07-21 16:48:27 +05301880 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301881 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1882 nla_put(vendor_event,
1883 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
1884 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
1885 nla_put_u32(vendor_event,
1886 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
1887 stats->state ) ||
1888 nla_put_u32(vendor_event,
1889 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
1890 stats->roaming ) ||
1891 nla_put_u32(vendor_event,
1892 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
1893 stats->capabilities ) ||
1894 nla_put(vendor_event,
1895 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
1896 strlen(stats->ssid), stats->ssid) ||
1897 nla_put(vendor_event,
1898 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
1899 WNI_CFG_BSSID_LEN, stats->bssid) ||
1900 nla_put(vendor_event,
1901 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
1902 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
1903 nla_put(vendor_event,
1904 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
1905 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
1906 )
1907 {
1908 hddLog(VOS_TRACE_LEVEL_ERROR,
1909 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1910 return FALSE;
1911 }
1912 return TRUE;
1913}
1914
Dino Mycle3b9536d2014-07-09 22:05:24 +05301915static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
1916 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301917 struct sk_buff *vendor_event)
1918{
1919 int i = 0;
1920 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301921 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1922 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301923 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301924
Sunil Duttc69bccb2014-05-26 21:30:20 +05301925 if (FALSE == put_wifi_interface_info(
1926 &pWifiIfaceStat->info,
1927 vendor_event))
1928 {
1929 hddLog(VOS_TRACE_LEVEL_ERROR,
1930 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1931 return FALSE;
1932
1933 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05301934 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
1935 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
1936 if (NULL == pWifiIfaceStatTL)
1937 {
1938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1939 return FALSE;
1940 }
1941
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301942 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1943 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1944 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1945 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1946
1947 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1948 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1949 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1950 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301951
1952 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1953 {
1954 if (VOS_STATUS_SUCCESS ==
1955 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1956 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1957 {
1958 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1959 * obtained from TL structure
1960 */
1961
1962 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1963 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301964 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1965
Srinivas Dasari98947432014-11-07 19:41:24 +05301966 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1967 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1968 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1969 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1970 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1971 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1972 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1973 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301974
Srinivas Dasari98947432014-11-07 19:41:24 +05301975 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1976 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1977 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1978 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1979 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1980 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1981 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1982 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301983
Srinivas Dasari98947432014-11-07 19:41:24 +05301984 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1985 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1986 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1987 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1988 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1989 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1990 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1991 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301992 }
1993 else
1994 {
1995 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1996 }
1997
Dino Mycle3b9536d2014-07-09 22:05:24 +05301998 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1999 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
2000 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
2001 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
2002 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
2003 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
2004 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
2005 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
2006 }
2007 else
2008 {
2009 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
2010 }
2011
2012
Sunil Duttc69bccb2014-05-26 21:30:20 +05302013
2014 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302015 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2016 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
2017 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302018 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
2019 pWifiIfaceStat->beaconRx) ||
2020 nla_put_u32(vendor_event,
2021 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
2022 pWifiIfaceStat->mgmtRx) ||
2023 nla_put_u32(vendor_event,
2024 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
2025 pWifiIfaceStat->mgmtActionRx) ||
2026 nla_put_u32(vendor_event,
2027 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
2028 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302029 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302030 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
2031 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302032 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302033 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
2034 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302035 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302036 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
2037 pWifiIfaceStat->rssiAck))
2038 {
2039 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302040 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2041 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302042 return FALSE;
2043 }
2044
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302045#ifdef FEATURE_EXT_LL_STAT
2046 /*
2047 * Ensure when EXT_LL_STAT is supported by both host and fwr,
2048 * then host should send Leaky AP stats to upper layer,
2049 * otherwise no need to send these stats.
2050 */
2051 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
2052 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
2053 )
2054 {
2055 hddLog(VOS_TRACE_LEVEL_INFO,
2056 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
2057 pWifiIfaceStat->leakyApStat.is_leaky_ap,
2058 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
2059 pWifiIfaceStat->leakyApStat.rx_leak_window,
2060 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
2061 if (nla_put_u32(vendor_event,
2062 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
2063 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
2064 nla_put_u32(vendor_event,
2065 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
2066 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
2067 nla_put_u32(vendor_event,
2068 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
2069 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05302070 hdd_wlan_nla_put_u64(vendor_event,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302071 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
2072 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
2073 {
2074 hddLog(VOS_TRACE_LEVEL_ERROR,
2075 FL("EXT_LL_STAT put fail"));
2076 vos_mem_free(pWifiIfaceStatTL);
2077 return FALSE;
2078 }
2079 }
2080#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05302081 wmmInfo = nla_nest_start(vendor_event,
2082 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302083 if(!wmmInfo)
2084 {
2085 vos_mem_free(pWifiIfaceStatTL);
2086 return FALSE;
2087 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302088 for (i = 0; i < WIFI_AC_MAX; i++)
2089 {
2090 struct nlattr *wmmStats;
2091 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302092 if(!wmmStats)
2093 {
2094 vos_mem_free(pWifiIfaceStatTL);
2095 return FALSE;
2096 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302097 if (FALSE == put_wifi_wmm_ac_stat(
2098 &pWifiIfaceStat->AccessclassStats[i],
2099 vendor_event))
2100 {
2101 hddLog(VOS_TRACE_LEVEL_ERROR,
2102 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05302103 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302104 return FALSE;
2105 }
2106
2107 nla_nest_end(vendor_event, wmmStats);
2108 }
2109 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05302110 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302111 return TRUE;
2112}
2113
2114static tSirWifiInterfaceMode
2115 hdd_map_device_to_ll_iface_mode ( int deviceMode )
2116{
2117 switch (deviceMode)
2118 {
2119 case WLAN_HDD_INFRA_STATION:
2120 return WIFI_INTERFACE_STA;
2121 case WLAN_HDD_SOFTAP:
2122 return WIFI_INTERFACE_SOFTAP;
2123 case WLAN_HDD_P2P_CLIENT:
2124 return WIFI_INTERFACE_P2P_CLIENT;
2125 case WLAN_HDD_P2P_GO:
2126 return WIFI_INTERFACE_P2P_GO;
2127 case WLAN_HDD_IBSS:
2128 return WIFI_INTERFACE_IBSS;
2129 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05302130 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302131 }
2132}
2133
2134static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
2135 tpSirWifiInterfaceInfo pInfo)
2136{
2137 v_U8_t *staMac = NULL;
2138 hdd_station_ctx_t *pHddStaCtx;
2139 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2140 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
2141
2142 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
2143
2144 vos_mem_copy(pInfo->macAddr,
2145 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
2146
2147 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2148 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
2149 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
2150 {
2151 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2152 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
2153 {
2154 pInfo->state = WIFI_DISCONNECTED;
2155 }
2156 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
2157 {
2158 hddLog(VOS_TRACE_LEVEL_ERROR,
2159 "%s: Session ID %d, Connection is in progress", __func__,
2160 pAdapter->sessionId);
2161 pInfo->state = WIFI_ASSOCIATING;
2162 }
2163 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
2164 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
2165 {
2166 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
2167 hddLog(VOS_TRACE_LEVEL_ERROR,
2168 "%s: client " MAC_ADDRESS_STR
2169 " is in the middle of WPS/EAPOL exchange.", __func__,
2170 MAC_ADDR_ARRAY(staMac));
2171 pInfo->state = WIFI_AUTHENTICATING;
2172 }
2173 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
2174 {
2175 pInfo->state = WIFI_ASSOCIATED;
2176 vos_mem_copy(pInfo->bssid,
2177 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
2178 vos_mem_copy(pInfo->ssid,
2179 pHddStaCtx->conn_info.SSID.SSID.ssId,
2180 pHddStaCtx->conn_info.SSID.SSID.length);
2181 //NULL Terminate the string.
2182 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
2183 }
2184 }
2185 vos_mem_copy(pInfo->countryStr,
2186 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2187
2188 vos_mem_copy(pInfo->apCountryStr,
2189 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2190
2191 return TRUE;
2192}
2193
2194/*
2195 * hdd_link_layer_process_peer_stats () - This function is called after
2196 * receiving Link Layer Peer statistics from FW.This function converts
2197 * the firmware data to the NL data and sends the same to the kernel/upper
2198 * layers.
2199 */
2200static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
2201 v_VOID_t *pData)
2202{
2203 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302204 tpSirWifiPeerStat pWifiPeerStat;
2205 tpSirWifiPeerInfo pWifiPeerInfo;
2206 struct nlattr *peerInfo;
2207 struct sk_buff *vendor_event;
2208 int status, i;
2209
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302210 ENTER();
2211
Sunil Duttc69bccb2014-05-26 21:30:20 +05302212 status = wlan_hdd_validate_context(pHddCtx);
2213 if (0 != status)
2214 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302215 return;
2216 }
2217
2218 pWifiPeerStat = (tpSirWifiPeerStat) pData;
2219
2220 hddLog(VOS_TRACE_LEVEL_INFO,
2221 "LL_STATS_PEER_ALL : numPeers %u",
2222 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302223 /*
2224 * Allocate a size of 4096 for the peer stats comprising
2225 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
2226 * sizeof (tSirWifiRateStat).Each field is put with an
2227 * NL attribute.The size of 4096 is considered assuming
2228 * that number of rates shall not exceed beyond 50 with
2229 * the sizeof (tSirWifiRateStat) being 32.
2230 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302231 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2232 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302233 if (!vendor_event)
2234 {
2235 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302236 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05302237 __func__);
2238 return;
2239 }
2240 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302241 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2242 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
2243 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302244 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
2245 pWifiPeerStat->numPeers))
2246 {
2247 hddLog(VOS_TRACE_LEVEL_ERROR,
2248 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
2249 kfree_skb(vendor_event);
2250 return;
2251 }
2252
2253 peerInfo = nla_nest_start(vendor_event,
2254 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302255 if(!peerInfo)
2256 {
2257 hddLog(VOS_TRACE_LEVEL_ERROR,
2258 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
2259 __func__);
2260 kfree_skb(vendor_event);
2261 return;
2262 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302263
2264 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2265 pWifiPeerStat->peerInfo);
2266
2267 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
2268 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302269 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302270 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302271
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302272 if(!peers)
2273 {
2274 hddLog(VOS_TRACE_LEVEL_ERROR,
2275 "%s: peer stats put fail",
2276 __func__);
2277 kfree_skb(vendor_event);
2278 return;
2279 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302280 if (FALSE == put_wifi_peer_info(
2281 pWifiPeerInfo, vendor_event))
2282 {
2283 hddLog(VOS_TRACE_LEVEL_ERROR,
2284 "%s: put_wifi_peer_info put fail", __func__);
2285 kfree_skb(vendor_event);
2286 return;
2287 }
2288
2289 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2290 pWifiPeerStat->peerInfo +
2291 (i * sizeof(tSirWifiPeerInfo)) +
2292 (numRate * sizeof (tSirWifiRateStat)));
2293 nla_nest_end(vendor_event, peers);
2294 }
2295 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302296 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302297 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302298}
2299
2300/*
2301 * hdd_link_layer_process_iface_stats () - This function is called after
2302 * receiving Link Layer Interface statistics from FW.This function converts
2303 * the firmware data to the NL data and sends the same to the kernel/upper
2304 * layers.
2305 */
2306static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
2307 v_VOID_t *pData)
2308{
2309 tpSirWifiIfaceStat pWifiIfaceStat;
2310 struct sk_buff *vendor_event;
2311 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2312 int status;
2313
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302314 ENTER();
2315
Sunil Duttc69bccb2014-05-26 21:30:20 +05302316 status = wlan_hdd_validate_context(pHddCtx);
2317 if (0 != status)
2318 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302319 return;
2320 }
2321 /*
2322 * Allocate a size of 4096 for the interface stats comprising
2323 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
2324 * assuming that all these fit with in the limit.Please take
2325 * a call on the limit based on the data requirements on
2326 * interface statistics.
2327 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302328 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2329 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302330 if (!vendor_event)
2331 {
2332 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302333 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302334 return;
2335 }
2336
2337 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
2338
Dino Mycle3b9536d2014-07-09 22:05:24 +05302339
2340 if (FALSE == hdd_get_interface_info( pAdapter,
2341 &pWifiIfaceStat->info))
2342 {
2343 hddLog(VOS_TRACE_LEVEL_ERROR,
2344 FL("hdd_get_interface_info get fail") );
2345 kfree_skb(vendor_event);
2346 return;
2347 }
2348
2349 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
2350 vendor_event))
2351 {
2352 hddLog(VOS_TRACE_LEVEL_ERROR,
2353 FL("put_wifi_iface_stats fail") );
2354 kfree_skb(vendor_event);
2355 return;
2356 }
2357
Sunil Duttc69bccb2014-05-26 21:30:20 +05302358 hddLog(VOS_TRACE_LEVEL_INFO,
2359 "WMI_LINK_STATS_IFACE Data");
2360
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302361 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302362
2363 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302364}
2365
2366/*
2367 * hdd_link_layer_process_radio_stats () - This function is called after
2368 * receiving Link Layer Radio statistics from FW.This function converts
2369 * the firmware data to the NL data and sends the same to the kernel/upper
2370 * layers.
2371 */
2372static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
2373 v_VOID_t *pData)
2374{
2375 int status, i;
2376 tpSirWifiRadioStat pWifiRadioStat;
2377 tpSirWifiChannelStats pWifiChannelStats;
2378 struct sk_buff *vendor_event;
2379 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2380 struct nlattr *chList;
2381
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302382 ENTER();
2383
Sunil Duttc69bccb2014-05-26 21:30:20 +05302384 status = wlan_hdd_validate_context(pHddCtx);
2385 if (0 != status)
2386 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302387 return;
2388 }
2389 pWifiRadioStat = (tpSirWifiRadioStat) pData;
2390
2391 hddLog(VOS_TRACE_LEVEL_INFO,
2392 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302393 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05302394 " radio is %d onTime is %u "
2395 " txTime is %u rxTime is %u "
2396 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05302397 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05302398 " onTimePnoScan is %u onTimeHs20 is %u "
2399 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302400 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302401 pWifiRadioStat->radio, pWifiRadioStat->onTime,
2402 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
2403 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302404 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302405 pWifiRadioStat->onTimeRoamScan,
2406 pWifiRadioStat->onTimePnoScan,
2407 pWifiRadioStat->onTimeHs20,
2408 pWifiRadioStat->numChannels);
2409 /*
2410 * Allocate a size of 4096 for the Radio stats comprising
2411 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
2412 * (tSirWifiChannelStats).Each channel data is put with an
2413 * NL attribute.The size of 4096 is considered assuming that
2414 * number of channels shall not exceed beyond 60 with the
2415 * sizeof (tSirWifiChannelStats) being 24 bytes.
2416 */
2417
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302418 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2419 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302420 if (!vendor_event)
2421 {
2422 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302423 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302424 return;
2425 }
2426
2427 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302428 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2429 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2430 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302431 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2432 pWifiRadioStat->radio) ||
2433 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302434 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2435 NUM_RADIOS) ||
2436 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302437 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2438 pWifiRadioStat->onTime) ||
2439 nla_put_u32(vendor_event,
2440 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2441 pWifiRadioStat->txTime) ||
2442 nla_put_u32(vendor_event,
2443 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2444 pWifiRadioStat->rxTime) ||
2445 nla_put_u32(vendor_event,
2446 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2447 pWifiRadioStat->onTimeScan) ||
2448 nla_put_u32(vendor_event,
2449 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2450 pWifiRadioStat->onTimeNbd) ||
2451 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302452 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2453 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302454 nla_put_u32(vendor_event,
2455 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2456 pWifiRadioStat->onTimeRoamScan) ||
2457 nla_put_u32(vendor_event,
2458 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2459 pWifiRadioStat->onTimePnoScan) ||
2460 nla_put_u32(vendor_event,
2461 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2462 pWifiRadioStat->onTimeHs20) ||
2463 nla_put_u32(vendor_event,
2464 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2465 pWifiRadioStat->numChannels))
2466 {
2467 hddLog(VOS_TRACE_LEVEL_ERROR,
2468 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2469 kfree_skb(vendor_event);
2470 return ;
2471 }
2472
2473 chList = nla_nest_start(vendor_event,
2474 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302475 if(!chList)
2476 {
2477 hddLog(VOS_TRACE_LEVEL_ERROR,
2478 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2479 __func__);
2480 kfree_skb(vendor_event);
2481 return;
2482 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302483 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2484 {
2485 struct nlattr *chInfo;
2486
2487 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2488 pWifiRadioStat->channels +
2489 (i * sizeof(tSirWifiChannelStats)));
2490
Sunil Duttc69bccb2014-05-26 21:30:20 +05302491 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302492 if(!chInfo)
2493 {
2494 hddLog(VOS_TRACE_LEVEL_ERROR,
2495 "%s: failed to put chInfo",
2496 __func__);
2497 kfree_skb(vendor_event);
2498 return;
2499 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302500
2501 if (nla_put_u32(vendor_event,
2502 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2503 pWifiChannelStats->channel.width) ||
2504 nla_put_u32(vendor_event,
2505 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2506 pWifiChannelStats->channel.centerFreq) ||
2507 nla_put_u32(vendor_event,
2508 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2509 pWifiChannelStats->channel.centerFreq0) ||
2510 nla_put_u32(vendor_event,
2511 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2512 pWifiChannelStats->channel.centerFreq1) ||
2513 nla_put_u32(vendor_event,
2514 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2515 pWifiChannelStats->onTime) ||
2516 nla_put_u32(vendor_event,
2517 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2518 pWifiChannelStats->ccaBusyTime))
2519 {
2520 hddLog(VOS_TRACE_LEVEL_ERROR,
2521 FL("cfg80211_vendor_event_alloc failed") );
2522 kfree_skb(vendor_event);
2523 return ;
2524 }
2525 nla_nest_end(vendor_event, chInfo);
2526 }
2527 nla_nest_end(vendor_event, chList);
2528
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302529 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302530
2531 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302532 return;
2533}
2534
2535/*
2536 * hdd_link_layer_stats_ind_callback () - This function is called after
2537 * receiving Link Layer indications from FW.This callback converts the firmware
2538 * data to the NL data and send the same to the kernel/upper layers.
2539 */
2540static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2541 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302542 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302543{
Dino Mycled3d50022014-07-07 12:58:25 +05302544 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2545 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302546 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302547 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302548 int status;
2549
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302550 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302551
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302552 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302553 if (0 != status)
2554 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302555 return;
2556 }
2557
Dino Mycled3d50022014-07-07 12:58:25 +05302558 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2559 if (NULL == pAdapter)
2560 {
2561 hddLog(VOS_TRACE_LEVEL_ERROR,
2562 FL(" MAC address %pM does not exist with host"),
2563 macAddr);
2564 return;
2565 }
2566
Sunil Duttc69bccb2014-05-26 21:30:20 +05302567 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302568 "%s: Interface: %s LLStats indType: %d", __func__,
2569 pAdapter->dev->name, indType);
2570
Sunil Duttc69bccb2014-05-26 21:30:20 +05302571 switch (indType)
2572 {
2573 case SIR_HAL_LL_STATS_RESULTS_RSP:
2574 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302575 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302576 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2577 "respId = %u, moreResultToFollow = %u",
2578 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2579 macAddr, linkLayerStatsResults->respId,
2580 linkLayerStatsResults->moreResultToFollow);
2581
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302582 spin_lock(&hdd_context_lock);
2583 context = &pHddCtx->ll_stats_context;
2584 /* validate response received from target */
2585 if ((context->request_id != linkLayerStatsResults->respId) ||
2586 !(context->request_bitmap & linkLayerStatsResults->paramId))
2587 {
2588 spin_unlock(&hdd_context_lock);
2589 hddLog(LOGE,
2590 FL("Error : Request id %d response id %d request bitmap 0x%x"
2591 "response bitmap 0x%x"),
2592 context->request_id, linkLayerStatsResults->respId,
2593 context->request_bitmap, linkLayerStatsResults->paramId);
2594 return;
2595 }
2596 spin_unlock(&hdd_context_lock);
2597
Sunil Duttc69bccb2014-05-26 21:30:20 +05302598 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2599 {
2600 hdd_link_layer_process_radio_stats(pAdapter,
2601 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302602 spin_lock(&hdd_context_lock);
2603 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2604 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302605 }
2606 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2607 {
2608 hdd_link_layer_process_iface_stats(pAdapter,
2609 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302610 spin_lock(&hdd_context_lock);
2611 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2612 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302613 }
2614 else if ( linkLayerStatsResults->paramId &
2615 WMI_LINK_STATS_ALL_PEER )
2616 {
2617 hdd_link_layer_process_peer_stats(pAdapter,
2618 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302619 spin_lock(&hdd_context_lock);
2620 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2621 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302622 } /* WMI_LINK_STATS_ALL_PEER */
2623 else
2624 {
2625 hddLog(VOS_TRACE_LEVEL_ERROR,
2626 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2627 }
2628
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302629 spin_lock(&hdd_context_lock);
2630 /* complete response event if all requests are completed */
2631 if (0 == context->request_bitmap)
2632 complete(&context->response_event);
2633 spin_unlock(&hdd_context_lock);
2634
Sunil Duttc69bccb2014-05-26 21:30:20 +05302635 break;
2636 }
2637 default:
2638 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2639 break;
2640 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302641
2642 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302643 return;
2644}
2645
2646const struct
2647nla_policy
2648qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2649{
2650 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2651 { .type = NLA_U32 },
2652 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2653 { .type = NLA_U32 },
2654};
2655
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302656static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2657 struct wireless_dev *wdev,
2658 const void *data,
2659 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302660{
2661 int status;
2662 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302663 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302664 struct net_device *dev = wdev->netdev;
2665 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2666 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2667
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302668 ENTER();
2669
Sunil Duttc69bccb2014-05-26 21:30:20 +05302670 status = wlan_hdd_validate_context(pHddCtx);
2671 if (0 != status)
2672 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302673 return -EINVAL;
2674 }
2675
2676 if (NULL == pAdapter)
2677 {
2678 hddLog(VOS_TRACE_LEVEL_ERROR,
2679 FL("HDD adapter is Null"));
2680 return -ENODEV;
2681 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302682 /* check the LLStats Capability */
2683 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2684 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2685 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302686 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302687 FL("Link Layer Statistics not supported by Firmware"));
2688 return -EINVAL;
2689 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302690
2691 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2692 (struct nlattr *)data,
2693 data_len, qca_wlan_vendor_ll_set_policy))
2694 {
2695 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2696 return -EINVAL;
2697 }
2698 if (!tb_vendor
2699 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2700 {
2701 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2702 return -EINVAL;
2703 }
2704 if (!tb_vendor[
2705 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2706 {
2707 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2708 return -EINVAL;
2709 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302710 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302711 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302712
Dino Mycledf0a5d92014-07-04 09:41:55 +05302713 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302714 nla_get_u32(
2715 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2716
Dino Mycledf0a5d92014-07-04 09:41:55 +05302717 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302718 nla_get_u32(
2719 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2720
Dino Mycled3d50022014-07-07 12:58:25 +05302721 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2722 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302723
2724
2725 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302726 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2727 "Statistics Gathering = %d ",
2728 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2729 linkLayerStatsSetReq.mpduSizeThreshold,
2730 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302731
2732 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2733 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302734 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302735 {
2736 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2737 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302738 return -EINVAL;
2739
2740 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302741
Sunil Duttc69bccb2014-05-26 21:30:20 +05302742 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302743 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302744 {
2745 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2746 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302747 return -EINVAL;
2748 }
2749
2750 pAdapter->isLinkLayerStatsSet = 1;
2751
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302752 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302753 return 0;
2754}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302755static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2756 struct wireless_dev *wdev,
2757 const void *data,
2758 int data_len)
2759{
2760 int ret = 0;
2761
2762 vos_ssr_protect(__func__);
2763 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2764 vos_ssr_unprotect(__func__);
2765
2766 return ret;
2767}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302768
2769const struct
2770nla_policy
2771qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2772{
2773 /* Unsigned 32bit value provided by the caller issuing the GET stats
2774 * command. When reporting
2775 * the stats results, the driver uses the same value to indicate
2776 * which GET request the results
2777 * correspond to.
2778 */
2779 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2780
2781 /* Unsigned 32bit value . bit mask to identify what statistics are
2782 requested for retrieval */
2783 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2784};
2785
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302786static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2787 struct wireless_dev *wdev,
2788 const void *data,
2789 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302790{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302791 unsigned long rc;
2792 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302793 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2794 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302795 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302796 struct net_device *dev = wdev->netdev;
2797 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302798 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302799 int status;
2800
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302801 ENTER();
2802
Sunil Duttc69bccb2014-05-26 21:30:20 +05302803 status = wlan_hdd_validate_context(pHddCtx);
2804 if (0 != status)
2805 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302806 return -EINVAL ;
2807 }
2808
2809 if (NULL == pAdapter)
2810 {
2811 hddLog(VOS_TRACE_LEVEL_FATAL,
2812 "%s: HDD adapter is Null", __func__);
2813 return -ENODEV;
2814 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302815
2816 if (pHddStaCtx == NULL)
2817 {
2818 hddLog(VOS_TRACE_LEVEL_FATAL,
2819 "%s: HddStaCtx is Null", __func__);
2820 return -ENODEV;
2821 }
2822
Dino Mycledf0a5d92014-07-04 09:41:55 +05302823 /* check the LLStats Capability */
2824 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2825 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2826 {
2827 hddLog(VOS_TRACE_LEVEL_ERROR,
2828 FL("Link Layer Statistics not supported by Firmware"));
2829 return -EINVAL;
2830 }
2831
Sunil Duttc69bccb2014-05-26 21:30:20 +05302832
2833 if (!pAdapter->isLinkLayerStatsSet)
2834 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302835 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302836 "%s: isLinkLayerStatsSet : %d",
2837 __func__, pAdapter->isLinkLayerStatsSet);
2838 return -EINVAL;
2839 }
2840
Mukul Sharma10313ba2015-07-29 19:14:39 +05302841 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2842 {
2843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2844 "%s: Roaming in progress, so unable to proceed this request", __func__);
2845 return -EBUSY;
2846 }
2847
Sunil Duttc69bccb2014-05-26 21:30:20 +05302848 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2849 (struct nlattr *)data,
2850 data_len, qca_wlan_vendor_ll_get_policy))
2851 {
2852 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2853 return -EINVAL;
2854 }
2855
2856 if (!tb_vendor
2857 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2858 {
2859 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2860 return -EINVAL;
2861 }
2862
2863 if (!tb_vendor
2864 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2865 {
2866 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2867 return -EINVAL;
2868 }
2869
Sunil Duttc69bccb2014-05-26 21:30:20 +05302870
Dino Mycledf0a5d92014-07-04 09:41:55 +05302871 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302872 nla_get_u32( tb_vendor[
2873 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302874 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302875 nla_get_u32( tb_vendor[
2876 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2877
Dino Mycled3d50022014-07-07 12:58:25 +05302878 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2879 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302880
2881 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302882 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
2883 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302884 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302885
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302886 spin_lock(&hdd_context_lock);
2887 context = &pHddCtx->ll_stats_context;
2888 context->request_id = linkLayerStatsGetReq.reqId;
2889 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
2890 INIT_COMPLETION(context->response_event);
2891 spin_unlock(&hdd_context_lock);
2892
Sunil Duttc69bccb2014-05-26 21:30:20 +05302893 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302894 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302895 {
2896 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2897 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302898 return -EINVAL;
2899 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302900
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302901 rc = wait_for_completion_timeout(&context->response_event,
2902 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
2903 if (!rc)
2904 {
2905 hddLog(LOGE,
2906 FL("Target response timed out request id %d request bitmap 0x%x"),
2907 context->request_id, context->request_bitmap);
2908 return -ETIMEDOUT;
2909 }
2910
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302911 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302912 return 0;
2913}
2914
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302915static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2916 struct wireless_dev *wdev,
2917 const void *data,
2918 int data_len)
2919{
2920 int ret = 0;
2921
2922 vos_ssr_protect(__func__);
2923 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
2924 vos_ssr_unprotect(__func__);
2925
2926 return ret;
2927}
2928
Sunil Duttc69bccb2014-05-26 21:30:20 +05302929const struct
2930nla_policy
2931qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2932{
2933 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2934 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2935 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2936 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2937};
2938
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302939static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2940 struct wireless_dev *wdev,
2941 const void *data,
2942 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302943{
2944 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2945 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302946 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302947 struct net_device *dev = wdev->netdev;
2948 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2949 u32 statsClearReqMask;
2950 u8 stopReq;
2951 int status;
2952
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302953 ENTER();
2954
Sunil Duttc69bccb2014-05-26 21:30:20 +05302955 status = wlan_hdd_validate_context(pHddCtx);
2956 if (0 != status)
2957 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302958 return -EINVAL;
2959 }
2960
2961 if (NULL == pAdapter)
2962 {
2963 hddLog(VOS_TRACE_LEVEL_FATAL,
2964 "%s: HDD adapter is Null", __func__);
2965 return -ENODEV;
2966 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302967 /* check the LLStats Capability */
2968 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2969 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2970 {
2971 hddLog(VOS_TRACE_LEVEL_ERROR,
2972 FL("Enable LLStats Capability"));
2973 return -EINVAL;
2974 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302975
2976 if (!pAdapter->isLinkLayerStatsSet)
2977 {
2978 hddLog(VOS_TRACE_LEVEL_FATAL,
2979 "%s: isLinkLayerStatsSet : %d",
2980 __func__, pAdapter->isLinkLayerStatsSet);
2981 return -EINVAL;
2982 }
2983
2984 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2985 (struct nlattr *)data,
2986 data_len, qca_wlan_vendor_ll_clr_policy))
2987 {
2988 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2989 return -EINVAL;
2990 }
2991
2992 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2993
2994 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2995 {
2996 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2997 return -EINVAL;
2998
2999 }
3000
Sunil Duttc69bccb2014-05-26 21:30:20 +05303001
Dino Mycledf0a5d92014-07-04 09:41:55 +05303002 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303003 nla_get_u32(
3004 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
3005
Dino Mycledf0a5d92014-07-04 09:41:55 +05303006 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303007 nla_get_u8(
3008 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
3009
3010 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05303011 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303012
Dino Mycled3d50022014-07-07 12:58:25 +05303013 vos_mem_copy(linkLayerStatsClearReq.macAddr,
3014 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05303015
3016 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05303017 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
3018 "statsClearReqMask = 0x%X, stopReq = %d",
3019 linkLayerStatsClearReq.reqId,
3020 linkLayerStatsClearReq.macAddr,
3021 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303022 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303023
3024 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303025 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303026 {
3027 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05303028 hdd_station_ctx_t *pHddStaCtx;
3029
3030 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3031 if (VOS_STATUS_SUCCESS !=
3032 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
3033 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
3034 {
3035 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3036 "WLANTL_ClearInterfaceStats Failed", __func__);
3037 return -EINVAL;
3038 }
3039 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
3040 (statsClearReqMask & WIFI_STATS_IFACE)) {
3041 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
3042 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
3043 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
3044 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
3045 }
3046
Sunil Duttc69bccb2014-05-26 21:30:20 +05303047 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
3048 2 * sizeof(u32) +
3049 NLMSG_HDRLEN);
3050
3051 if (temp_skbuff != NULL)
3052 {
3053
3054 if (nla_put_u32(temp_skbuff,
3055 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
3056 statsClearReqMask) ||
3057 nla_put_u32(temp_skbuff,
3058 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
3059 stopReq))
3060 {
3061 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
3062 kfree_skb(temp_skbuff);
3063 return -EINVAL;
3064 }
3065 /* If the ask is to stop the stats collection as part of clear
3066 * (stopReq = 1) , ensure that no further requests of get
3067 * go to the firmware by having isLinkLayerStatsSet set to 0.
3068 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303069 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05303070 * case the firmware is just asked to clear the statistics.
3071 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05303072 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303073 pAdapter->isLinkLayerStatsSet = 0;
3074 return cfg80211_vendor_cmd_reply(temp_skbuff);
3075 }
3076 return -ENOMEM;
3077 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303078
3079 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303080 return -EINVAL;
3081}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303082static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3083 struct wireless_dev *wdev,
3084 const void *data,
3085 int data_len)
3086{
3087 int ret = 0;
3088
3089 vos_ssr_protect(__func__);
3090 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
3091 vos_ssr_unprotect(__func__);
3092
3093 return ret;
3094
3095
3096}
Sunil Duttc69bccb2014-05-26 21:30:20 +05303097#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
3098
Dino Mycle6fb96c12014-06-10 11:52:40 +05303099#ifdef WLAN_FEATURE_EXTSCAN
3100static const struct nla_policy
3101wlan_hdd_extscan_config_policy
3102 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
3103{
3104 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
3105 { .type = NLA_U32 },
3106 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
3107 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05303108 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
3109 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303110 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
3111 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
3112 { .type = NLA_U32 },
3113 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
3114 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
3115
3116 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
3117 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
3118 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
3119 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
3120 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303121 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
3122 { .type = NLA_U32 },
3123 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
3124 { .type = NLA_U32 },
3125 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
3126 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303127 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
3128 { .type = NLA_U32 },
3129 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
3130 { .type = NLA_U32 },
3131 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
3132 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303133 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
3134 { .type = NLA_U8 },
3135 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303136 { .type = NLA_U8 },
3137 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
3138 { .type = NLA_U8 },
3139 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
3140 { .type = NLA_U8 },
3141
3142 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
3143 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05303144 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
3145 .type = NLA_UNSPEC,
3146 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05303147 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
3148 { .type = NLA_S32 },
3149 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
3150 { .type = NLA_S32 },
3151 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
3152 { .type = NLA_U32 },
3153 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
3154 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303155 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
3156 { .type = NLA_U32 },
3157 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
3158 { .type = NLA_BINARY,
3159 .len = IEEE80211_MAX_SSID_LEN + 1 },
3160 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303161 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303162 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
3163 { .type = NLA_U32 },
3164 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
3165 { .type = NLA_U8 },
3166 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
3167 { .type = NLA_S32 },
3168 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
3169 { .type = NLA_S32 },
3170 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
3171 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303172};
3173
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303174/**
3175 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
3176 * @ctx: hdd global context
3177 * @data: capabilities data
3178 *
3179 * Return: none
3180 */
3181static void
3182wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303183{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303184 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303185 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303186 tSirEXTScanCapabilitiesEvent *data =
3187 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303188
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303189 ENTER();
3190
3191 if (wlan_hdd_validate_context(pHddCtx))
3192 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303193 return;
3194 }
3195
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303196 if (!pMsg)
3197 {
3198 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3199 return;
3200 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303201
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303202 vos_spin_lock_acquire(&hdd_context_lock);
3203
3204 context = &pHddCtx->ext_scan_context;
3205 /* validate response received from target*/
3206 if (context->request_id != data->requestId)
3207 {
3208 vos_spin_lock_release(&hdd_context_lock);
3209 hddLog(LOGE,
3210 FL("Target response id did not match: request_id %d resposne_id %d"),
3211 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303212 return;
3213 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303214 else
3215 {
3216 context->capability_response = *data;
3217 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303218 }
3219
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303220 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303221
Dino Mycle6fb96c12014-06-10 11:52:40 +05303222 return;
3223}
3224
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303225/*
3226 * define short names for the global vendor params
3227 * used by wlan_hdd_send_ext_scan_capability()
3228 */
3229#define PARAM_REQUEST_ID \
3230 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3231#define PARAM_STATUS \
3232 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
3233#define MAX_SCAN_CACHE_SIZE \
3234 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
3235#define MAX_SCAN_BUCKETS \
3236 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
3237#define MAX_AP_CACHE_PER_SCAN \
3238 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
3239#define MAX_RSSI_SAMPLE_SIZE \
3240 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
3241#define MAX_SCAN_RPT_THRHOLD \
3242 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
3243#define MAX_HOTLIST_BSSIDS \
3244 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
3245#define MAX_BSSID_HISTORY_ENTRIES \
3246 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
3247#define MAX_HOTLIST_SSIDS \
3248 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303249#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
3250 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303251
3252static int wlan_hdd_send_ext_scan_capability(void *ctx)
3253{
3254 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3255 struct sk_buff *skb = NULL;
3256 int ret;
3257 tSirEXTScanCapabilitiesEvent *data;
3258 tANI_U32 nl_buf_len;
3259
3260 ret = wlan_hdd_validate_context(pHddCtx);
3261 if (0 != ret)
3262 {
3263 return ret;
3264 }
3265
3266 data = &(pHddCtx->ext_scan_context.capability_response);
3267
3268 nl_buf_len = NLMSG_HDRLEN;
3269 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
3270 (sizeof(data->status) + NLA_HDRLEN) +
3271 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
3272 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
3273 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
3274 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
3275 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
3276 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
3277 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
3278 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
3279
3280 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
3281
3282 if (!skb)
3283 {
3284 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
3285 return -ENOMEM;
3286 }
3287
3288 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
3289 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
3290 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
3291 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
3292 data->maxRssiSampleSize, data->maxScanReportingThreshold);
3293 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
3294 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
3295 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
3296
3297 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
3298 nla_put_u32(skb, PARAM_STATUS, data->status) ||
3299 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
3300 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
3301 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
3302 data->maxApPerScan) ||
3303 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
3304 data->maxRssiSampleSize) ||
3305 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
3306 data->maxScanReportingThreshold) ||
3307 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
3308 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
3309 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303310 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
3311 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303312 {
3313 hddLog(LOGE, FL("nla put fail"));
3314 goto nla_put_failure;
3315 }
3316
3317 cfg80211_vendor_cmd_reply(skb);
3318 return 0;
3319
3320nla_put_failure:
3321 kfree_skb(skb);
3322 return -EINVAL;;
3323}
3324
3325/*
3326 * done with short names for the global vendor params
3327 * used by wlan_hdd_send_ext_scan_capability()
3328 */
3329#undef PARAM_REQUEST_ID
3330#undef PARAM_STATUS
3331#undef MAX_SCAN_CACHE_SIZE
3332#undef MAX_SCAN_BUCKETS
3333#undef MAX_AP_CACHE_PER_SCAN
3334#undef MAX_RSSI_SAMPLE_SIZE
3335#undef MAX_SCAN_RPT_THRHOLD
3336#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303337#undef MAX_BSSID_HISTORY_ENTRIES
3338#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05303339
3340static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
3341{
3342 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
3343 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303344 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303345 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303346
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303347 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303348
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303349 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303350 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303351
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303352 if (!pMsg)
3353 {
3354 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303355 return;
3356 }
3357
Dino Mycle6fb96c12014-06-10 11:52:40 +05303358 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3359 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
3360
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303361 context = &pHddCtx->ext_scan_context;
3362 spin_lock(&hdd_context_lock);
3363 if (context->request_id == pData->requestId) {
3364 context->response_status = pData->status ? -EINVAL : 0;
3365 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303366 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303367 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303368
3369 /*
3370 * Store the Request ID for comparing with the requestID obtained
3371 * in other requests.HDD shall return a failure is the extscan_stop
3372 * request is issued with a different requestId as that of the
3373 * extscan_start request. Also, This requestId shall be used while
3374 * indicating the full scan results to the upper layers.
3375 * The requestId is stored with the assumption that the firmware
3376 * shall return the ext scan start request's requestId in ext scan
3377 * start response.
3378 */
3379 if (pData->status == 0)
3380 pMac->sme.extScanStartReqId = pData->requestId;
3381
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303382 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303383 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303384}
3385
3386
3387static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
3388{
3389 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
3390 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303391 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303392
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303393 ENTER();
3394
3395 if (wlan_hdd_validate_context(pHddCtx)){
3396 return;
3397 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303398
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303399 if (!pMsg)
3400 {
3401 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303402 return;
3403 }
3404
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303405 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3406 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303407
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303408 context = &pHddCtx->ext_scan_context;
3409 spin_lock(&hdd_context_lock);
3410 if (context->request_id == pData->requestId) {
3411 context->response_status = pData->status ? -EINVAL : 0;
3412 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303413 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303414 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303415
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303416 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303417 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303418}
3419
Dino Mycle6fb96c12014-06-10 11:52:40 +05303420static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3421 void *pMsg)
3422{
3423 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303424 tpSirEXTScanSetBssidHotListRspParams pData =
3425 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303426 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303427
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303428 ENTER();
3429
3430 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303431 return;
3432 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303433
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303434 if (!pMsg)
3435 {
3436 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3437 return;
3438 }
3439
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303440 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3441 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303442
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303443 context = &pHddCtx->ext_scan_context;
3444 spin_lock(&hdd_context_lock);
3445 if (context->request_id == pData->requestId) {
3446 context->response_status = pData->status ? -EINVAL : 0;
3447 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303448 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303449 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303450
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303451 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303452 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303453}
3454
3455static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3456 void *pMsg)
3457{
3458 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303459 tpSirEXTScanResetBssidHotlistRspParams pData =
3460 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303461 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303462
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303463 ENTER();
3464
3465 if (wlan_hdd_validate_context(pHddCtx)) {
3466 return;
3467 }
3468 if (!pMsg)
3469 {
3470 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303471 return;
3472 }
3473
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303474 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3475 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303476
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303477 context = &pHddCtx->ext_scan_context;
3478 spin_lock(&hdd_context_lock);
3479 if (context->request_id == pData->requestId) {
3480 context->response_status = pData->status ? -EINVAL : 0;
3481 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303482 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303483 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303484
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303485 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303486 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303487}
3488
Dino Mycle6fb96c12014-06-10 11:52:40 +05303489static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3490 void *pMsg)
3491{
3492 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3493 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303494 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303495 tANI_S32 totalResults;
3496 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303497 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3498 struct hdd_ext_scan_context *context;
3499 bool ignore_cached_results = false;
3500 tExtscanCachedScanResult *result;
3501 struct nlattr *nla_results;
3502 tANI_U16 ieLength= 0;
3503 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303504
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303505 ENTER();
3506
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303507 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303508 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303509
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303510 if (!pMsg)
3511 {
3512 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3513 return;
3514 }
3515
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303516 spin_lock(&hdd_context_lock);
3517 context = &pHddCtx->ext_scan_context;
3518 ignore_cached_results = context->ignore_cached_results;
3519 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303520
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303521 if (ignore_cached_results) {
3522 hddLog(LOGE,
3523 FL("Ignore the cached results received after timeout"));
3524 return;
3525 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303526
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303527 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3528 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303529
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303530 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303531
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303532 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3533 scan_id_index++) {
3534 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303535
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303536 totalResults = result->num_results;
3537 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3538 result->scan_id, result->flags, totalResults);
3539 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303540
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303541 do{
3542 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3543 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3544 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303545
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303546 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3547 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3548
3549 if (!skb) {
3550 hddLog(VOS_TRACE_LEVEL_ERROR,
3551 FL("cfg80211_vendor_event_alloc failed"));
3552 return;
3553 }
3554
3555 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3556
3557 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3558 pData->requestId) ||
3559 nla_put_u32(skb,
3560 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3561 resultsPerEvent)) {
3562 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3563 goto fail;
3564 }
3565 if (nla_put_u8(skb,
3566 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3567 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303568 {
3569 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3570 goto fail;
3571 }
3572
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303573 if (nla_put_u32(skb,
3574 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3575 result->scan_id)) {
3576 hddLog(LOGE, FL("put fail"));
3577 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303578 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303579
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303580 nla_results = nla_nest_start(skb,
3581 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3582 if (!nla_results)
3583 goto fail;
3584
3585 if (resultsPerEvent) {
3586 struct nlattr *aps;
3587 struct nlattr *nla_result;
3588
3589 nla_result = nla_nest_start(skb, scan_id_index);
3590 if(!nla_result)
3591 goto fail;
3592
3593 if (nla_put_u32(skb,
3594 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3595 result->scan_id) ||
3596 nla_put_u32(skb,
3597 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3598 result->flags) ||
3599 nla_put_u32(skb,
3600 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3601 totalResults)) {
3602 hddLog(LOGE, FL("put fail"));
3603 goto fail;
3604 }
3605
3606 aps = nla_nest_start(skb,
3607 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3608 if (!aps)
3609 {
3610 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3611 goto fail;
3612 }
3613
3614 head_ptr = (tpSirWifiScanResult) &(result->ap);
3615
3616 for (j = 0; j < resultsPerEvent; j++, i++) {
3617 struct nlattr *ap;
3618 pSirWifiScanResult = head_ptr + i;
3619
3620 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303621 * Firmware returns timestamp from extscan_start till
3622 * BSSID was cached (in micro seconds). Add this with
3623 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303624 * to derive the time since boot when the
3625 * BSSID was cached.
3626 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303627 pSirWifiScanResult->ts +=
3628 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303629 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3630 "Ssid (%s)"
3631 "Bssid: %pM "
3632 "Channel (%u)"
3633 "Rssi (%d)"
3634 "RTT (%u)"
3635 "RTT_SD (%u)"
3636 "Beacon Period %u"
3637 "Capability 0x%x "
3638 "Ie length %d",
3639 i,
3640 pSirWifiScanResult->ts,
3641 pSirWifiScanResult->ssid,
3642 pSirWifiScanResult->bssid,
3643 pSirWifiScanResult->channel,
3644 pSirWifiScanResult->rssi,
3645 pSirWifiScanResult->rtt,
3646 pSirWifiScanResult->rtt_sd,
3647 pSirWifiScanResult->beaconPeriod,
3648 pSirWifiScanResult->capability,
3649 ieLength);
3650
3651 ap = nla_nest_start(skb, j + 1);
3652 if (!ap)
3653 {
3654 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3655 goto fail;
3656 }
3657
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303658 if (hdd_wlan_nla_put_u64(skb,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303659 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3660 pSirWifiScanResult->ts) )
3661 {
3662 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3663 goto fail;
3664 }
3665 if (nla_put(skb,
3666 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3667 sizeof(pSirWifiScanResult->ssid),
3668 pSirWifiScanResult->ssid) )
3669 {
3670 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3671 goto fail;
3672 }
3673 if (nla_put(skb,
3674 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3675 sizeof(pSirWifiScanResult->bssid),
3676 pSirWifiScanResult->bssid) )
3677 {
3678 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3679 goto fail;
3680 }
3681 if (nla_put_u32(skb,
3682 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3683 pSirWifiScanResult->channel) )
3684 {
3685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3686 goto fail;
3687 }
3688 if (nla_put_s32(skb,
3689 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3690 pSirWifiScanResult->rssi) )
3691 {
3692 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3693 goto fail;
3694 }
3695 if (nla_put_u32(skb,
3696 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3697 pSirWifiScanResult->rtt) )
3698 {
3699 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3700 goto fail;
3701 }
3702 if (nla_put_u32(skb,
3703 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3704 pSirWifiScanResult->rtt_sd))
3705 {
3706 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3707 goto fail;
3708 }
3709 if (nla_put_u32(skb,
3710 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3711 pSirWifiScanResult->beaconPeriod))
3712 {
3713 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3714 goto fail;
3715 }
3716 if (nla_put_u32(skb,
3717 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3718 pSirWifiScanResult->capability))
3719 {
3720 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3721 goto fail;
3722 }
3723 if (nla_put_u32(skb,
3724 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3725 ieLength))
3726 {
3727 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3728 goto fail;
3729 }
3730
3731 if (ieLength)
3732 if (nla_put(skb,
3733 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3734 ieLength, ie)) {
3735 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3736 goto fail;
3737 }
3738
3739 nla_nest_end(skb, ap);
3740 }
3741 nla_nest_end(skb, aps);
3742 nla_nest_end(skb, nla_result);
3743 }
3744
3745 nla_nest_end(skb, nla_results);
3746
3747 cfg80211_vendor_cmd_reply(skb);
3748
3749 } while (totalResults > 0);
3750 }
3751
3752 if (!pData->moreData) {
3753 spin_lock(&hdd_context_lock);
3754 context->response_status = 0;
3755 complete(&context->response_event);
3756 spin_unlock(&hdd_context_lock);
3757 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303758
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303759 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303760 return;
3761fail:
3762 kfree_skb(skb);
3763 return;
3764}
3765
3766static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3767 void *pMsg)
3768{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303769 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303770 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3771 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303772 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303773
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303774 ENTER();
3775
3776 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303777 hddLog(LOGE,
3778 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303779 return;
3780 }
3781 if (!pMsg)
3782 {
3783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303784 return;
3785 }
3786
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303787 if (pData->bss_found)
3788 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3789 else
3790 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3791
Dino Mycle6fb96c12014-06-10 11:52:40 +05303792 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303793#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3794 NULL,
3795#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303796 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303797 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303798
3799 if (!skb) {
3800 hddLog(VOS_TRACE_LEVEL_ERROR,
3801 FL("cfg80211_vendor_event_alloc failed"));
3802 return;
3803 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303804
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303805 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3806 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3807 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3808 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3809
3810 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303811 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3812 "Ssid (%s) "
3813 "Bssid (" MAC_ADDRESS_STR ") "
3814 "Channel (%u) "
3815 "Rssi (%d) "
3816 "RTT (%u) "
3817 "RTT_SD (%u) ",
3818 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303819 pData->bssHotlist[i].ts,
3820 pData->bssHotlist[i].ssid,
3821 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3822 pData->bssHotlist[i].channel,
3823 pData->bssHotlist[i].rssi,
3824 pData->bssHotlist[i].rtt,
3825 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303826 }
3827
3828 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3829 pData->requestId) ||
3830 nla_put_u32(skb,
3831 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303832 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303833 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3834 goto fail;
3835 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303836 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303837 struct nlattr *aps;
3838
3839 aps = nla_nest_start(skb,
3840 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3841 if (!aps)
3842 goto fail;
3843
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303844 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303845 struct nlattr *ap;
3846
3847 ap = nla_nest_start(skb, i + 1);
3848 if (!ap)
3849 goto fail;
3850
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303851 if (hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303852 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303853 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303854 nla_put(skb,
3855 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303856 sizeof(pData->bssHotlist[i].ssid),
3857 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303858 nla_put(skb,
3859 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303860 sizeof(pData->bssHotlist[i].bssid),
3861 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303862 nla_put_u32(skb,
3863 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303864 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303865 nla_put_s32(skb,
3866 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303867 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303868 nla_put_u32(skb,
3869 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303870 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303871 nla_put_u32(skb,
3872 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303873 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303874 goto fail;
3875
3876 nla_nest_end(skb, ap);
3877 }
3878 nla_nest_end(skb, aps);
3879
3880 if (nla_put_u8(skb,
3881 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3882 pData->moreData))
3883 goto fail;
3884 }
3885
3886 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303887 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303888 return;
3889
3890fail:
3891 kfree_skb(skb);
3892 return;
3893
3894}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303895
3896static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3897 void *pMsg)
3898{
3899 struct sk_buff *skb;
3900 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3901 tpSirWifiFullScanResultEvent pData =
3902 (tpSirWifiFullScanResultEvent) (pMsg);
3903
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303904 ENTER();
3905
3906 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303907 hddLog(LOGE,
3908 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303909 return;
3910 }
3911 if (!pMsg)
3912 {
3913 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303914 return;
3915 }
3916
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303917 /*
3918 * If the full scan result including IE data exceeds NL 4K size
3919 * limitation, drop that beacon/probe rsp frame.
3920 */
3921 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3922 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3923 return;
3924 }
3925
Dino Mycle6fb96c12014-06-10 11:52:40 +05303926 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303927#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3928 NULL,
3929#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303930 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3931 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3932 GFP_KERNEL);
3933
3934 if (!skb) {
3935 hddLog(VOS_TRACE_LEVEL_ERROR,
3936 FL("cfg80211_vendor_event_alloc failed"));
3937 return;
3938 }
3939
Dino Mycle6fb96c12014-06-10 11:52:40 +05303940 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3941 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3942 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3943 "Ssid (%s)"
3944 "Bssid (" MAC_ADDRESS_STR ")"
3945 "Channel (%u)"
3946 "Rssi (%d)"
3947 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303948 "RTT_SD (%u)"
3949 "Bcn Period %d"
3950 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303951 pData->ap.ts,
3952 pData->ap.ssid,
3953 MAC_ADDR_ARRAY(pData->ap.bssid),
3954 pData->ap.channel,
3955 pData->ap.rssi,
3956 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303957 pData->ap.rtt_sd,
3958 pData->ap.beaconPeriod,
3959 pData->ap.capability);
3960
Dino Mycle6fb96c12014-06-10 11:52:40 +05303961 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3962 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3963 pData->requestId) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303964 hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303965 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3966 pData->ap.ts) ||
3967 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3968 sizeof(pData->ap.ssid),
3969 pData->ap.ssid) ||
3970 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3971 WNI_CFG_BSSID_LEN,
3972 pData->ap.bssid) ||
3973 nla_put_u32(skb,
3974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3975 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303976 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303977 pData->ap.rssi) ||
3978 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3979 pData->ap.rtt) ||
3980 nla_put_u32(skb,
3981 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3982 pData->ap.rtt_sd) ||
3983 nla_put_u16(skb,
3984 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3985 pData->ap.beaconPeriod) ||
3986 nla_put_u16(skb,
3987 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3988 pData->ap.capability) ||
3989 nla_put_u32(skb,
3990 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303991 pData->ieLength) ||
3992 nla_put_u8(skb,
3993 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3994 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303995 {
3996 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3997 goto nla_put_failure;
3998 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303999
4000 if (pData->ieLength) {
4001 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
4002 pData->ieLength,
4003 pData->ie))
4004 {
4005 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4006 goto nla_put_failure;
4007 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304008 }
4009
4010 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304011 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304012 return;
4013
4014nla_put_failure:
4015 kfree_skb(skb);
4016 return;
4017}
4018
4019static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
4020 void *pMsg)
4021{
4022 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4023 struct sk_buff *skb = NULL;
4024 tpSirEXTScanResultsAvailableIndParams pData =
4025 (tpSirEXTScanResultsAvailableIndParams) pMsg;
4026
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304027 ENTER();
4028
4029 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304030 hddLog(LOGE,
4031 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304032 return;
4033 }
4034 if (!pMsg)
4035 {
4036 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304037 return;
4038 }
4039
4040 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_SCAN_RESULTS_AVAILABLE_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, "Req Id (%u)", pData->requestId);
4055 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
4056 pData->numResultsAvailable);
4057 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4058 pData->requestId) ||
4059 nla_put_u32(skb,
4060 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
4061 pData->numResultsAvailable)) {
4062 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4063 goto nla_put_failure;
4064 }
4065
4066 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304067 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304068 return;
4069
4070nla_put_failure:
4071 kfree_skb(skb);
4072 return;
4073}
4074
4075static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
4076{
4077 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4078 struct sk_buff *skb = NULL;
4079 tpSirEXTScanProgressIndParams pData =
4080 (tpSirEXTScanProgressIndParams) pMsg;
4081
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304082 ENTER();
4083
4084 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304085 hddLog(LOGE,
4086 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304087 return;
4088 }
4089 if (!pMsg)
4090 {
4091 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304092 return;
4093 }
4094
4095 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304096#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4097 NULL,
4098#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304099 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4100 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
4101 GFP_KERNEL);
4102
4103 if (!skb) {
4104 hddLog(VOS_TRACE_LEVEL_ERROR,
4105 FL("cfg80211_vendor_event_alloc failed"));
4106 return;
4107 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304108 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304109 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
4110 pData->extScanEventType);
4111 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
4112 pData->status);
4113
4114 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
4115 pData->extScanEventType) ||
4116 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05304117 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4118 pData->requestId) ||
4119 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304120 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
4121 pData->status)) {
4122 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4123 goto nla_put_failure;
4124 }
4125
4126 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304127 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304128 return;
4129
4130nla_put_failure:
4131 kfree_skb(skb);
4132 return;
4133}
4134
4135void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
4136 void *pMsg)
4137{
4138 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4139
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304140 ENTER();
4141
Dino Mycle6fb96c12014-06-10 11:52:40 +05304142 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304143 return;
4144 }
4145
4146 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
4147
4148
4149 switch(evType) {
4150 case SIR_HAL_EXTSCAN_START_RSP:
4151 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
4152 break;
4153
4154 case SIR_HAL_EXTSCAN_STOP_RSP:
4155 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
4156 break;
4157 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
4158 /* There is no need to send this response to upper layer
4159 Just log the message */
4160 hddLog(VOS_TRACE_LEVEL_INFO,
4161 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
4162 break;
4163 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
4164 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
4165 break;
4166
4167 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
4168 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
4169 break;
4170
Dino Mycle6fb96c12014-06-10 11:52:40 +05304171 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304172 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304173 break;
4174 case SIR_HAL_EXTSCAN_PROGRESS_IND:
4175 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
4176 break;
4177 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
4178 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
4179 break;
4180 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
4181 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
4182 break;
4183 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
4184 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
4185 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304186 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
4187 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
4188 break;
4189 default:
4190 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
4191 break;
4192 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304193 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304194}
4195
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304196static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4197 struct wireless_dev *wdev,
4198 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304199{
Dino Myclee8843b32014-07-04 14:21:45 +05304200 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304201 struct net_device *dev = wdev->netdev;
4202 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4203 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4204 struct nlattr
4205 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4206 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304207 struct hdd_ext_scan_context *context;
4208 unsigned long rc;
4209 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304210
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304211 ENTER();
4212
Dino Mycle6fb96c12014-06-10 11:52:40 +05304213 status = wlan_hdd_validate_context(pHddCtx);
4214 if (0 != status)
4215 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304216 return -EINVAL;
4217 }
Dino Myclee8843b32014-07-04 14:21:45 +05304218 /* check the EXTScan Capability */
4219 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304220 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4221 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304222 {
4223 hddLog(VOS_TRACE_LEVEL_ERROR,
4224 FL("EXTScan not enabled/supported by Firmware"));
4225 return -EINVAL;
4226 }
4227
Dino Mycle6fb96c12014-06-10 11:52:40 +05304228 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4229 data, dataLen,
4230 wlan_hdd_extscan_config_policy)) {
4231 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4232 return -EINVAL;
4233 }
4234
4235 /* Parse and fetch request Id */
4236 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4237 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4238 return -EINVAL;
4239 }
4240
Dino Myclee8843b32014-07-04 14:21:45 +05304241 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304242 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304243 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304244
Dino Myclee8843b32014-07-04 14:21:45 +05304245 reqMsg.sessionId = pAdapter->sessionId;
4246 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304247
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304248 vos_spin_lock_acquire(&hdd_context_lock);
4249 context = &pHddCtx->ext_scan_context;
4250 context->request_id = reqMsg.requestId;
4251 INIT_COMPLETION(context->response_event);
4252 vos_spin_lock_release(&hdd_context_lock);
4253
Dino Myclee8843b32014-07-04 14:21:45 +05304254 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304255 if (!HAL_STATUS_SUCCESS(status)) {
4256 hddLog(VOS_TRACE_LEVEL_ERROR,
4257 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304258 return -EINVAL;
4259 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304260
4261 rc = wait_for_completion_timeout(&context->response_event,
4262 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4263 if (!rc) {
4264 hddLog(LOGE, FL("Target response timed out"));
4265 return -ETIMEDOUT;
4266 }
4267
4268 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
4269 if (ret)
4270 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
4271
4272 return ret;
4273
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304274 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304275 return 0;
4276}
4277
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304278static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4279 struct wireless_dev *wdev,
4280 const void *data, int dataLen)
4281{
4282 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304283
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304284 vos_ssr_protect(__func__);
4285 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
4286 vos_ssr_unprotect(__func__);
4287
4288 return ret;
4289}
4290
4291static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4292 struct wireless_dev *wdev,
4293 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304294{
Dino Myclee8843b32014-07-04 14:21:45 +05304295 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304296 struct net_device *dev = wdev->netdev;
4297 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4298 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4299 struct nlattr
4300 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4301 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304302 struct hdd_ext_scan_context *context;
4303 unsigned long rc;
4304 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304305
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304306 ENTER();
4307
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304308 if (VOS_FTM_MODE == hdd_get_conparam()) {
4309 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4310 return -EINVAL;
4311 }
4312
Dino Mycle6fb96c12014-06-10 11:52:40 +05304313 status = wlan_hdd_validate_context(pHddCtx);
4314 if (0 != status)
4315 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304316 return -EINVAL;
4317 }
Dino Myclee8843b32014-07-04 14:21:45 +05304318 /* check the EXTScan Capability */
4319 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304320 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4321 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304322 {
4323 hddLog(VOS_TRACE_LEVEL_ERROR,
4324 FL("EXTScan not enabled/supported by Firmware"));
4325 return -EINVAL;
4326 }
4327
Dino Mycle6fb96c12014-06-10 11:52:40 +05304328 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4329 data, dataLen,
4330 wlan_hdd_extscan_config_policy)) {
4331 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4332 return -EINVAL;
4333 }
4334 /* Parse and fetch request Id */
4335 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4337 return -EINVAL;
4338 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304339
Dino Myclee8843b32014-07-04 14:21:45 +05304340 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304341 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4342
Dino Myclee8843b32014-07-04 14:21:45 +05304343 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304344
Dino Myclee8843b32014-07-04 14:21:45 +05304345 reqMsg.sessionId = pAdapter->sessionId;
4346 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304347
4348 /* Parse and fetch flush parameter */
4349 if (!tb
4350 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
4351 {
4352 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
4353 goto failed;
4354 }
Dino Myclee8843b32014-07-04 14:21:45 +05304355 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304356 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
4357
Dino Myclee8843b32014-07-04 14:21:45 +05304358 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304359
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304360 spin_lock(&hdd_context_lock);
4361 context = &pHddCtx->ext_scan_context;
4362 context->request_id = reqMsg.requestId;
4363 context->ignore_cached_results = false;
4364 INIT_COMPLETION(context->response_event);
4365 spin_unlock(&hdd_context_lock);
4366
Dino Myclee8843b32014-07-04 14:21:45 +05304367 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304368 if (!HAL_STATUS_SUCCESS(status)) {
4369 hddLog(VOS_TRACE_LEVEL_ERROR,
4370 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304371 return -EINVAL;
4372 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304373
4374 rc = wait_for_completion_timeout(&context->response_event,
4375 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4376 if (!rc) {
4377 hddLog(LOGE, FL("Target response timed out"));
4378 retval = -ETIMEDOUT;
4379 spin_lock(&hdd_context_lock);
4380 context->ignore_cached_results = true;
4381 spin_unlock(&hdd_context_lock);
4382 } else {
4383 spin_lock(&hdd_context_lock);
4384 retval = context->response_status;
4385 spin_unlock(&hdd_context_lock);
4386 }
4387
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304388 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304389 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304390
4391failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05304392 return -EINVAL;
4393}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304394static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4395 struct wireless_dev *wdev,
4396 const void *data, int dataLen)
4397{
4398 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304399
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304400 vos_ssr_protect(__func__);
4401 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
4402 vos_ssr_unprotect(__func__);
4403
4404 return ret;
4405}
4406
4407static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304408 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05304409 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304410{
4411 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
4412 struct net_device *dev = wdev->netdev;
4413 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4414 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4415 struct nlattr
4416 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4417 struct nlattr
4418 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4419 struct nlattr *apTh;
4420 eHalStatus status;
4421 tANI_U8 i = 0;
4422 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304423 struct hdd_ext_scan_context *context;
4424 tANI_U32 request_id;
4425 unsigned long rc;
4426 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304427
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304428 ENTER();
4429
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304430 if (VOS_FTM_MODE == hdd_get_conparam()) {
4431 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4432 return -EINVAL;
4433 }
4434
Dino Mycle6fb96c12014-06-10 11:52:40 +05304435 status = wlan_hdd_validate_context(pHddCtx);
4436 if (0 != status)
4437 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304438 return -EINVAL;
4439 }
Dino Myclee8843b32014-07-04 14:21:45 +05304440 /* check the EXTScan Capability */
4441 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304442 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4443 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304444 {
4445 hddLog(VOS_TRACE_LEVEL_ERROR,
4446 FL("EXTScan not enabled/supported by Firmware"));
4447 return -EINVAL;
4448 }
4449
Dino Mycle6fb96c12014-06-10 11:52:40 +05304450 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4451 data, dataLen,
4452 wlan_hdd_extscan_config_policy)) {
4453 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4454 return -EINVAL;
4455 }
4456
4457 /* Parse and fetch request Id */
4458 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4459 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4460 return -EINVAL;
4461 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304462 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4463 vos_mem_malloc(sizeof(*pReqMsg));
4464 if (!pReqMsg) {
4465 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4466 return -ENOMEM;
4467 }
4468
Dino Myclee8843b32014-07-04 14:21:45 +05304469
Dino Mycle6fb96c12014-06-10 11:52:40 +05304470 pReqMsg->requestId = nla_get_u32(
4471 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4472 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4473
4474 /* Parse and fetch number of APs */
4475 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4476 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4477 goto fail;
4478 }
4479
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304480 /* Parse and fetch lost ap sample size */
4481 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4482 hddLog(LOGE, FL("attr lost ap sample size failed"));
4483 goto fail;
4484 }
4485
4486 pReqMsg->lostBssidSampleSize = nla_get_u32(
4487 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4488 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4489
Dino Mycle6fb96c12014-06-10 11:52:40 +05304490 pReqMsg->sessionId = pAdapter->sessionId;
4491 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4492
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304493 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304494 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304495 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4496 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4497 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4498 goto fail;
4499 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304500 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304501
4502 nla_for_each_nested(apTh,
4503 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304504 if (i == pReqMsg->numBssid) {
4505 hddLog(LOGW, FL("Ignoring excess AP"));
4506 break;
4507 }
4508
Dino Mycle6fb96c12014-06-10 11:52:40 +05304509 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4510 nla_data(apTh), nla_len(apTh),
4511 NULL)) {
4512 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4513 goto fail;
4514 }
4515
4516 /* Parse and fetch MAC address */
4517 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4518 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4519 goto fail;
4520 }
4521 memcpy(pReqMsg->ap[i].bssid, nla_data(
4522 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4523 sizeof(tSirMacAddr));
4524 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4525
4526 /* Parse and fetch low RSSI */
4527 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4528 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4529 goto fail;
4530 }
4531 pReqMsg->ap[i].low = nla_get_s32(
4532 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4533 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4534
4535 /* Parse and fetch high RSSI */
4536 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4537 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4538 goto fail;
4539 }
4540 pReqMsg->ap[i].high = nla_get_s32(
4541 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4542 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4543 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304544 i++;
4545 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304546
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304547 if (i < pReqMsg->numBssid) {
4548 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4549 i, pReqMsg->numBssid);
4550 pReqMsg->numBssid = i;
4551 }
4552
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304553 context = &pHddCtx->ext_scan_context;
4554 spin_lock(&hdd_context_lock);
4555 INIT_COMPLETION(context->response_event);
4556 context->request_id = request_id = pReqMsg->requestId;
4557 spin_unlock(&hdd_context_lock);
4558
Dino Mycle6fb96c12014-06-10 11:52:40 +05304559 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4560 if (!HAL_STATUS_SUCCESS(status)) {
4561 hddLog(VOS_TRACE_LEVEL_ERROR,
4562 FL("sme_SetBssHotlist failed(err=%d)"), status);
4563 vos_mem_free(pReqMsg);
4564 return -EINVAL;
4565 }
4566
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304567 /* request was sent -- wait for the response */
4568 rc = wait_for_completion_timeout(&context->response_event,
4569 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4570
4571 if (!rc) {
4572 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4573 retval = -ETIMEDOUT;
4574 } else {
4575 spin_lock(&hdd_context_lock);
4576 if (context->request_id == request_id)
4577 retval = context->response_status;
4578 else
4579 retval = -EINVAL;
4580 spin_unlock(&hdd_context_lock);
4581 }
4582
Dino Myclee8843b32014-07-04 14:21:45 +05304583 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304584 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304585 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304586
4587fail:
4588 vos_mem_free(pReqMsg);
4589 return -EINVAL;
4590}
4591
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304592static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4593 struct wireless_dev *wdev,
4594 const void *data, int dataLen)
4595{
4596 int ret = 0;
4597
4598 vos_ssr_protect(__func__);
4599 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4600 dataLen);
4601 vos_ssr_unprotect(__func__);
4602
4603 return ret;
4604}
4605
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304606static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304607 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304608 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304609{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304610 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4611 struct net_device *dev = wdev->netdev;
4612 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4613 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4614 uint8_t num_channels = 0;
4615 uint8_t num_chan_new = 0;
4616 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304617 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304618 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304619 tWifiBand wifiBand;
4620 eHalStatus status;
4621 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304622 tANI_U8 i,j,k;
4623 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304624
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304625 ENTER();
4626
Dino Mycle6fb96c12014-06-10 11:52:40 +05304627 status = wlan_hdd_validate_context(pHddCtx);
4628 if (0 != status)
4629 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304630 return -EINVAL;
4631 }
Dino Myclee8843b32014-07-04 14:21:45 +05304632
Dino Mycle6fb96c12014-06-10 11:52:40 +05304633 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4634 data, dataLen,
4635 wlan_hdd_extscan_config_policy)) {
4636 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4637 return -EINVAL;
4638 }
4639
4640 /* Parse and fetch request Id */
4641 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4642 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4643 return -EINVAL;
4644 }
4645 requestId = nla_get_u32(
4646 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4647 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4648
4649 /* Parse and fetch wifi band */
4650 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4651 {
4652 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4653 return -EINVAL;
4654 }
4655 wifiBand = nla_get_u32(
4656 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4657 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4658
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304659 /* Parse and fetch max channels */
4660 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4661 {
4662 hddLog(LOGE, FL("attr max channels failed"));
4663 return -EINVAL;
4664 }
4665 maxChannels = nla_get_u32(
4666 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4667 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4668
Dino Mycle6fb96c12014-06-10 11:52:40 +05304669 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304670 wifiBand, chan_list,
4671 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304672 if (eHAL_STATUS_SUCCESS != status) {
4673 hddLog(VOS_TRACE_LEVEL_ERROR,
4674 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4675 return -EINVAL;
4676 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304677
Agrawal Ashish16abf782016-08-18 22:42:59 +05304678 num_channels = VOS_MIN(num_channels, maxChannels);
4679 num_chan_new = num_channels;
4680 /* remove the indoor only channels if iface is SAP */
4681 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4682 {
4683 num_chan_new = 0;
4684 for (i = 0; i < num_channels; i++)
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304685 for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) {
Agrawal Ashish16abf782016-08-18 22:42:59 +05304686 if (wiphy->bands[j] == NULL)
4687 continue;
4688 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4689 if ((chan_list[i] ==
4690 wiphy->bands[j]->channels[k].center_freq) &&
4691 (!(wiphy->bands[j]->channels[k].flags &
4692 IEEE80211_CHAN_INDOOR_ONLY))) {
4693 chan_list[num_chan_new] = chan_list[i];
4694 num_chan_new++;
4695 }
4696 }
4697 }
4698 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304699
Agrawal Ashish16abf782016-08-18 22:42:59 +05304700 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4701 for (i = 0; i < num_chan_new; i++)
4702 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4703 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304704
4705 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304706 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304707 NLMSG_HDRLEN);
4708
4709 if (!replySkb) {
4710 hddLog(VOS_TRACE_LEVEL_ERROR,
4711 FL("valid channels: buffer alloc fail"));
4712 return -EINVAL;
4713 }
4714 if (nla_put_u32(replySkb,
4715 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304716 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304717 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304718 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304719
4720 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4721 kfree_skb(replySkb);
4722 return -EINVAL;
4723 }
4724
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304725 ret = cfg80211_vendor_cmd_reply(replySkb);
4726
4727 EXIT();
4728 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304729}
4730
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304731static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4732 struct wireless_dev *wdev,
4733 const void *data, int dataLen)
4734{
4735 int ret = 0;
4736
4737 vos_ssr_protect(__func__);
4738 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4739 dataLen);
4740 vos_ssr_unprotect(__func__);
4741
4742 return ret;
4743}
4744
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304745static int hdd_extscan_start_fill_bucket_channel_spec(
4746 hdd_context_t *pHddCtx,
4747 tpSirEXTScanStartReqParams pReqMsg,
4748 struct nlattr **tb)
4749{
4750 struct nlattr *bucket[
4751 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4752 struct nlattr *channel[
4753 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4754 struct nlattr *buckets;
4755 struct nlattr *channels;
4756 int rem1, rem2;
4757 eHalStatus status;
4758 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304759 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304760 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4761 tANI_U32 passive_max_chn_time, active_max_chn_time;
4762
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304763 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304764 bktIndex = 0;
4765
4766 nla_for_each_nested(buckets,
4767 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304768 if (bktIndex >= expected_buckets) {
4769 hddLog(LOGW, FL("ignoring excess buckets"));
4770 break;
4771 }
4772
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304773 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304774 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4775 nla_data(buckets), nla_len(buckets),
4776 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304777 hddLog(LOGE, FL("nla_parse failed"));
4778 return -EINVAL;
4779 }
4780
4781 /* Parse and fetch bucket spec */
4782 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4783 hddLog(LOGE, FL("attr bucket index failed"));
4784 return -EINVAL;
4785 }
4786 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4787 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4788 hddLog(LOG1, FL("Bucket spec Index %d"),
4789 pReqMsg->buckets[bktIndex].bucket);
4790
4791 /* Parse and fetch wifi band */
4792 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4793 hddLog(LOGE, FL("attr wifi band failed"));
4794 return -EINVAL;
4795 }
4796 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4797 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4798 hddLog(LOG1, FL("Wifi band %d"),
4799 pReqMsg->buckets[bktIndex].band);
4800
4801 /* Parse and fetch period */
4802 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4803 hddLog(LOGE, FL("attr period failed"));
4804 return -EINVAL;
4805 }
4806 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4807 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4808 hddLog(LOG1, FL("period %d"),
4809 pReqMsg->buckets[bktIndex].period);
4810
4811 /* Parse and fetch report events */
4812 if (!bucket[
4813 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4814 hddLog(LOGE, FL("attr report events failed"));
4815 return -EINVAL;
4816 }
4817 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4818 bucket[
4819 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4820 hddLog(LOG1, FL("report events %d"),
4821 pReqMsg->buckets[bktIndex].reportEvents);
4822
4823 /* Parse and fetch max period */
4824 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4825 hddLog(LOGE, FL("attr max period failed"));
4826 return -EINVAL;
4827 }
4828 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4829 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4830 hddLog(LOG1, FL("max period %u"),
4831 pReqMsg->buckets[bktIndex].max_period);
4832
4833 /* Parse and fetch exponent */
4834 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4835 hddLog(LOGE, FL("attr exponent failed"));
4836 return -EINVAL;
4837 }
4838 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4839 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4840 hddLog(LOG1, FL("exponent %u"),
4841 pReqMsg->buckets[bktIndex].exponent);
4842
4843 /* Parse and fetch step count */
4844 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4845 hddLog(LOGE, FL("attr step count failed"));
4846 return -EINVAL;
4847 }
4848 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4849 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4850 hddLog(LOG1, FL("Step count %u"),
4851 pReqMsg->buckets[bktIndex].step_count);
4852
4853 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4854 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4855
4856 /* Framework shall pass the channel list if the input WiFi band is
4857 * WIFI_BAND_UNSPECIFIED.
4858 * If the input WiFi band is specified (any value other than
4859 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4860 */
4861 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4862 numChannels = 0;
4863 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4864 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4865 pReqMsg->buckets[bktIndex].band,
4866 chanList, &numChannels);
4867 if (!HAL_STATUS_SUCCESS(status)) {
4868 hddLog(LOGE,
4869 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4870 status);
4871 return -EINVAL;
4872 }
4873
4874 pReqMsg->buckets[bktIndex].numChannels =
4875 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4876 hddLog(LOG1, FL("Num channels %d"),
4877 pReqMsg->buckets[bktIndex].numChannels);
4878
4879 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4880 j++) {
4881 pReqMsg->buckets[bktIndex].channels[j].channel =
4882 chanList[j];
4883 pReqMsg->buckets[bktIndex].channels[j].
4884 chnlClass = 0;
4885 if (CSR_IS_CHANNEL_DFS(
4886 vos_freq_to_chan(chanList[j]))) {
4887 pReqMsg->buckets[bktIndex].channels[j].
4888 passive = 1;
4889 pReqMsg->buckets[bktIndex].channels[j].
4890 dwellTimeMs = passive_max_chn_time;
4891 } else {
4892 pReqMsg->buckets[bktIndex].channels[j].
4893 passive = 0;
4894 pReqMsg->buckets[bktIndex].channels[j].
4895 dwellTimeMs = active_max_chn_time;
4896 }
4897
4898 hddLog(LOG1,
4899 "Channel %u Passive %u Dwell time %u ms",
4900 pReqMsg->buckets[bktIndex].channels[j].channel,
4901 pReqMsg->buckets[bktIndex].channels[j].passive,
4902 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4903 }
4904
4905 bktIndex++;
4906 continue;
4907 }
4908
4909 /* Parse and fetch number of channels */
4910 if (!bucket[
4911 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4912 hddLog(LOGE, FL("attr num channels failed"));
4913 return -EINVAL;
4914 }
4915
4916 pReqMsg->buckets[bktIndex].numChannels =
4917 nla_get_u32(bucket[
4918 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4919 hddLog(LOG1, FL("num channels %d"),
4920 pReqMsg->buckets[bktIndex].numChannels);
4921
4922 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4923 hddLog(LOGE, FL("attr channel spec failed"));
4924 return -EINVAL;
4925 }
4926
4927 j = 0;
4928 nla_for_each_nested(channels,
4929 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4930 if (nla_parse(channel,
4931 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4932 nla_data(channels), nla_len(channels),
4933 wlan_hdd_extscan_config_policy)) {
4934 hddLog(LOGE, FL("nla_parse failed"));
4935 return -EINVAL;
4936 }
4937
4938 /* Parse and fetch channel */
4939 if (!channel[
4940 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4941 hddLog(LOGE, FL("attr channel failed"));
4942 return -EINVAL;
4943 }
4944 pReqMsg->buckets[bktIndex].channels[j].channel =
4945 nla_get_u32(channel[
4946 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4947 hddLog(LOG1, FL("channel %u"),
4948 pReqMsg->buckets[bktIndex].channels[j].channel);
4949
4950 /* Parse and fetch dwell time */
4951 if (!channel[
4952 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4953 hddLog(LOGE, FL("attr dwelltime failed"));
4954 return -EINVAL;
4955 }
4956 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4957 nla_get_u32(channel[
4958 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4959
4960 hddLog(LOG1, FL("Dwell time (%u ms)"),
4961 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4962
4963
4964 /* Parse and fetch channel spec passive */
4965 if (!channel[
4966 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4967 hddLog(LOGE,
4968 FL("attr channel spec passive failed"));
4969 return -EINVAL;
4970 }
4971 pReqMsg->buckets[bktIndex].channels[j].passive =
4972 nla_get_u8(channel[
4973 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4974 hddLog(LOG1, FL("Chnl spec passive %u"),
4975 pReqMsg->buckets[bktIndex].channels[j].passive);
4976
4977 j++;
4978 }
4979
4980 bktIndex++;
4981 }
4982
4983 return 0;
4984}
4985
4986
4987/*
4988 * define short names for the global vendor params
4989 * used by wlan_hdd_cfg80211_extscan_start()
4990 */
4991#define PARAM_MAX \
4992QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4993#define PARAM_REQUEST_ID \
4994QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4995#define PARAM_BASE_PERIOD \
4996QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4997#define PARAM_MAX_AP_PER_SCAN \
4998QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4999#define PARAM_RPT_THRHLD_PERCENT \
5000QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
5001#define PARAM_RPT_THRHLD_NUM_SCANS \
5002QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
5003#define PARAM_NUM_BUCKETS \
5004QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
5005
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305006static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305007 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305008 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305009{
Dino Myclee8843b32014-07-04 14:21:45 +05305010 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305011 struct net_device *dev = wdev->netdev;
5012 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5013 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5014 struct nlattr *tb[PARAM_MAX + 1];
5015 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305016 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305017 tANI_U32 request_id;
5018 struct hdd_ext_scan_context *context;
5019 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305020
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305021 ENTER();
5022
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305023 if (VOS_FTM_MODE == hdd_get_conparam()) {
5024 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5025 return -EINVAL;
5026 }
5027
Dino Mycle6fb96c12014-06-10 11:52:40 +05305028 status = wlan_hdd_validate_context(pHddCtx);
5029 if (0 != status)
5030 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305031 return -EINVAL;
5032 }
Dino Myclee8843b32014-07-04 14:21:45 +05305033 /* check the EXTScan Capability */
5034 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305035 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5036 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305037 {
5038 hddLog(VOS_TRACE_LEVEL_ERROR,
5039 FL("EXTScan not enabled/supported by Firmware"));
5040 return -EINVAL;
5041 }
5042
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305043 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305044 data, dataLen,
5045 wlan_hdd_extscan_config_policy)) {
5046 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5047 return -EINVAL;
5048 }
5049
5050 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305051 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305052 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5053 return -EINVAL;
5054 }
5055
Dino Myclee8843b32014-07-04 14:21:45 +05305056 pReqMsg = (tpSirEXTScanStartReqParams)
5057 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305058 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305059 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5060 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305061 }
5062
5063 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305064 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305065 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5066
5067 pReqMsg->sessionId = pAdapter->sessionId;
5068 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5069
5070 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305071 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305072 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5073 goto fail;
5074 }
5075 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305076 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305077 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5078 pReqMsg->basePeriod);
5079
5080 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305081 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305082 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5083 goto fail;
5084 }
5085 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305086 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305087 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5088 pReqMsg->maxAPperScan);
5089
5090 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305091 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305092 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5093 goto fail;
5094 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305095 pReqMsg->reportThresholdPercent = nla_get_u8(
5096 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305097 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305098 pReqMsg->reportThresholdPercent);
5099
5100 /* Parse and fetch report threshold num scans */
5101 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5102 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5103 goto fail;
5104 }
5105 pReqMsg->reportThresholdNumScans = nla_get_u8(
5106 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5107 hddLog(LOG1, FL("Report Threshold num scans %d"),
5108 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305109
5110 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305111 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305112 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5113 goto fail;
5114 }
5115 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305116 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305117 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5118 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5119 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5120 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5121 }
5122 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5123 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305124
Dino Mycle6fb96c12014-06-10 11:52:40 +05305125 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5126 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5127 goto fail;
5128 }
5129
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305130 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305131
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305132 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5133 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305134
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305135 context = &pHddCtx->ext_scan_context;
5136 spin_lock(&hdd_context_lock);
5137 INIT_COMPLETION(context->response_event);
5138 context->request_id = request_id = pReqMsg->requestId;
5139 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305140
Dino Mycle6fb96c12014-06-10 11:52:40 +05305141 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5142 if (!HAL_STATUS_SUCCESS(status)) {
5143 hddLog(VOS_TRACE_LEVEL_ERROR,
5144 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305145 goto fail;
5146 }
5147
Srinivas Dasari91727c12016-03-23 17:59:06 +05305148 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5149
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305150 /* request was sent -- wait for the response */
5151 rc = wait_for_completion_timeout(&context->response_event,
5152 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5153
5154 if (!rc) {
5155 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5156 retval = -ETIMEDOUT;
5157 } else {
5158 spin_lock(&hdd_context_lock);
5159 if (context->request_id == request_id)
5160 retval = context->response_status;
5161 else
5162 retval = -EINVAL;
5163 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305164 }
5165
Dino Myclee8843b32014-07-04 14:21:45 +05305166 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305167 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305168 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305169
5170fail:
5171 vos_mem_free(pReqMsg);
5172 return -EINVAL;
5173}
5174
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305175/*
5176 * done with short names for the global vendor params
5177 * used by wlan_hdd_cfg80211_extscan_start()
5178 */
5179#undef PARAM_MAX
5180#undef PARAM_REQUEST_ID
5181#undef PARAM_BASE_PERIOD
5182#undef PARAMS_MAX_AP_PER_SCAN
5183#undef PARAMS_RPT_THRHLD_PERCENT
5184#undef PARAMS_RPT_THRHLD_NUM_SCANS
5185#undef PARAMS_NUM_BUCKETS
5186
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305187static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5188 struct wireless_dev *wdev,
5189 const void *data, int dataLen)
5190{
5191 int ret = 0;
5192
5193 vos_ssr_protect(__func__);
5194 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5195 vos_ssr_unprotect(__func__);
5196
5197 return ret;
5198}
5199
5200static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305201 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305202 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305203{
Dino Myclee8843b32014-07-04 14:21:45 +05305204 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305205 struct net_device *dev = wdev->netdev;
5206 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5207 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5208 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5209 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305210 int retval;
5211 unsigned long rc;
5212 struct hdd_ext_scan_context *context;
5213 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305214
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305215 ENTER();
5216
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305217 if (VOS_FTM_MODE == hdd_get_conparam()) {
5218 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5219 return -EINVAL;
5220 }
5221
Dino Mycle6fb96c12014-06-10 11:52:40 +05305222 status = wlan_hdd_validate_context(pHddCtx);
5223 if (0 != status)
5224 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305225 return -EINVAL;
5226 }
Dino Myclee8843b32014-07-04 14:21:45 +05305227 /* check the EXTScan Capability */
5228 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305229 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5230 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305231 {
5232 hddLog(VOS_TRACE_LEVEL_ERROR,
5233 FL("EXTScan not enabled/supported by Firmware"));
5234 return -EINVAL;
5235 }
5236
Dino Mycle6fb96c12014-06-10 11:52:40 +05305237 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5238 data, dataLen,
5239 wlan_hdd_extscan_config_policy)) {
5240 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5241 return -EINVAL;
5242 }
5243
5244 /* Parse and fetch request Id */
5245 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5246 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5247 return -EINVAL;
5248 }
5249
Dino Myclee8843b32014-07-04 14:21:45 +05305250 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305251 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305252 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305253
Dino Myclee8843b32014-07-04 14:21:45 +05305254 reqMsg.sessionId = pAdapter->sessionId;
5255 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305256
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305257 context = &pHddCtx->ext_scan_context;
5258 spin_lock(&hdd_context_lock);
5259 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305260 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305261 spin_unlock(&hdd_context_lock);
5262
Dino Myclee8843b32014-07-04 14:21:45 +05305263 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305264 if (!HAL_STATUS_SUCCESS(status)) {
5265 hddLog(VOS_TRACE_LEVEL_ERROR,
5266 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305267 return -EINVAL;
5268 }
5269
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305270 /* request was sent -- wait for the response */
5271 rc = wait_for_completion_timeout(&context->response_event,
5272 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5273
5274 if (!rc) {
5275 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5276 retval = -ETIMEDOUT;
5277 } else {
5278 spin_lock(&hdd_context_lock);
5279 if (context->request_id == request_id)
5280 retval = context->response_status;
5281 else
5282 retval = -EINVAL;
5283 spin_unlock(&hdd_context_lock);
5284 }
5285
5286 return retval;
5287
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305288 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305289 return 0;
5290}
5291
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305292static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5293 struct wireless_dev *wdev,
5294 const void *data, int dataLen)
5295{
5296 int ret = 0;
5297
5298 vos_ssr_protect(__func__);
5299 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5300 vos_ssr_unprotect(__func__);
5301
5302 return ret;
5303}
5304
5305static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305306 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305307 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305308{
Dino Myclee8843b32014-07-04 14:21:45 +05305309 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305310 struct net_device *dev = wdev->netdev;
5311 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5312 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5313 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5314 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305315 struct hdd_ext_scan_context *context;
5316 tANI_U32 request_id;
5317 unsigned long rc;
5318 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305319
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305320 ENTER();
5321
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305322 if (VOS_FTM_MODE == hdd_get_conparam()) {
5323 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5324 return -EINVAL;
5325 }
5326
Dino Mycle6fb96c12014-06-10 11:52:40 +05305327 status = wlan_hdd_validate_context(pHddCtx);
5328 if (0 != status)
5329 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305330 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305331 return -EINVAL;
5332 }
Dino Myclee8843b32014-07-04 14:21:45 +05305333 /* check the EXTScan Capability */
5334 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305335 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5336 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305337 {
5338 hddLog(VOS_TRACE_LEVEL_ERROR,
5339 FL("EXTScan not enabled/supported by Firmware"));
5340 return -EINVAL;
5341 }
5342
Dino Mycle6fb96c12014-06-10 11:52:40 +05305343 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5344 data, dataLen,
5345 wlan_hdd_extscan_config_policy)) {
5346 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5347 return -EINVAL;
5348 }
5349
5350 /* Parse and fetch request Id */
5351 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5352 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5353 return -EINVAL;
5354 }
5355
Dino Myclee8843b32014-07-04 14:21:45 +05305356 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305357 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305358 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305359
Dino Myclee8843b32014-07-04 14:21:45 +05305360 reqMsg.sessionId = pAdapter->sessionId;
5361 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305362
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305363 context = &pHddCtx->ext_scan_context;
5364 spin_lock(&hdd_context_lock);
5365 INIT_COMPLETION(context->response_event);
5366 context->request_id = request_id = reqMsg.requestId;
5367 spin_unlock(&hdd_context_lock);
5368
Dino Myclee8843b32014-07-04 14:21:45 +05305369 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305370 if (!HAL_STATUS_SUCCESS(status)) {
5371 hddLog(VOS_TRACE_LEVEL_ERROR,
5372 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305373 return -EINVAL;
5374 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305375
5376 /* request was sent -- wait for the response */
5377 rc = wait_for_completion_timeout(&context->response_event,
5378 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5379 if (!rc) {
5380 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5381 retval = -ETIMEDOUT;
5382 } else {
5383 spin_lock(&hdd_context_lock);
5384 if (context->request_id == request_id)
5385 retval = context->response_status;
5386 else
5387 retval = -EINVAL;
5388 spin_unlock(&hdd_context_lock);
5389 }
5390
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305391 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305392 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305393}
5394
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305395static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5396 struct wireless_dev *wdev,
5397 const void *data, int dataLen)
5398{
5399 int ret = 0;
5400
5401 vos_ssr_protect(__func__);
5402 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5403 vos_ssr_unprotect(__func__);
5404
5405 return ret;
5406}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305407#endif /* WLAN_FEATURE_EXTSCAN */
5408
Atul Mittal115287b2014-07-08 13:26:33 +05305409/*EXT TDLS*/
5410static const struct nla_policy
5411wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5412{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305413 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5414 .type = NLA_UNSPEC,
5415 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305416 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5417 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5418 {.type = NLA_S32 },
5419 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5420 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5421
5422};
5423
5424static const struct nla_policy
5425wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5426{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305427 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5428 .type = NLA_UNSPEC,
5429 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305430
5431};
5432
5433static const struct nla_policy
5434wlan_hdd_tdls_config_state_change_policy[
5435 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5436{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305437 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5438 .type = NLA_UNSPEC,
5439 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305440 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5441 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305442 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5443 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5444 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305445
5446};
5447
5448static const struct nla_policy
5449wlan_hdd_tdls_config_get_status_policy[
5450 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5451{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305452 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5453 .type = NLA_UNSPEC,
5454 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305455 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5456 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305457 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5458 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5459 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305460
5461};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305462
5463static const struct nla_policy
5464wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5465{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305466 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5467 .type = NLA_UNSPEC,
5468 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305469};
5470
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305471static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305472 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305473 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305474 int data_len)
5475{
5476
5477 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5478 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5479
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305480 ENTER();
5481
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305482 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305483 return -EINVAL;
5484 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305485 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305486 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305487 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305488 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305489 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305490 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305491 return -ENOTSUPP;
5492 }
5493
5494 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5495 data, data_len, wlan_hdd_mac_config)) {
5496 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5497 return -EINVAL;
5498 }
5499
5500 /* Parse and fetch mac address */
5501 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5502 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5503 return -EINVAL;
5504 }
5505
5506 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5507 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5508 VOS_MAC_ADDR_LAST_3_BYTES);
5509
Siddharth Bhal76972212014-10-15 16:22:51 +05305510 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5511
5512 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305513 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5514 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305515 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5516 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5517 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5518 {
5519 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5520 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5521 VOS_MAC_ADDRESS_LEN);
5522 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305523 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305524
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305525 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5526 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305527
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305528 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305529 return 0;
5530}
5531
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305532static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5533 struct wireless_dev *wdev,
5534 const void *data,
5535 int data_len)
5536{
5537 int ret = 0;
5538
5539 vos_ssr_protect(__func__);
5540 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5541 vos_ssr_unprotect(__func__);
5542
5543 return ret;
5544}
5545
5546static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305547 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305548 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305549 int data_len)
5550{
5551 u8 peer[6] = {0};
5552 struct net_device *dev = wdev->netdev;
5553 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5554 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5555 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5556 eHalStatus ret;
5557 tANI_S32 state;
5558 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305559 tANI_S32 global_operating_class = 0;
5560 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305561 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305562 int retVal;
5563
5564 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305565
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305566 if (!pAdapter) {
5567 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5568 return -EINVAL;
5569 }
5570
Atul Mittal115287b2014-07-08 13:26:33 +05305571 ret = wlan_hdd_validate_context(pHddCtx);
5572 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305573 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305574 return -EINVAL;
5575 }
5576 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305577 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305578 return -ENOTSUPP;
5579 }
5580 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5581 data, data_len,
5582 wlan_hdd_tdls_config_get_status_policy)) {
5583 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5584 return -EINVAL;
5585 }
5586
5587 /* Parse and fetch mac address */
5588 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5589 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5590 return -EINVAL;
5591 }
5592
5593 memcpy(peer, nla_data(
5594 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5595 sizeof(peer));
5596 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5597
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305598 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305599
Atul Mittal115287b2014-07-08 13:26:33 +05305600 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305601 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305602 NLMSG_HDRLEN);
5603
5604 if (!skb) {
5605 hddLog(VOS_TRACE_LEVEL_ERROR,
5606 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5607 return -EINVAL;
5608 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305609 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 +05305610 reason,
5611 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305612 global_operating_class,
5613 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305614 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305615 if (nla_put_s32(skb,
5616 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5617 state) ||
5618 nla_put_s32(skb,
5619 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5620 reason) ||
5621 nla_put_s32(skb,
5622 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5623 global_operating_class) ||
5624 nla_put_s32(skb,
5625 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5626 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305627
5628 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5629 goto nla_put_failure;
5630 }
5631
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305632 retVal = cfg80211_vendor_cmd_reply(skb);
5633 EXIT();
5634 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305635
5636nla_put_failure:
5637 kfree_skb(skb);
5638 return -EINVAL;
5639}
5640
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305641static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5642 struct wireless_dev *wdev,
5643 const void *data,
5644 int data_len)
5645{
5646 int ret = 0;
5647
5648 vos_ssr_protect(__func__);
5649 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5650 vos_ssr_unprotect(__func__);
5651
5652 return ret;
5653}
5654
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305655static int wlan_hdd_cfg80211_exttdls_callback(
5656#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5657 const tANI_U8* mac,
5658#else
5659 tANI_U8* mac,
5660#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305661 tANI_S32 state,
5662 tANI_S32 reason,
5663 void *ctx)
5664{
5665 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305666 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305667 tANI_S32 global_operating_class = 0;
5668 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305669 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305670
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305671 ENTER();
5672
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305673 if (!pAdapter) {
5674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5675 return -EINVAL;
5676 }
5677
5678 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305679 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305680 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305681 return -EINVAL;
5682 }
5683
5684 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305686 return -ENOTSUPP;
5687 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305688 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5689#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5690 NULL,
5691#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305692 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5693 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5694 GFP_KERNEL);
5695
5696 if (!skb) {
5697 hddLog(VOS_TRACE_LEVEL_ERROR,
5698 FL("cfg80211_vendor_event_alloc failed"));
5699 return -EINVAL;
5700 }
5701 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305702 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5703 reason,
5704 state,
5705 global_operating_class,
5706 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305707 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5708 MAC_ADDR_ARRAY(mac));
5709
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305710 if (nla_put(skb,
5711 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5712 VOS_MAC_ADDR_SIZE, mac) ||
5713 nla_put_s32(skb,
5714 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5715 state) ||
5716 nla_put_s32(skb,
5717 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5718 reason) ||
5719 nla_put_s32(skb,
5720 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5721 channel) ||
5722 nla_put_s32(skb,
5723 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5724 global_operating_class)
5725 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305726 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5727 goto nla_put_failure;
5728 }
5729
5730 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305731 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305732 return (0);
5733
5734nla_put_failure:
5735 kfree_skb(skb);
5736 return -EINVAL;
5737}
5738
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305739static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305740 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305741 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305742 int data_len)
5743{
5744 u8 peer[6] = {0};
5745 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305746 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5747 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5748 eHalStatus status;
5749 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305750 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305751 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305752
5753 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305754
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305755 if (!dev) {
5756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5757 return -EINVAL;
5758 }
5759
5760 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5761 if (!pAdapter) {
5762 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5763 return -EINVAL;
5764 }
5765
Atul Mittal115287b2014-07-08 13:26:33 +05305766 status = wlan_hdd_validate_context(pHddCtx);
5767 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305769 return -EINVAL;
5770 }
5771 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305772 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305773 return -ENOTSUPP;
5774 }
5775 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5776 data, data_len,
5777 wlan_hdd_tdls_config_enable_policy)) {
5778 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5779 return -EINVAL;
5780 }
5781
5782 /* Parse and fetch mac address */
5783 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5785 return -EINVAL;
5786 }
5787
5788 memcpy(peer, nla_data(
5789 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5790 sizeof(peer));
5791 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5792
5793 /* Parse and fetch channel */
5794 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5795 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5796 return -EINVAL;
5797 }
5798 pReqMsg.channel = nla_get_s32(
5799 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5800 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5801
5802 /* Parse and fetch global operating class */
5803 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5805 return -EINVAL;
5806 }
5807 pReqMsg.global_operating_class = nla_get_s32(
5808 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5809 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5810 pReqMsg.global_operating_class);
5811
5812 /* Parse and fetch latency ms */
5813 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5814 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5815 return -EINVAL;
5816 }
5817 pReqMsg.max_latency_ms = nla_get_s32(
5818 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5819 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5820 pReqMsg.max_latency_ms);
5821
5822 /* Parse and fetch required bandwidth kbps */
5823 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5824 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5825 return -EINVAL;
5826 }
5827
5828 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5829 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5830 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5831 pReqMsg.min_bandwidth_kbps);
5832
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305833 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305834 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305835 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305836 wlan_hdd_cfg80211_exttdls_callback);
5837
5838 EXIT();
5839 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305840}
5841
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305842static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5843 struct wireless_dev *wdev,
5844 const void *data,
5845 int data_len)
5846{
5847 int ret = 0;
5848
5849 vos_ssr_protect(__func__);
5850 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5851 vos_ssr_unprotect(__func__);
5852
5853 return ret;
5854}
5855
5856static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305857 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305858 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305859 int data_len)
5860{
5861 u8 peer[6] = {0};
5862 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305863 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5864 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5865 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305866 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305867 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305868
5869 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305870
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305871 if (!dev) {
5872 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5873 return -EINVAL;
5874 }
5875
5876 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5877 if (!pAdapter) {
5878 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5879 return -EINVAL;
5880 }
5881
Atul Mittal115287b2014-07-08 13:26:33 +05305882 status = wlan_hdd_validate_context(pHddCtx);
5883 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305884 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305885 return -EINVAL;
5886 }
5887 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305888 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305889 return -ENOTSUPP;
5890 }
5891 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5892 data, data_len,
5893 wlan_hdd_tdls_config_disable_policy)) {
5894 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5895 return -EINVAL;
5896 }
5897 /* Parse and fetch mac address */
5898 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5899 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5900 return -EINVAL;
5901 }
5902
5903 memcpy(peer, nla_data(
5904 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5905 sizeof(peer));
5906 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5907
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305908 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5909
5910 EXIT();
5911 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305912}
5913
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305914static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5915 struct wireless_dev *wdev,
5916 const void *data,
5917 int data_len)
5918{
5919 int ret = 0;
5920
5921 vos_ssr_protect(__func__);
5922 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5923 vos_ssr_unprotect(__func__);
5924
5925 return ret;
5926}
5927
Dasari Srinivas7875a302014-09-26 17:50:57 +05305928static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305929__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305930 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305931 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305932{
5933 struct net_device *dev = wdev->netdev;
5934 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5935 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5936 struct sk_buff *skb = NULL;
5937 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305938 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305939
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305940 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305941
5942 ret = wlan_hdd_validate_context(pHddCtx);
5943 if (0 != ret)
5944 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305945 return ret;
5946 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305947 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5948 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5949 fset |= WIFI_FEATURE_INFRA;
5950 }
5951
5952 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5953 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5954 fset |= WIFI_FEATURE_INFRA_5G;
5955 }
5956
5957#ifdef WLAN_FEATURE_P2P
5958 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5959 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5960 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5961 fset |= WIFI_FEATURE_P2P;
5962 }
5963#endif
5964
5965 /* Soft-AP is supported currently by default */
5966 fset |= WIFI_FEATURE_SOFT_AP;
5967
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305968 /* HOTSPOT is a supplicant feature, enable it by default */
5969 fset |= WIFI_FEATURE_HOTSPOT;
5970
Dasari Srinivas7875a302014-09-26 17:50:57 +05305971#ifdef WLAN_FEATURE_EXTSCAN
5972 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305973 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5974 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5975 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305976 fset |= WIFI_FEATURE_EXTSCAN;
5977 }
5978#endif
5979
Dasari Srinivas7875a302014-09-26 17:50:57 +05305980 if (sme_IsFeatureSupportedByFW(NAN)) {
5981 hddLog(LOG1, FL("NAN is supported by firmware"));
5982 fset |= WIFI_FEATURE_NAN;
5983 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305984
5985 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05305986 if (sme_IsFeatureSupportedByFW(RTT) &&
5987 pHddCtx->cfg_ini->enable_rtt_support) {
5988 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305989 fset |= WIFI_FEATURE_D2AP_RTT;
5990 }
5991
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305992 if (sme_IsFeatureSupportedByFW(RTT3)) {
5993 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5994 fset |= WIFI_FEATURE_RTT3;
5995 }
5996
Dasari Srinivas7875a302014-09-26 17:50:57 +05305997#ifdef FEATURE_WLAN_BATCH_SCAN
5998 if (fset & WIFI_FEATURE_EXTSCAN) {
5999 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
6000 fset &= ~WIFI_FEATURE_BATCH_SCAN;
6001 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
6002 hddLog(LOG1, FL("Batch scan is supported by firmware"));
6003 fset |= WIFI_FEATURE_BATCH_SCAN;
6004 }
6005#endif
6006
6007#ifdef FEATURE_WLAN_SCAN_PNO
6008 if (pHddCtx->cfg_ini->configPNOScanSupport &&
6009 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
6010 hddLog(LOG1, FL("PNO is supported by firmware"));
6011 fset |= WIFI_FEATURE_PNO;
6012 }
6013#endif
6014
6015 /* STA+STA is supported currently by default */
6016 fset |= WIFI_FEATURE_ADDITIONAL_STA;
6017
6018#ifdef FEATURE_WLAN_TDLS
6019 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6020 sme_IsFeatureSupportedByFW(TDLS)) {
6021 hddLog(LOG1, FL("TDLS is supported by firmware"));
6022 fset |= WIFI_FEATURE_TDLS;
6023 }
6024
6025 /* TDLS_OFFCHANNEL is not supported currently by default */
6026#endif
6027
6028#ifdef WLAN_AP_STA_CONCURRENCY
6029 /* AP+STA concurrency is supported currently by default */
6030 fset |= WIFI_FEATURE_AP_STA;
6031#endif
6032
Mukul Sharma5add0532015-08-17 15:57:47 +05306033#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306034 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6035 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306036 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6037 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306038 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306039#endif
6040
Dasari Srinivas7875a302014-09-26 17:50:57 +05306041 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6042 NLMSG_HDRLEN);
6043
6044 if (!skb) {
6045 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6046 return -EINVAL;
6047 }
6048 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6049
6050 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6051 hddLog(LOGE, FL("nla put fail"));
6052 goto nla_put_failure;
6053 }
6054
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306055 ret = cfg80211_vendor_cmd_reply(skb);
6056 EXIT();
6057 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306058
6059nla_put_failure:
6060 kfree_skb(skb);
6061 return -EINVAL;
6062}
6063
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306064static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306065wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6066 struct wireless_dev *wdev,
6067 const void *data, int data_len)
6068{
6069 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306070 vos_ssr_protect(__func__);
6071 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6072 vos_ssr_unprotect(__func__);
6073
6074 return ret;
6075}
6076
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306077
6078static const struct
6079nla_policy
6080qca_wlan_vendor_wifi_logger_get_ring_data_policy
6081[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6082 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6083 = {.type = NLA_U32 },
6084};
6085
6086static int
6087 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6088 struct wireless_dev *wdev,
6089 const void *data,
6090 int data_len)
6091{
6092 int ret;
6093 VOS_STATUS status;
6094 uint32_t ring_id;
6095 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6096 struct nlattr *tb
6097 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6098
6099 ENTER();
6100
6101 ret = wlan_hdd_validate_context(hdd_ctx);
6102 if (0 != ret) {
6103 return ret;
6104 }
6105
6106 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6107 data, data_len,
6108 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6109 hddLog(LOGE, FL("Invalid attribute"));
6110 return -EINVAL;
6111 }
6112
6113 /* Parse and fetch ring id */
6114 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6115 hddLog(LOGE, FL("attr ATTR failed"));
6116 return -EINVAL;
6117 }
6118
6119 ring_id = nla_get_u32(
6120 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6121
6122 hddLog(LOG1, FL("Bug report triggered by framework"));
6123
6124 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6125 WLAN_LOG_INDICATOR_FRAMEWORK,
6126 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306127 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306128 );
6129 if (VOS_STATUS_SUCCESS != status) {
6130 hddLog(LOGE, FL("Failed to trigger bug report"));
6131
6132 return -EINVAL;
6133 }
6134
6135 return 0;
6136
6137
6138}
6139
6140
6141static int
6142 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6143 struct wireless_dev *wdev,
6144 const void *data,
6145 int data_len)
6146{
6147 int ret = 0;
6148
6149 vos_ssr_protect(__func__);
6150 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6151 wdev, data, data_len);
6152 vos_ssr_unprotect(__func__);
6153
6154 return ret;
6155
6156}
6157
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306158#define MAX_CONCURRENT_MATRIX \
6159 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6160#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6161 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6162static const struct nla_policy
6163wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6164 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6165};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306166
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306167static int
6168__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306169 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306170 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306171{
6172 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6173 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306174 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306175 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306176 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6177 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306178
6179 ENTER();
6180
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306181 ret = wlan_hdd_validate_context(pHddCtx);
6182 if (0 != ret)
6183 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306184 return ret;
6185 }
6186
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306187 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6188 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306189 hddLog(LOGE, FL("Invalid ATTR"));
6190 return -EINVAL;
6191 }
6192
6193 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306194 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306195 hddLog(LOGE, FL("Attr max feature set size failed"));
6196 return -EINVAL;
6197 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306198 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306199 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6200
6201 /* Fill feature combination matrix */
6202 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306203 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6204 WIFI_FEATURE_P2P;
6205
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306206 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6207 WIFI_FEATURE_SOFT_AP;
6208
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306209 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6210 WIFI_FEATURE_SOFT_AP;
6211
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306212 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6213 WIFI_FEATURE_SOFT_AP |
6214 WIFI_FEATURE_P2P;
6215
6216 /* Add more feature combinations here */
6217
6218 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6219 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6220 hddLog(LOG1, "Feature set matrix");
6221 for (i = 0; i < feature_sets; i++)
6222 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6223
6224 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6225 sizeof(u32) * feature_sets +
6226 NLMSG_HDRLEN);
6227
6228 if (reply_skb) {
6229 if (nla_put_u32(reply_skb,
6230 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6231 feature_sets) ||
6232 nla_put(reply_skb,
6233 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6234 sizeof(u32) * feature_sets, feature_set_matrix)) {
6235 hddLog(LOGE, FL("nla put fail"));
6236 kfree_skb(reply_skb);
6237 return -EINVAL;
6238 }
6239
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306240 ret = cfg80211_vendor_cmd_reply(reply_skb);
6241 EXIT();
6242 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306243 }
6244 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6245 return -ENOMEM;
6246
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306247}
6248
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306249#undef MAX_CONCURRENT_MATRIX
6250#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6251
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306252static int
6253wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6254 struct wireless_dev *wdev,
6255 const void *data, int data_len)
6256{
6257 int ret = 0;
6258
6259 vos_ssr_protect(__func__);
6260 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6261 data_len);
6262 vos_ssr_unprotect(__func__);
6263
6264 return ret;
6265}
6266
c_manjeecfd1efb2015-09-25 19:32:34 +05306267
6268static int
6269__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6270 struct wireless_dev *wdev,
6271 const void *data, int data_len)
6272{
6273 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6274 int ret;
6275 ENTER();
6276
6277 ret = wlan_hdd_validate_context(pHddCtx);
6278 if (0 != ret)
6279 {
6280 return ret;
6281 }
6282
6283 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6284 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6285 {
6286 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306287 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306288 }
6289 /*call common API for FW mem dump req*/
6290 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6291
Abhishek Singhc783fa72015-12-09 18:07:34 +05306292 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306293 {
6294 /*indicate to userspace the status of fw mem dump */
6295 wlan_indicate_mem_dump_complete(true);
6296 }
6297 else
6298 {
6299 /*else send failure to userspace */
6300 wlan_indicate_mem_dump_complete(false);
6301 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306302 EXIT();
6303 return ret;
6304}
6305
6306/**
6307 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6308 * @wiphy: pointer to wireless wiphy structure.
6309 * @wdev: pointer to wireless_dev structure.
6310 * @data: Pointer to the NL data.
6311 * @data_len:Length of @data
6312 *
6313 * This is called when wlan driver needs to get the firmware memory dump
6314 * via vendor specific command.
6315 *
6316 * Return: 0 on success, error number otherwise.
6317 */
6318
6319static int
6320wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6321 struct wireless_dev *wdev,
6322 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306323{
6324 int ret = 0;
6325 vos_ssr_protect(__func__);
6326 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6327 data_len);
6328 vos_ssr_unprotect(__func__);
6329 return ret;
6330}
c_manjeecfd1efb2015-09-25 19:32:34 +05306331
Sushant Kaushik8e644982015-09-23 12:18:54 +05306332static const struct
6333nla_policy
6334qca_wlan_vendor_wifi_logger_start_policy
6335[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6336 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6337 = {.type = NLA_U32 },
6338 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6339 = {.type = NLA_U32 },
6340 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6341 = {.type = NLA_U32 },
6342};
6343
6344/**
6345 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6346 * or disable the collection of packet statistics from the firmware
6347 * @wiphy: WIPHY structure pointer
6348 * @wdev: Wireless device structure pointer
6349 * @data: Pointer to the data received
6350 * @data_len: Length of the data received
6351 *
6352 * This function is used to enable or disable the collection of packet
6353 * statistics from the firmware
6354 *
6355 * Return: 0 on success and errno on failure
6356 */
6357static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6358 struct wireless_dev *wdev,
6359 const void *data,
6360 int data_len)
6361{
6362 eHalStatus status;
6363 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6364 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6365 tAniWifiStartLog start_log;
6366
6367 status = wlan_hdd_validate_context(hdd_ctx);
6368 if (0 != status) {
6369 return -EINVAL;
6370 }
6371
6372 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6373 data, data_len,
6374 qca_wlan_vendor_wifi_logger_start_policy)) {
6375 hddLog(LOGE, FL("Invalid attribute"));
6376 return -EINVAL;
6377 }
6378
6379 /* Parse and fetch ring id */
6380 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6381 hddLog(LOGE, FL("attr ATTR failed"));
6382 return -EINVAL;
6383 }
6384 start_log.ringId = nla_get_u32(
6385 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6386 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6387
6388 /* Parse and fetch verbose level */
6389 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6390 hddLog(LOGE, FL("attr verbose_level failed"));
6391 return -EINVAL;
6392 }
6393 start_log.verboseLevel = nla_get_u32(
6394 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6395 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6396
6397 /* Parse and fetch flag */
6398 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6399 hddLog(LOGE, FL("attr flag failed"));
6400 return -EINVAL;
6401 }
6402 start_log.flag = nla_get_u32(
6403 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6404 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6405
6406 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306407 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6408 !vos_isPktStatsEnabled()))
6409
Sushant Kaushik8e644982015-09-23 12:18:54 +05306410 {
6411 hddLog(LOGE, FL("per pkt stats not enabled"));
6412 return -EINVAL;
6413 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306414
Sushant Kaushik33200572015-08-05 16:46:20 +05306415 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306416 return 0;
6417}
6418
6419/**
6420 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6421 * or disable the collection of packet statistics from the firmware
6422 * @wiphy: WIPHY structure pointer
6423 * @wdev: Wireless device structure pointer
6424 * @data: Pointer to the data received
6425 * @data_len: Length of the data received
6426 *
6427 * This function is used to enable or disable the collection of packet
6428 * statistics from the firmware
6429 *
6430 * Return: 0 on success and errno on failure
6431 */
6432static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6433 struct wireless_dev *wdev,
6434 const void *data,
6435 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306436{
6437 int ret = 0;
6438
6439 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306440
6441 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6442 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306443 vos_ssr_unprotect(__func__);
6444
6445 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306446}
6447
6448
Agarwal Ashish738843c2014-09-25 12:27:56 +05306449static const struct nla_policy
6450wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6451 +1] =
6452{
6453 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6454};
6455
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306456static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306457 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306458 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306459 int data_len)
6460{
6461 struct net_device *dev = wdev->netdev;
6462 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6463 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6464 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6465 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6466 eHalStatus status;
6467 u32 dfsFlag = 0;
6468
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306469 ENTER();
6470
Agarwal Ashish738843c2014-09-25 12:27:56 +05306471 status = wlan_hdd_validate_context(pHddCtx);
6472 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306473 return -EINVAL;
6474 }
6475 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6476 data, data_len,
6477 wlan_hdd_set_no_dfs_flag_config_policy)) {
6478 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6479 return -EINVAL;
6480 }
6481
6482 /* Parse and fetch required bandwidth kbps */
6483 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6484 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6485 return -EINVAL;
6486 }
6487
6488 dfsFlag = nla_get_u32(
6489 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6490 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6491 dfsFlag);
6492
6493 pHddCtx->disable_dfs_flag = dfsFlag;
6494
6495 sme_disable_dfs_channel(hHal, dfsFlag);
6496 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306497
6498 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306499 return 0;
6500}
Atul Mittal115287b2014-07-08 13:26:33 +05306501
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306502static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6503 struct wireless_dev *wdev,
6504 const void *data,
6505 int data_len)
6506{
6507 int ret = 0;
6508
6509 vos_ssr_protect(__func__);
6510 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6511 vos_ssr_unprotect(__func__);
6512
6513 return ret;
6514
6515}
6516
Mukul Sharma2a271632014-10-13 14:59:01 +05306517const struct
6518nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6519{
6520 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306521 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6522 .type = NLA_UNSPEC,
6523 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306524};
6525
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306526static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306527 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306528{
6529
6530 u8 bssid[6] = {0};
6531 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6532 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6533 eHalStatus status = eHAL_STATUS_SUCCESS;
6534 v_U32_t isFwrRoamEnabled = FALSE;
6535 int ret;
6536
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306537 ENTER();
6538
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306539 ret = wlan_hdd_validate_context(pHddCtx);
6540 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306541 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306542 }
6543
6544 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6545 data, data_len,
6546 qca_wlan_vendor_attr);
6547 if (ret){
6548 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6549 return -EINVAL;
6550 }
6551
6552 /* Parse and fetch Enable flag */
6553 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6554 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6555 return -EINVAL;
6556 }
6557
6558 isFwrRoamEnabled = nla_get_u32(
6559 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6560
6561 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6562
6563 /* Parse and fetch bssid */
6564 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6565 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6566 return -EINVAL;
6567 }
6568
6569 memcpy(bssid, nla_data(
6570 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6571 sizeof(bssid));
6572 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6573
6574 //Update roaming
6575 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306576 if (!HAL_STATUS_SUCCESS(status)) {
6577 hddLog(LOGE,
6578 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6579 return -EINVAL;
6580 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306581 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306582 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306583}
6584
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306585static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6586 struct wireless_dev *wdev, const void *data, int data_len)
6587{
6588 int ret = 0;
6589
6590 vos_ssr_protect(__func__);
6591 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6592 vos_ssr_unprotect(__func__);
6593
6594 return ret;
6595}
6596
Sushant Kaushik847890c2015-09-28 16:05:17 +05306597static const struct
6598nla_policy
6599qca_wlan_vendor_get_wifi_info_policy[
6600 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6601 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6602 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6603};
6604
6605
6606/**
6607 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6608 * @wiphy: pointer to wireless wiphy structure.
6609 * @wdev: pointer to wireless_dev structure.
6610 * @data: Pointer to the data to be passed via vendor interface
6611 * @data_len:Length of the data to be passed
6612 *
6613 * This is called when wlan driver needs to send wifi driver related info
6614 * (driver/fw version) to the user space application upon request.
6615 *
6616 * Return: Return the Success or Failure code.
6617 */
6618static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6619 struct wireless_dev *wdev,
6620 const void *data, int data_len)
6621{
6622 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6623 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6624 tSirVersionString version;
6625 uint32 version_len;
6626 uint8 attr;
6627 int status;
6628 struct sk_buff *reply_skb = NULL;
6629
6630 if (VOS_FTM_MODE == hdd_get_conparam()) {
6631 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6632 return -EINVAL;
6633 }
6634
6635 status = wlan_hdd_validate_context(hdd_ctx);
6636 if (0 != status) {
6637 hddLog(LOGE, FL("HDD context is not valid"));
6638 return -EINVAL;
6639 }
6640
6641 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6642 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6643 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6644 return -EINVAL;
6645 }
6646
6647 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6648 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6649 QWLAN_VERSIONSTR);
6650 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6651 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6652 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6653 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6654 hdd_ctx->fw_Version);
6655 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6656 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6657 } else {
6658 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6659 return -EINVAL;
6660 }
6661
6662 version_len = strlen(version);
6663 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6664 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6665 if (!reply_skb) {
6666 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6667 return -ENOMEM;
6668 }
6669
6670 if (nla_put(reply_skb, attr, version_len, version)) {
6671 hddLog(LOGE, FL("nla put fail"));
6672 kfree_skb(reply_skb);
6673 return -EINVAL;
6674 }
6675
6676 return cfg80211_vendor_cmd_reply(reply_skb);
6677}
6678
6679/**
6680 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6681 * @wiphy: pointer to wireless wiphy structure.
6682 * @wdev: pointer to wireless_dev structure.
6683 * @data: Pointer to the data to be passed via vendor interface
6684 * @data_len:Length of the data to be passed
6685 * @data_len: Length of the data received
6686 *
6687 * This function is used to enable or disable the collection of packet
6688 * statistics from the firmware
6689 *
6690 * Return: 0 on success and errno on failure
6691 */
6692
6693static int
6694wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6695 struct wireless_dev *wdev,
6696 const void *data, int data_len)
6697
6698
6699{
6700 int ret = 0;
6701
6702 vos_ssr_protect(__func__);
6703 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6704 wdev, data, data_len);
6705 vos_ssr_unprotect(__func__);
6706
6707 return ret;
6708}
6709
6710
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306711/*
6712 * define short names for the global vendor params
6713 * used by __wlan_hdd_cfg80211_monitor_rssi()
6714 */
6715#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6716#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6717#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6718#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6719#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6720
6721/**---------------------------------------------------------------------------
6722
6723 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6724 monitor start is completed successfully.
6725
6726 \return - None
6727
6728 --------------------------------------------------------------------------*/
6729void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6730{
6731 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6732
6733 if (NULL == pHddCtx)
6734 {
6735 hddLog(VOS_TRACE_LEVEL_ERROR,
6736 "%s: HDD context is NULL",__func__);
6737 return;
6738 }
6739
6740 if (VOS_STATUS_SUCCESS == status)
6741 {
6742 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6743 }
6744 else
6745 {
6746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6747 }
6748
6749 return;
6750}
6751
6752/**---------------------------------------------------------------------------
6753
6754 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6755 stop is completed successfully.
6756
6757 \return - None
6758
6759 --------------------------------------------------------------------------*/
6760void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6761{
6762 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6763
6764 if (NULL == pHddCtx)
6765 {
6766 hddLog(VOS_TRACE_LEVEL_ERROR,
6767 "%s: HDD context is NULL",__func__);
6768 return;
6769 }
6770
6771 if (VOS_STATUS_SUCCESS == status)
6772 {
6773 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6774 }
6775 else
6776 {
6777 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6778 }
6779
6780 return;
6781}
6782
6783/**
6784 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6785 * @wiphy: Pointer to wireless phy
6786 * @wdev: Pointer to wireless device
6787 * @data: Pointer to data
6788 * @data_len: Data length
6789 *
6790 * Return: 0 on success, negative errno on failure
6791 */
6792
6793static int
6794__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6795 struct wireless_dev *wdev,
6796 const void *data,
6797 int data_len)
6798{
6799 struct net_device *dev = wdev->netdev;
6800 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6801 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6802 hdd_station_ctx_t *pHddStaCtx;
6803 struct nlattr *tb[PARAM_MAX + 1];
6804 tpSirRssiMonitorReq pReq;
6805 eHalStatus status;
6806 int ret;
6807 uint32_t control;
6808 static const struct nla_policy policy[PARAM_MAX + 1] = {
6809 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6810 [PARAM_CONTROL] = { .type = NLA_U32 },
6811 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6812 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6813 };
6814
6815 ENTER();
6816
6817 ret = wlan_hdd_validate_context(hdd_ctx);
6818 if (0 != ret) {
6819 return -EINVAL;
6820 }
6821
6822 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6823 hddLog(LOGE, FL("Not in Connected state!"));
6824 return -ENOTSUPP;
6825 }
6826
6827 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6828 hddLog(LOGE, FL("Invalid ATTR"));
6829 return -EINVAL;
6830 }
6831
6832 if (!tb[PARAM_REQUEST_ID]) {
6833 hddLog(LOGE, FL("attr request id failed"));
6834 return -EINVAL;
6835 }
6836
6837 if (!tb[PARAM_CONTROL]) {
6838 hddLog(LOGE, FL("attr control failed"));
6839 return -EINVAL;
6840 }
6841
6842 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6843
6844 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6845 if(NULL == pReq)
6846 {
6847 hddLog(LOGE,
6848 FL("vos_mem_alloc failed "));
6849 return eHAL_STATUS_FAILED_ALLOC;
6850 }
6851 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6852
6853 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6854 pReq->sessionId = pAdapter->sessionId;
6855 pReq->rssiMonitorCbContext = hdd_ctx;
6856 control = nla_get_u32(tb[PARAM_CONTROL]);
6857 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6858
6859 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6860 pReq->requestId, pReq->sessionId, control);
6861
6862 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6863 if (!tb[PARAM_MIN_RSSI]) {
6864 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306865 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306866 }
6867
6868 if (!tb[PARAM_MAX_RSSI]) {
6869 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306870 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306871 }
6872
6873 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6874 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6875 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6876
6877 if (!(pReq->minRssi < pReq->maxRssi)) {
6878 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6879 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306880 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306881 }
6882 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6883 pReq->minRssi, pReq->maxRssi);
6884 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6885
6886 }
6887 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6888 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6889 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6890 }
6891 else {
6892 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306893 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306894 }
6895
6896 if (!HAL_STATUS_SUCCESS(status)) {
6897 hddLog(LOGE,
6898 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306899 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306900 }
6901
6902 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306903fail:
6904 vos_mem_free(pReq);
6905 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306906}
6907
6908/*
6909 * done with short names for the global vendor params
6910 * used by __wlan_hdd_cfg80211_monitor_rssi()
6911 */
6912#undef PARAM_MAX
6913#undef PARAM_CONTROL
6914#undef PARAM_REQUEST_ID
6915#undef PARAM_MAX_RSSI
6916#undef PARAM_MIN_RSSI
6917
6918/**
6919 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6920 * @wiphy: wiphy structure pointer
6921 * @wdev: Wireless device structure pointer
6922 * @data: Pointer to the data received
6923 * @data_len: Length of @data
6924 *
6925 * Return: 0 on success; errno on failure
6926 */
6927static int
6928wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6929 const void *data, int data_len)
6930{
6931 int ret;
6932
6933 vos_ssr_protect(__func__);
6934 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6935 vos_ssr_unprotect(__func__);
6936
6937 return ret;
6938}
6939
6940/**
6941 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6942 * @hddctx: HDD context
6943 * @data: rssi breached event data
6944 *
6945 * This function reads the rssi breached event %data and fill in the skb with
6946 * NL attributes and send up the NL event.
6947 * This callback execute in atomic context and must not invoke any
6948 * blocking calls.
6949 *
6950 * Return: none
6951 */
6952void hdd_rssi_threshold_breached_cb(void *hddctx,
6953 struct rssi_breach_event *data)
6954{
6955 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6956 int status;
6957 struct sk_buff *skb;
6958
6959 ENTER();
6960 status = wlan_hdd_validate_context(pHddCtx);
6961
6962 if (0 != status) {
6963 return;
6964 }
6965
6966 if (!data) {
6967 hddLog(LOGE, FL("data is null"));
6968 return;
6969 }
6970
6971 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6972#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6973 NULL,
6974#endif
6975 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6976 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6977 GFP_KERNEL);
6978
6979 if (!skb) {
6980 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6981 return;
6982 }
6983
6984 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6985 data->request_id, data->curr_rssi);
6986 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6987 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6988
6989 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6990 data->request_id) ||
6991 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6992 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6993 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6994 data->curr_rssi)) {
6995 hddLog(LOGE, FL("nla put fail"));
6996 goto fail;
6997 }
6998
6999 cfg80211_vendor_event(skb, GFP_KERNEL);
7000 return;
7001
7002fail:
7003 kfree_skb(skb);
7004 return;
7005}
7006
7007
7008
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307009/**
7010 * __wlan_hdd_cfg80211_setband() - set band
7011 * @wiphy: Pointer to wireless phy
7012 * @wdev: Pointer to wireless device
7013 * @data: Pointer to data
7014 * @data_len: Data length
7015 *
7016 * Return: 0 on success, negative errno on failure
7017 */
7018static int
7019__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7020 struct wireless_dev *wdev,
7021 const void *data,
7022 int data_len)
7023{
7024 struct net_device *dev = wdev->netdev;
7025 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7026 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7027 int ret;
7028 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7029 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7030
7031 ENTER();
7032
7033 ret = wlan_hdd_validate_context(hdd_ctx);
7034 if (0 != ret) {
7035 hddLog(LOGE, FL("HDD context is not valid"));
7036 return ret;
7037 }
7038
7039 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7040 policy)) {
7041 hddLog(LOGE, FL("Invalid ATTR"));
7042 return -EINVAL;
7043 }
7044
7045 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7046 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7047 return -EINVAL;
7048 }
7049
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307050 hdd_ctx->isSetBandByNL = TRUE;
7051 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307052 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307053 hdd_ctx->isSetBandByNL = FALSE;
7054
7055 EXIT();
7056 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307057}
7058
7059/**
7060 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7061 * @wiphy: wiphy structure pointer
7062 * @wdev: Wireless device structure pointer
7063 * @data: Pointer to the data received
7064 * @data_len: Length of @data
7065 *
7066 * Return: 0 on success; errno on failure
7067 */
7068static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7069 struct wireless_dev *wdev,
7070 const void *data,
7071 int data_len)
7072{
7073 int ret = 0;
7074
7075 vos_ssr_protect(__func__);
7076 ret = __wlan_hdd_cfg80211_setband(wiphy,
7077 wdev, data, data_len);
7078 vos_ssr_unprotect(__func__);
7079
7080 return ret;
7081}
7082
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307083#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7084/**
7085 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7086 * @hdd_ctx: HDD context
7087 * @request_id: [input] request id
7088 * @pattern_id: [output] pattern id
7089 *
7090 * This function loops through request id to pattern id array
7091 * if the slot is available, store the request id and return pattern id
7092 * if entry exists, return the pattern id
7093 *
7094 * Return: 0 on success and errno on failure
7095 */
7096static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7097 uint32_t request_id,
7098 uint8_t *pattern_id)
7099{
7100 uint32_t i;
7101
7102 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7103 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7104 {
7105 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7106 {
7107 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7108 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7109 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7110 return 0;
7111 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7112 request_id) {
7113 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7114 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7115 return 0;
7116 }
7117 }
7118 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7119 return -EINVAL;
7120}
7121
7122/**
7123 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7124 * @hdd_ctx: HDD context
7125 * @request_id: [input] request id
7126 * @pattern_id: [output] pattern id
7127 *
7128 * This function loops through request id to pattern id array
7129 * reset request id to 0 (slot available again) and
7130 * return pattern id
7131 *
7132 * Return: 0 on success and errno on failure
7133 */
7134static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7135 uint32_t request_id,
7136 uint8_t *pattern_id)
7137{
7138 uint32_t i;
7139
7140 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7141 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7142 {
7143 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7144 {
7145 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7146 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7147 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7148 return 0;
7149 }
7150 }
7151 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7152 return -EINVAL;
7153}
7154
7155
7156/*
7157 * define short names for the global vendor params
7158 * used by __wlan_hdd_cfg80211_offloaded_packets()
7159 */
7160#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7161#define PARAM_REQUEST_ID \
7162 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7163#define PARAM_CONTROL \
7164 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7165#define PARAM_IP_PACKET \
7166 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7167#define PARAM_SRC_MAC_ADDR \
7168 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7169#define PARAM_DST_MAC_ADDR \
7170 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7171#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7172
7173/**
7174 * wlan_hdd_add_tx_ptrn() - add tx pattern
7175 * @adapter: adapter pointer
7176 * @hdd_ctx: hdd context
7177 * @tb: nl attributes
7178 *
7179 * This function reads the NL attributes and forms a AddTxPtrn message
7180 * posts it to SME.
7181 *
7182 */
7183static int
7184wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7185 struct nlattr **tb)
7186{
7187 struct sSirAddPeriodicTxPtrn *add_req;
7188 eHalStatus status;
7189 uint32_t request_id, ret, len;
7190 uint8_t pattern_id = 0;
7191 v_MACADDR_t dst_addr;
7192 uint16_t eth_type = htons(ETH_P_IP);
7193
7194 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7195 {
7196 hddLog(LOGE, FL("Not in Connected state!"));
7197 return -ENOTSUPP;
7198 }
7199
7200 add_req = vos_mem_malloc(sizeof(*add_req));
7201 if (!add_req)
7202 {
7203 hddLog(LOGE, FL("memory allocation failed"));
7204 return -ENOMEM;
7205 }
7206
7207 /* Parse and fetch request Id */
7208 if (!tb[PARAM_REQUEST_ID])
7209 {
7210 hddLog(LOGE, FL("attr request id failed"));
7211 goto fail;
7212 }
7213
7214 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7215 hddLog(LOG1, FL("Request Id: %u"), request_id);
7216 if (request_id == 0)
7217 {
7218 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307219 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307220 }
7221
7222 if (!tb[PARAM_PERIOD])
7223 {
7224 hddLog(LOGE, FL("attr period failed"));
7225 goto fail;
7226 }
7227 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7228 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7229 if (add_req->usPtrnIntervalMs == 0)
7230 {
7231 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7232 goto fail;
7233 }
7234
7235 if (!tb[PARAM_SRC_MAC_ADDR])
7236 {
7237 hddLog(LOGE, FL("attr source mac address failed"));
7238 goto fail;
7239 }
7240 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7241 VOS_MAC_ADDR_SIZE);
7242 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7243 MAC_ADDR_ARRAY(add_req->macAddress));
7244
7245 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7246 VOS_MAC_ADDR_SIZE))
7247 {
7248 hddLog(LOGE,
7249 FL("input src mac address and connected ap bssid are different"));
7250 goto fail;
7251 }
7252
7253 if (!tb[PARAM_DST_MAC_ADDR])
7254 {
7255 hddLog(LOGE, FL("attr dst mac address failed"));
7256 goto fail;
7257 }
7258 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7259 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7260 MAC_ADDR_ARRAY(dst_addr.bytes));
7261
7262 if (!tb[PARAM_IP_PACKET])
7263 {
7264 hddLog(LOGE, FL("attr ip packet failed"));
7265 goto fail;
7266 }
7267 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7268 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7269
7270 if (add_req->ucPtrnSize < 0 ||
7271 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7272 HDD_ETH_HEADER_LEN))
7273 {
7274 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7275 add_req->ucPtrnSize);
7276 goto fail;
7277 }
7278
7279 len = 0;
7280 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7281 len += VOS_MAC_ADDR_SIZE;
7282 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7283 VOS_MAC_ADDR_SIZE);
7284 len += VOS_MAC_ADDR_SIZE;
7285 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7286 len += 2;
7287
7288 /*
7289 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7290 * ------------------------------------------------------------
7291 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7292 * ------------------------------------------------------------
7293 */
7294 vos_mem_copy(&add_req->ucPattern[len],
7295 nla_data(tb[PARAM_IP_PACKET]),
7296 add_req->ucPtrnSize);
7297 add_req->ucPtrnSize += len;
7298
7299 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7300 add_req->ucPattern, add_req->ucPtrnSize);
7301
7302 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7303 if (ret)
7304 {
7305 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7306 goto fail;
7307 }
7308 add_req->ucPtrnId = pattern_id;
7309 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7310
7311 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7312 if (!HAL_STATUS_SUCCESS(status))
7313 {
7314 hddLog(LOGE,
7315 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7316 goto fail;
7317 }
7318
7319 EXIT();
7320 vos_mem_free(add_req);
7321 return 0;
7322
7323fail:
7324 vos_mem_free(add_req);
7325 return -EINVAL;
7326}
7327
7328/**
7329 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7330 * @adapter: adapter pointer
7331 * @hdd_ctx: hdd context
7332 * @tb: nl attributes
7333 *
7334 * This function reads the NL attributes and forms a DelTxPtrn message
7335 * posts it to SME.
7336 *
7337 */
7338static int
7339wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7340 struct nlattr **tb)
7341{
7342 struct sSirDelPeriodicTxPtrn *del_req;
7343 eHalStatus status;
7344 uint32_t request_id, ret;
7345 uint8_t pattern_id = 0;
7346
7347 /* Parse and fetch request Id */
7348 if (!tb[PARAM_REQUEST_ID])
7349 {
7350 hddLog(LOGE, FL("attr request id failed"));
7351 return -EINVAL;
7352 }
7353 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7354 if (request_id == 0)
7355 {
7356 hddLog(LOGE, FL("request_id cannot be zero"));
7357 return -EINVAL;
7358 }
7359
7360 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7361 if (ret)
7362 {
7363 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7364 return -EINVAL;
7365 }
7366
7367 del_req = vos_mem_malloc(sizeof(*del_req));
7368 if (!del_req)
7369 {
7370 hddLog(LOGE, FL("memory allocation failed"));
7371 return -ENOMEM;
7372 }
7373
7374 vos_mem_set(del_req, sizeof(*del_req), 0);
7375 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7376 VOS_MAC_ADDR_SIZE);
7377 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7378 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7379 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7380 request_id, pattern_id, del_req->ucPatternIdBitmap);
7381
7382 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7383 if (!HAL_STATUS_SUCCESS(status))
7384 {
7385 hddLog(LOGE,
7386 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7387 goto fail;
7388 }
7389
7390 EXIT();
7391 vos_mem_free(del_req);
7392 return 0;
7393
7394fail:
7395 vos_mem_free(del_req);
7396 return -EINVAL;
7397}
7398
7399
7400/**
7401 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7402 * @wiphy: Pointer to wireless phy
7403 * @wdev: Pointer to wireless device
7404 * @data: Pointer to data
7405 * @data_len: Data length
7406 *
7407 * Return: 0 on success, negative errno on failure
7408 */
7409static int
7410__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7411 struct wireless_dev *wdev,
7412 const void *data,
7413 int data_len)
7414{
7415 struct net_device *dev = wdev->netdev;
7416 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7417 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7418 struct nlattr *tb[PARAM_MAX + 1];
7419 uint8_t control;
7420 int ret;
7421 static const struct nla_policy policy[PARAM_MAX + 1] =
7422 {
7423 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7424 [PARAM_CONTROL] = { .type = NLA_U32 },
7425 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7426 .len = VOS_MAC_ADDR_SIZE },
7427 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7428 .len = VOS_MAC_ADDR_SIZE },
7429 [PARAM_PERIOD] = { .type = NLA_U32 },
7430 };
7431
7432 ENTER();
7433
7434 ret = wlan_hdd_validate_context(hdd_ctx);
7435 if (0 != ret)
7436 {
7437 hddLog(LOGE, FL("HDD context is not valid"));
7438 return ret;
7439 }
7440
7441 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7442 {
7443 hddLog(LOGE,
7444 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7445 return -ENOTSUPP;
7446 }
7447
7448 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7449 {
7450 hddLog(LOGE, FL("Invalid ATTR"));
7451 return -EINVAL;
7452 }
7453
7454 if (!tb[PARAM_CONTROL])
7455 {
7456 hddLog(LOGE, FL("attr control failed"));
7457 return -EINVAL;
7458 }
7459 control = nla_get_u32(tb[PARAM_CONTROL]);
7460 hddLog(LOG1, FL("Control: %d"), control);
7461
7462 if (control == WLAN_START_OFFLOADED_PACKETS)
7463 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7464 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7465 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7466 else
7467 {
7468 hddLog(LOGE, FL("Invalid control: %d"), control);
7469 return -EINVAL;
7470 }
7471}
7472
7473/*
7474 * done with short names for the global vendor params
7475 * used by __wlan_hdd_cfg80211_offloaded_packets()
7476 */
7477#undef PARAM_MAX
7478#undef PARAM_REQUEST_ID
7479#undef PARAM_CONTROL
7480#undef PARAM_IP_PACKET
7481#undef PARAM_SRC_MAC_ADDR
7482#undef PARAM_DST_MAC_ADDR
7483#undef PARAM_PERIOD
7484
7485/**
7486 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7487 * @wiphy: wiphy structure pointer
7488 * @wdev: Wireless device structure pointer
7489 * @data: Pointer to the data received
7490 * @data_len: Length of @data
7491 *
7492 * Return: 0 on success; errno on failure
7493 */
7494static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7495 struct wireless_dev *wdev,
7496 const void *data,
7497 int data_len)
7498{
7499 int ret = 0;
7500
7501 vos_ssr_protect(__func__);
7502 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7503 wdev, data, data_len);
7504 vos_ssr_unprotect(__func__);
7505
7506 return ret;
7507}
7508#endif
7509
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307510static const struct
7511nla_policy
7512qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307513 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7514 .type = NLA_BINARY,
7515 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307516};
7517
7518/**
7519 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7520 * get link properties like nss, rate flags and operating frequency for
7521 * the connection with the given peer.
7522 * @wiphy: WIPHY structure pointer
7523 * @wdev: Wireless device structure pointer
7524 * @data: Pointer to the data received
7525 * @data_len: Length of the data received
7526 *
7527 * This function return the above link properties on success.
7528 *
7529 * Return: 0 on success and errno on failure
7530 */
7531static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7532 struct wireless_dev *wdev,
7533 const void *data,
7534 int data_len)
7535{
7536 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7537 struct net_device *dev = wdev->netdev;
7538 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7539 hdd_station_ctx_t *hdd_sta_ctx;
7540 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7541 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7542 uint32_t sta_id;
7543 struct sk_buff *reply_skb;
7544 uint32_t rate_flags = 0;
7545 uint8_t nss;
7546 uint8_t final_rate_flags = 0;
7547 uint32_t freq;
7548 v_CONTEXT_t pVosContext = NULL;
7549 ptSapContext pSapCtx = NULL;
7550
7551 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7552 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7553 return -EINVAL;
7554 }
7555
7556 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7557 qca_wlan_vendor_attr_policy)) {
7558 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7559 return -EINVAL;
7560 }
7561
7562 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7563 hddLog(VOS_TRACE_LEVEL_ERROR,
7564 FL("Attribute peerMac not provided for mode=%d"),
7565 adapter->device_mode);
7566 return -EINVAL;
7567 }
7568
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307569 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7570 hddLog(VOS_TRACE_LEVEL_ERROR,
7571 FL("Attribute peerMac is invalid=%d"),
7572 adapter->device_mode);
7573 return -EINVAL;
7574 }
7575
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307576 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7577 sizeof(peer_mac));
7578 hddLog(VOS_TRACE_LEVEL_INFO,
7579 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7580 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7581
7582 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7583 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7584 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7585 if ((hdd_sta_ctx->conn_info.connState !=
7586 eConnectionState_Associated) ||
7587 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7588 VOS_MAC_ADDRESS_LEN)) {
7589 hddLog(VOS_TRACE_LEVEL_ERROR,
7590 FL("Not Associated to mac "MAC_ADDRESS_STR),
7591 MAC_ADDR_ARRAY(peer_mac));
7592 return -EINVAL;
7593 }
7594
7595 nss = 1; //pronto supports only one spatial stream
7596 freq = vos_chan_to_freq(
7597 hdd_sta_ctx->conn_info.operationChannel);
7598 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7599
7600 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7601 adapter->device_mode == WLAN_HDD_SOFTAP) {
7602
7603 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7604 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7605 if(pSapCtx == NULL){
7606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7607 FL("psapCtx is NULL"));
7608 return -ENOENT;
7609 }
7610
7611
7612 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7613 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7614 !vos_is_macaddr_broadcast(
7615 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7616 vos_mem_compare(
7617 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7618 peer_mac, VOS_MAC_ADDRESS_LEN))
7619 break;
7620 }
7621
7622 if (WLAN_MAX_STA_COUNT == sta_id) {
7623 hddLog(VOS_TRACE_LEVEL_ERROR,
7624 FL("No active peer with mac="MAC_ADDRESS_STR),
7625 MAC_ADDR_ARRAY(peer_mac));
7626 return -EINVAL;
7627 }
7628
7629 nss = 1; //pronto supports only one spatial stream
7630 freq = vos_chan_to_freq(
7631 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7632 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7633 } else {
7634 hddLog(VOS_TRACE_LEVEL_ERROR,
7635 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7636 MAC_ADDR_ARRAY(peer_mac));
7637 return -EINVAL;
7638 }
7639
7640 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7641 if (rate_flags & eHAL_TX_RATE_VHT80) {
7642 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307643#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7644 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307645 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307646#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307647 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7648 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307649#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7650 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307651 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307652#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307653 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7654 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7655 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7656 final_rate_flags |= RATE_INFO_FLAGS_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307657#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7658 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307659 if (rate_flags & eHAL_TX_RATE_HT40)
7660 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307661#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307662 }
7663
7664 if (rate_flags & eHAL_TX_RATE_SGI) {
7665 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7666 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7667 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7668 }
7669 }
7670
7671 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7672 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7673
7674 if (NULL == reply_skb) {
7675 hddLog(VOS_TRACE_LEVEL_ERROR,
7676 FL("getLinkProperties: skb alloc failed"));
7677 return -EINVAL;
7678 }
7679
7680 if (nla_put_u8(reply_skb,
7681 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7682 nss) ||
7683 nla_put_u8(reply_skb,
7684 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7685 final_rate_flags) ||
7686 nla_put_u32(reply_skb,
7687 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7688 freq)) {
7689 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7690 kfree_skb(reply_skb);
7691 return -EINVAL;
7692 }
7693
7694 return cfg80211_vendor_cmd_reply(reply_skb);
7695}
7696
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307697#define BEACON_MISS_THRESH_2_4 \
7698 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7699#define BEACON_MISS_THRESH_5_0 \
7700 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307701#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7702#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7703#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7704#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307705#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7706 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307707
7708/**
7709 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7710 * vendor command
7711 *
7712 * @wiphy: wiphy device pointer
7713 * @wdev: wireless device pointer
7714 * @data: Vendor command data buffer
7715 * @data_len: Buffer length
7716 *
7717 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7718 *
7719 * Return: EOK or other error codes.
7720 */
7721
7722static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7723 struct wireless_dev *wdev,
7724 const void *data,
7725 int data_len)
7726{
7727 struct net_device *dev = wdev->netdev;
7728 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7729 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7730 hdd_station_ctx_t *pHddStaCtx;
7731 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7732 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307733 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307734 eHalStatus status;
7735 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307736 uint8_t hb_thresh_val;
7737
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307738 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7739 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7740 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307741 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7742 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7743 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307744 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7745 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307746 };
7747
7748 ENTER();
7749
7750 if (VOS_FTM_MODE == hdd_get_conparam()) {
7751 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7752 return -EINVAL;
7753 }
7754
7755 ret_val = wlan_hdd_validate_context(pHddCtx);
7756 if (ret_val) {
7757 return ret_val;
7758 }
7759
7760 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7761
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307762 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7763 hddLog(LOGE, FL("Invalid ATTR"));
7764 return -EINVAL;
7765 }
7766
7767 /* check the Wifi Capability */
7768 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7769 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7770 {
7771 hddLog(VOS_TRACE_LEVEL_ERROR,
7772 FL("WIFICONFIG not supported by Firmware"));
7773 return -EINVAL;
7774 }
7775
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307776 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7777 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7778 modifyRoamParamsReq.value =
7779 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7780
7781 if (eHAL_STATUS_SUCCESS !=
7782 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7783 {
7784 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7785 ret_val = -EINVAL;
7786 }
7787 return ret_val;
7788 }
7789
7790 /* Moved this down in order to provide provision to set beacon
7791 * miss penalty count irrespective of connection state.
7792 */
7793 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7794 hddLog(LOGE, FL("Not in Connected state!"));
7795 return -ENOTSUPP;
7796 }
7797
7798 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307799
7800 if (!pReq) {
7801 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7802 "%s: Not able to allocate memory for tSetWifiConfigParams",
7803 __func__);
7804 return eHAL_STATUS_E_MALLOC_FAILED;
7805 }
7806
7807 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7808
7809 pReq->sessionId = pAdapter->sessionId;
7810 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7811
7812 if (tb[PARAM_MODULATED_DTIM]) {
7813 pReq->paramValue = nla_get_u32(
7814 tb[PARAM_MODULATED_DTIM]);
7815 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7816 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307817 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307818 hdd_set_pwrparams(pHddCtx);
7819 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7820 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7821
7822 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7823 iw_full_power_cbfn, pAdapter,
7824 eSME_FULL_PWR_NEEDED_BY_HDD);
7825 }
7826 else
7827 {
7828 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7829 }
7830 }
7831
7832 if (tb[PARAM_STATS_AVG_FACTOR]) {
7833 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7834 pReq->paramValue = nla_get_u16(
7835 tb[PARAM_STATS_AVG_FACTOR]);
7836 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7837 pReq->paramType, pReq->paramValue);
7838 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7839
7840 if (eHAL_STATUS_SUCCESS != status)
7841 {
7842 vos_mem_free(pReq);
7843 pReq = NULL;
7844 ret_val = -EPERM;
7845 return ret_val;
7846 }
7847 }
7848
7849
7850 if (tb[PARAM_GUARD_TIME]) {
7851 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7852 pReq->paramValue = nla_get_u32(
7853 tb[PARAM_GUARD_TIME]);
7854 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7855 pReq->paramType, pReq->paramValue);
7856 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7857
7858 if (eHAL_STATUS_SUCCESS != status)
7859 {
7860 vos_mem_free(pReq);
7861 pReq = NULL;
7862 ret_val = -EPERM;
7863 return ret_val;
7864 }
7865
7866 }
7867
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307868 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7869 hb_thresh_val = nla_get_u8(
7870 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7871
7872 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7873 hb_thresh_val);
7874 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7875 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7876 NULL, eANI_BOOLEAN_FALSE);
7877
7878 status = sme_update_hb_threshold(
7879 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7880 WNI_CFG_HEART_BEAT_THRESHOLD,
7881 hb_thresh_val, eCSR_BAND_24);
7882 if (eHAL_STATUS_SUCCESS != status) {
7883 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7884 vos_mem_free(pReq);
7885 pReq = NULL;
7886 return -EPERM;
7887 }
7888 }
7889
7890 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7891 hb_thresh_val = nla_get_u8(
7892 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7893
7894 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
7895 hb_thresh_val);
7896 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7897 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7898 NULL, eANI_BOOLEAN_FALSE);
7899
7900 status = sme_update_hb_threshold(
7901 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7902 WNI_CFG_HEART_BEAT_THRESHOLD,
7903 hb_thresh_val, eCSR_BAND_5G);
7904 if (eHAL_STATUS_SUCCESS != status) {
7905 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7906 vos_mem_free(pReq);
7907 pReq = NULL;
7908 return -EPERM;
7909 }
7910 }
7911
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307912 EXIT();
7913 return ret_val;
7914}
7915
7916/**
7917 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7918 * vendor command
7919 *
7920 * @wiphy: wiphy device pointer
7921 * @wdev: wireless device pointer
7922 * @data: Vendor command data buffer
7923 * @data_len: Buffer length
7924 *
7925 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7926 *
7927 * Return: EOK or other error codes.
7928 */
7929static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7930 struct wireless_dev *wdev,
7931 const void *data,
7932 int data_len)
7933{
7934 int ret;
7935
7936 vos_ssr_protect(__func__);
7937 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7938 data, data_len);
7939 vos_ssr_unprotect(__func__);
7940
7941 return ret;
7942}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307943
7944/*
7945 * define short names for the global vendor params
7946 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7947 */
7948#define STATS_SET_INVALID \
7949 QCA_ATTR_NUD_STATS_SET_INVALID
7950#define STATS_SET_START \
7951 QCA_ATTR_NUD_STATS_SET_START
7952#define STATS_GW_IPV4 \
7953 QCA_ATTR_NUD_STATS_GW_IPV4
7954#define STATS_SET_MAX \
7955 QCA_ATTR_NUD_STATS_SET_MAX
7956
7957const struct nla_policy
7958qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
7959{
7960 [STATS_SET_START] = {.type = NLA_FLAG },
7961 [STATS_GW_IPV4] = {.type = NLA_U32 },
7962};
7963
7964/**
7965 * hdd_set_nud_stats_cb() - hdd callback api to get status
7966 * @data: pointer to adapter
7967 * @rsp: status
7968 *
7969 * Return: None
7970 */
7971static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
7972{
7973
7974 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7975
7976 if (NULL == adapter)
7977 return;
7978
7979 if (VOS_STATUS_SUCCESS == rsp) {
7980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7981 "%s success received STATS_SET_START", __func__);
7982 } else {
7983 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7984 "%s STATS_SET_START Failed!!", __func__);
7985 }
7986 return;
7987}
7988
7989/**
7990 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7991 * @wiphy: pointer to wireless wiphy structure.
7992 * @wdev: pointer to wireless_dev structure.
7993 * @data: pointer to apfind configuration data.
7994 * @data_len: the length in byte of apfind data.
7995 *
7996 * This is called when wlan driver needs to send arp stats to
7997 * firmware.
7998 *
7999 * Return: An error code or 0 on success.
8000 */
8001static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8002 struct wireless_dev *wdev,
8003 const void *data, int data_len)
8004{
8005 struct nlattr *tb[STATS_SET_MAX + 1];
8006 struct net_device *dev = wdev->netdev;
8007 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8008 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308009 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308010 setArpStatsParams arp_stats_params;
8011 int err = 0;
8012
8013 ENTER();
8014
8015 err = wlan_hdd_validate_context(hdd_ctx);
8016 if (0 != err)
8017 return err;
8018
8019 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8021 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8022 return -EINVAL;
8023 }
8024
8025 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8026 qca_wlan_vendor_set_nud_stats);
8027 if (err)
8028 {
8029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8030 "%s STATS_SET_START ATTR", __func__);
8031 return err;
8032 }
8033
8034 if (tb[STATS_SET_START])
8035 {
8036 if (!tb[STATS_GW_IPV4]) {
8037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8038 "%s STATS_SET_START CMD", __func__);
8039 return -EINVAL;
8040 }
8041 arp_stats_params.flag = true;
8042 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8043 } else {
8044 arp_stats_params.flag = false;
8045 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308046 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8048 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308049 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8050 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308051
8052 arp_stats_params.pkt_type = 1; // ARP packet type
8053
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308054 if (arp_stats_params.flag) {
8055 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8056 WLANTL_SetARPFWDatapath(pVosContext, true);
8057 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8058 "%s Set FW in data path for ARP with tgt IP :%d",
8059 __func__, hdd_ctx->track_arp_ip);
8060 }
8061 else {
8062 WLANTL_SetARPFWDatapath(pVosContext, false);
8063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8064 "%s Remove FW from data path", __func__);
8065 }
8066
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308067 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8068 arp_stats_params.data_ctx = adapter;
8069
8070 if (eHAL_STATUS_SUCCESS !=
8071 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8072 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8073 "%s STATS_SET_START CMD Failed!!", __func__);
8074 return -EINVAL;
8075 }
8076
8077 EXIT();
8078
8079 return err;
8080}
8081
8082/**
8083 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8084 * @wiphy: pointer to wireless wiphy structure.
8085 * @wdev: pointer to wireless_dev structure.
8086 * @data: pointer to apfind configuration data.
8087 * @data_len: the length in byte of apfind data.
8088 *
8089 * This is called when wlan driver needs to send arp stats to
8090 * firmware.
8091 *
8092 * Return: An error code or 0 on success.
8093 */
8094static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8095 struct wireless_dev *wdev,
8096 const void *data, int data_len)
8097{
8098 int ret;
8099
8100 vos_ssr_protect(__func__);
8101 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8102 vos_ssr_unprotect(__func__);
8103
8104 return ret;
8105}
8106#undef STATS_SET_INVALID
8107#undef STATS_SET_START
8108#undef STATS_GW_IPV4
8109#undef STATS_SET_MAX
8110
8111/*
8112 * define short names for the global vendor params
8113 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8114 */
8115#define STATS_GET_INVALID \
8116 QCA_ATTR_NUD_STATS_SET_INVALID
8117#define COUNT_FROM_NETDEV \
8118 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8119#define COUNT_TO_LOWER_MAC \
8120 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8121#define RX_COUNT_BY_LOWER_MAC \
8122 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8123#define COUNT_TX_SUCCESS \
8124 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8125#define RSP_RX_COUNT_BY_LOWER_MAC \
8126 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8127#define RSP_RX_COUNT_BY_UPPER_MAC \
8128 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8129#define RSP_COUNT_TO_NETDEV \
8130 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8131#define RSP_COUNT_OUT_OF_ORDER_DROP \
8132 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8133#define AP_LINK_ACTIVE \
8134 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8135#define AP_LINK_DAD \
8136 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8137#define STATS_GET_MAX \
8138 QCA_ATTR_NUD_STATS_GET_MAX
8139
8140const struct nla_policy
8141qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8142{
8143 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8144 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8145 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8146 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8147 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8148 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8149 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8150 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8151 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8152 [AP_LINK_DAD] = {.type = NLA_FLAG },
8153};
8154
8155static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8156{
8157
8158 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8159 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8160 struct hdd_nud_stats_context *context;
8161 int status;
8162
8163 ENTER();
8164
8165 if (NULL == adapter)
8166 return;
8167
8168 status = wlan_hdd_validate_context(hdd_ctx);
8169 if (0 != status) {
8170 return;
8171 }
8172
8173 if (!rsp) {
8174 hddLog(LOGE, FL("data is null"));
8175 return;
8176 }
8177
8178 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8179 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8180 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8181 adapter->dad |= rsp->dad;
8182
8183 spin_lock(&hdd_context_lock);
8184 context = &hdd_ctx->nud_stats_context;
8185 complete(&context->response_event);
8186 spin_unlock(&hdd_context_lock);
8187
8188 return;
8189}
8190static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8191 struct wireless_dev *wdev,
8192 const void *data, int data_len)
8193{
8194 int err = 0;
8195 unsigned long rc;
8196 struct hdd_nud_stats_context *context;
8197 struct net_device *dev = wdev->netdev;
8198 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8199 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8200 getArpStatsParams arp_stats_params;
8201 struct sk_buff *skb;
8202
8203 ENTER();
8204
8205 err = wlan_hdd_validate_context(hdd_ctx);
8206 if (0 != err)
8207 return err;
8208
8209 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8210 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8211 arp_stats_params.data_ctx = adapter;
8212
8213 spin_lock(&hdd_context_lock);
8214 context = &hdd_ctx->nud_stats_context;
8215 INIT_COMPLETION(context->response_event);
8216 spin_unlock(&hdd_context_lock);
8217
8218 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8220 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8221 return -EINVAL;
8222 }
8223
8224 if (eHAL_STATUS_SUCCESS !=
8225 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8227 "%s STATS_SET_START CMD Failed!!", __func__);
8228 return -EINVAL;
8229 }
8230
8231 rc = wait_for_completion_timeout(&context->response_event,
8232 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8233 if (!rc)
8234 {
8235 hddLog(LOGE,
8236 FL("Target response timed out request "));
8237 return -ETIMEDOUT;
8238 }
8239
8240 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8241 WLAN_NUD_STATS_LEN);
8242 if (!skb)
8243 {
8244 hddLog(VOS_TRACE_LEVEL_ERROR,
8245 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8246 __func__);
8247 return -ENOMEM;
8248 }
8249
8250 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8251 adapter->hdd_stats.hddArpStats.txCount) ||
8252 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8253 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8254 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8255 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8256 nla_put_u16(skb, COUNT_TX_SUCCESS,
8257 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8258 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8259 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8260 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8261 adapter->hdd_stats.hddArpStats.rxCount) ||
8262 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8263 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8264 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8265 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8266 hddLog(LOGE, FL("nla put fail"));
8267 kfree_skb(skb);
8268 return -EINVAL;
8269 }
8270 if (adapter->con_status)
8271 nla_put_flag(skb, AP_LINK_ACTIVE);
8272 if (adapter->dad)
8273 nla_put_flag(skb, AP_LINK_DAD);
8274
8275 cfg80211_vendor_cmd_reply(skb);
8276 return err;
8277}
8278
8279static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8280 struct wireless_dev *wdev,
8281 const void *data, int data_len)
8282{
8283 int ret;
8284
8285 vos_ssr_protect(__func__);
8286 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8287 vos_ssr_unprotect(__func__);
8288
8289 return ret;
8290}
8291
8292#undef QCA_ATTR_NUD_STATS_SET_INVALID
8293#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8294#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8295#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8296#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8297#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8298#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8299#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8300#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8301#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8302#undef QCA_ATTR_NUD_STATS_GET_MAX
8303
8304
8305
Kapil Guptaee33bf12016-12-20 18:27:37 +05308306#ifdef WLAN_FEATURE_APFIND
8307/**
8308 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8309 * @wiphy: pointer to wireless wiphy structure.
8310 * @wdev: pointer to wireless_dev structure.
8311 * @data: pointer to apfind configuration data.
8312 * @data_len: the length in byte of apfind data.
8313 *
8314 * This is called when wlan driver needs to send APFIND configurations to
8315 * firmware.
8316 *
8317 * Return: An error code or 0 on success.
8318 */
8319static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8320 struct wireless_dev *wdev,
8321 const void *data, int data_len)
8322{
8323 struct sme_ap_find_request_req apfind_req;
8324 VOS_STATUS status;
8325 int ret_val;
8326 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8327
8328 ENTER();
8329
8330 ret_val = wlan_hdd_validate_context(hdd_ctx);
8331 if (ret_val)
8332 return ret_val;
8333
8334 if (VOS_FTM_MODE == hdd_get_conparam()) {
8335 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8336 return -EPERM;
8337 }
8338
8339 apfind_req.request_data_len = data_len;
8340 apfind_req.request_data = data;
8341
8342 status = sme_apfind_set_cmd(&apfind_req);
8343 if (VOS_STATUS_SUCCESS != status) {
8344 ret_val = -EIO;
8345 }
8346 return ret_val;
8347}
8348
8349/**
8350 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8351 * @wiphy: pointer to wireless wiphy structure.
8352 * @wdev: pointer to wireless_dev structure.
8353 * @data: pointer to apfind configuration data.
8354 * @data_len: the length in byte of apfind data.
8355 *
8356 * This is called when wlan driver needs to send APFIND configurations to
8357 * firmware.
8358 *
8359 * Return: An error code or 0 on success.
8360 */
8361static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8362 struct wireless_dev *wdev,
8363 const void *data, int data_len)
8364{
8365 int ret;
8366
8367 vos_ssr_protect(__func__);
8368 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8369 vos_ssr_unprotect(__func__);
8370
8371 return ret;
8372}
8373#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308374const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8375{
Mukul Sharma2a271632014-10-13 14:59:01 +05308376 {
8377 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8378 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8379 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8380 WIPHY_VENDOR_CMD_NEED_NETDEV |
8381 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308382 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308383 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308384
8385 {
8386 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8387 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8388 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8389 WIPHY_VENDOR_CMD_NEED_NETDEV |
8390 WIPHY_VENDOR_CMD_NEED_RUNNING,
8391 .doit = wlan_hdd_cfg80211_nan_request
8392 },
8393
Sunil Duttc69bccb2014-05-26 21:30:20 +05308394#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8395 {
8396 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8397 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8398 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8399 WIPHY_VENDOR_CMD_NEED_NETDEV |
8400 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308401 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308402 },
8403
8404 {
8405 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8406 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8407 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8408 WIPHY_VENDOR_CMD_NEED_NETDEV |
8409 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308410 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308411 },
8412
8413 {
8414 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8415 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8416 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8417 WIPHY_VENDOR_CMD_NEED_NETDEV |
8418 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308419 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308420 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308421#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308422#ifdef WLAN_FEATURE_EXTSCAN
8423 {
8424 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8425 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8426 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8427 WIPHY_VENDOR_CMD_NEED_NETDEV |
8428 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308429 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308430 },
8431 {
8432 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8433 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8434 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8435 WIPHY_VENDOR_CMD_NEED_NETDEV |
8436 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308437 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308438 },
8439 {
8440 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8441 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8442 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8443 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308444 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308445 },
8446 {
8447 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8448 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8449 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8450 WIPHY_VENDOR_CMD_NEED_NETDEV |
8451 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308452 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308453 },
8454 {
8455 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8456 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8457 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8458 WIPHY_VENDOR_CMD_NEED_NETDEV |
8459 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308460 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308461 },
8462 {
8463 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8464 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8465 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8466 WIPHY_VENDOR_CMD_NEED_NETDEV |
8467 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308468 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308469 },
8470 {
8471 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8472 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8473 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8474 WIPHY_VENDOR_CMD_NEED_NETDEV |
8475 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308476 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308477 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308478#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308479/*EXT TDLS*/
8480 {
8481 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8482 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8483 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8484 WIPHY_VENDOR_CMD_NEED_NETDEV |
8485 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308486 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308487 },
8488 {
8489 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8490 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8491 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8492 WIPHY_VENDOR_CMD_NEED_NETDEV |
8493 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308494 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308495 },
8496 {
8497 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8498 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8499 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8500 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308501 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308502 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308503 {
8504 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8505 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8506 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8507 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308508 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308509 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308510 {
8511 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8512 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8513 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8514 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308515 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308516 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308517 {
8518 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8519 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8520 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8521 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308522 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308523 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308524 {
8525 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8526 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8527 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8528 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308529 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308530 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308531 {
8532 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308533 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8534 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8535 WIPHY_VENDOR_CMD_NEED_NETDEV |
8536 WIPHY_VENDOR_CMD_NEED_RUNNING,
8537 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8538 },
8539 {
8540 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308541 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8542 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8543 WIPHY_VENDOR_CMD_NEED_NETDEV |
8544 WIPHY_VENDOR_CMD_NEED_RUNNING,
8545 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308546 },
8547 {
8548 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8549 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8550 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8551 WIPHY_VENDOR_CMD_NEED_NETDEV,
8552 .doit = wlan_hdd_cfg80211_wifi_logger_start
8553 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308554 {
8555 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8556 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8557 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8558 WIPHY_VENDOR_CMD_NEED_NETDEV|
8559 WIPHY_VENDOR_CMD_NEED_RUNNING,
8560 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308561 },
8562 {
8563 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8564 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8565 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8566 WIPHY_VENDOR_CMD_NEED_NETDEV |
8567 WIPHY_VENDOR_CMD_NEED_RUNNING,
8568 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308569 },
8570 {
8571 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8572 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8573 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8574 WIPHY_VENDOR_CMD_NEED_NETDEV |
8575 WIPHY_VENDOR_CMD_NEED_RUNNING,
8576 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308577 },
8578#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8579 {
8580 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8581 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8582 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8583 WIPHY_VENDOR_CMD_NEED_NETDEV |
8584 WIPHY_VENDOR_CMD_NEED_RUNNING,
8585 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308586 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308587#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308588 {
8589 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8590 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8591 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8592 WIPHY_VENDOR_CMD_NEED_NETDEV |
8593 WIPHY_VENDOR_CMD_NEED_RUNNING,
8594 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308595 },
8596 {
8597 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8598 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8599 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8600 WIPHY_VENDOR_CMD_NEED_NETDEV |
8601 WIPHY_VENDOR_CMD_NEED_RUNNING,
8602 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308603 },
8604#ifdef WLAN_FEATURE_APFIND
8605 {
8606 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8607 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8608 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8609 WIPHY_VENDOR_CMD_NEED_NETDEV,
8610 .doit = wlan_hdd_cfg80211_apfind_cmd
8611 },
8612#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308613 {
8614 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8615 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8616 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8617 WIPHY_VENDOR_CMD_NEED_NETDEV |
8618 WIPHY_VENDOR_CMD_NEED_RUNNING,
8619 .doit = wlan_hdd_cfg80211_set_nud_stats
8620 },
8621 {
8622 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8623 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8624 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8625 WIPHY_VENDOR_CMD_NEED_NETDEV |
8626 WIPHY_VENDOR_CMD_NEED_RUNNING,
8627 .doit = wlan_hdd_cfg80211_get_nud_stats
8628 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308629 {
8630 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8631 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8632 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8633 WIPHY_VENDOR_CMD_NEED_NETDEV |
8634 WIPHY_VENDOR_CMD_NEED_RUNNING,
8635 .doit = hdd_cfg80211_get_station_cmd
8636 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308637};
8638
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008639/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308640static const
8641struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008642{
8643#ifdef FEATURE_WLAN_CH_AVOID
8644 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308645 .vendor_id = QCA_NL80211_VENDOR_ID,
8646 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008647 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308648#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8649#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8650 {
8651 /* Index = 1*/
8652 .vendor_id = QCA_NL80211_VENDOR_ID,
8653 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8654 },
8655 {
8656 /* Index = 2*/
8657 .vendor_id = QCA_NL80211_VENDOR_ID,
8658 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8659 },
8660 {
8661 /* Index = 3*/
8662 .vendor_id = QCA_NL80211_VENDOR_ID,
8663 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8664 },
8665 {
8666 /* Index = 4*/
8667 .vendor_id = QCA_NL80211_VENDOR_ID,
8668 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8669 },
8670 {
8671 /* Index = 5*/
8672 .vendor_id = QCA_NL80211_VENDOR_ID,
8673 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8674 },
8675 {
8676 /* Index = 6*/
8677 .vendor_id = QCA_NL80211_VENDOR_ID,
8678 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8679 },
8680#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308681#ifdef WLAN_FEATURE_EXTSCAN
8682 {
8683 .vendor_id = QCA_NL80211_VENDOR_ID,
8684 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8685 },
8686 {
8687 .vendor_id = QCA_NL80211_VENDOR_ID,
8688 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8689 },
8690 {
8691 .vendor_id = QCA_NL80211_VENDOR_ID,
8692 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8693 },
8694 {
8695 .vendor_id = QCA_NL80211_VENDOR_ID,
8696 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8697 },
8698 {
8699 .vendor_id = QCA_NL80211_VENDOR_ID,
8700 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8701 },
8702 {
8703 .vendor_id = QCA_NL80211_VENDOR_ID,
8704 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8705 },
8706 {
8707 .vendor_id = QCA_NL80211_VENDOR_ID,
8708 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8709 },
8710 {
8711 .vendor_id = QCA_NL80211_VENDOR_ID,
8712 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8713 },
8714 {
8715 .vendor_id = QCA_NL80211_VENDOR_ID,
8716 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8717 },
8718 {
8719 .vendor_id = QCA_NL80211_VENDOR_ID,
8720 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8721 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308722#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308723/*EXT TDLS*/
8724 {
8725 .vendor_id = QCA_NL80211_VENDOR_ID,
8726 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8727 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308728 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8729 .vendor_id = QCA_NL80211_VENDOR_ID,
8730 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8731 },
8732
Srinivas Dasari030bad32015-02-18 23:23:54 +05308733
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308734 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308735 .vendor_id = QCA_NL80211_VENDOR_ID,
8736 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8737 },
8738
Sushant Kaushik084f6592015-09-10 13:11:56 +05308739 {
8740 .vendor_id = QCA_NL80211_VENDOR_ID,
8741 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308742 },
8743 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8744 .vendor_id = QCA_NL80211_VENDOR_ID,
8745 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8746 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308747 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8748 .vendor_id = QCA_NL80211_VENDOR_ID,
8749 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8750 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308751 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8752 .vendor_id = QCA_NL80211_VENDOR_ID,
8753 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8754 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008755};
8756
Jeff Johnson295189b2012-06-20 16:38:30 -07008757/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308758 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308759 * This function is called by hdd_wlan_startup()
8760 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308761 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008762 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308763struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008764{
8765 struct wiphy *wiphy;
8766 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308767 /*
8768 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008769 */
8770 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8771
8772 if (!wiphy)
8773 {
8774 /* Print error and jump into err label and free the memory */
8775 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8776 return NULL;
8777 }
8778
Sunil Duttc69bccb2014-05-26 21:30:20 +05308779
Jeff Johnson295189b2012-06-20 16:38:30 -07008780 return wiphy;
8781}
8782
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308783#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8784 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8785/**
8786 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8787 * @wiphy: pointer to wiphy
8788 * @config: pointer to config
8789 *
8790 * Return: None
8791 */
8792static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8793 hdd_config_t *config)
8794{
8795 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
8796 if (config->max_sched_scan_plan_interval)
8797 wiphy->max_sched_scan_plan_interval =
8798 config->max_sched_scan_plan_interval;
8799 if (config->max_sched_scan_plan_iterations)
8800 wiphy->max_sched_scan_plan_iterations =
8801 config->max_sched_scan_plan_iterations;
8802}
8803#else
8804static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8805 hdd_config_t *config)
8806{
8807}
8808#endif
8809
Jeff Johnson295189b2012-06-20 16:38:30 -07008810/*
8811 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308812 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07008813 * private ioctl to change the band value
8814 */
8815int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
8816{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308817 int i, j;
8818 eNVChannelEnabledType channelEnabledState;
8819
Jeff Johnsone7245742012-09-05 17:12:55 -07008820 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308821
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308822 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008823 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308824
8825 if (NULL == wiphy->bands[i])
8826 {
8827 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
8828 __func__, i);
8829 continue;
8830 }
8831
8832 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8833 {
8834 struct ieee80211_supported_band *band = wiphy->bands[i];
8835
8836 channelEnabledState = vos_nv_getChannelEnabledState(
8837 band->channels[j].hw_value);
8838
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308839 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308840 {
Abhishek Singh678227a2014-11-04 10:52:38 +05308841 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308842 continue;
8843 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308844 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308845 {
8846 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8847 continue;
8848 }
8849
8850 if (NV_CHANNEL_DISABLE == channelEnabledState ||
8851 NV_CHANNEL_INVALID == channelEnabledState)
8852 {
8853 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8854 }
8855 else if (NV_CHANNEL_DFS == channelEnabledState)
8856 {
8857 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8858 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
8859 }
8860 else
8861 {
8862 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
8863 |IEEE80211_CHAN_RADAR);
8864 }
8865 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008866 }
8867 return 0;
8868}
8869/*
8870 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308871 * This function is called by hdd_wlan_startup()
8872 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07008873 * This function is used to initialize and register wiphy structure.
8874 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308875int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008876 struct wiphy *wiphy,
8877 hdd_config_t *pCfg
8878 )
8879{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308880 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308881 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8882
Jeff Johnsone7245742012-09-05 17:12:55 -07008883 ENTER();
8884
Jeff Johnson295189b2012-06-20 16:38:30 -07008885 /* Now bind the underlying wlan device with wiphy */
8886 set_wiphy_dev(wiphy, dev);
8887
8888 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008889
Kiet Lam6c583332013-10-14 05:37:09 +05308890#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008891 /* the flag for the other case would be initialzed in
8892 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05308893#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8894 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
8895#else
Amar Singhal0a402232013-10-11 20:57:16 -07008896 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05308897#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05308898#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008899
Amar Singhalfddc28c2013-09-05 13:03:40 -07008900 /* This will disable updating of NL channels from passive to
8901 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308902#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8903 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
8904#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07008905 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308906#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07008907
Amar Singhala49cbc52013-10-08 18:37:44 -07008908
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008909#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008910 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
8911 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
8912 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07008913 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308914#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05308915 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308916#else
8917 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
8918#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008919#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008920
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008921#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008922 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08008923#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008924 || pCfg->isFastRoamIniFeatureEnabled
8925#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008926#ifdef FEATURE_WLAN_ESE
8927 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008928#endif
8929 )
8930 {
8931 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
8932 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08008933#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008934#ifdef FEATURE_WLAN_TDLS
8935 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
8936 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
8937#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308938#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05308939 if (pCfg->configPNOScanSupport)
8940 {
8941 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
8942 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
8943 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
8944 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
8945 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308946#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008947
Abhishek Singh10d85972015-04-17 10:27:23 +05308948#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8949 wiphy->features |= NL80211_FEATURE_HT_IBSS;
8950#endif
8951
Amar Singhalfddc28c2013-09-05 13:03:40 -07008952#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008953 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
8954 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07008955 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008956 driver need to determine what to do with both
8957 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07008958
8959 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07008960#else
8961 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008962#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008963
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308964 wiphy->max_scan_ssids = MAX_SCAN_SSID;
8965
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05308966 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07008967
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308968 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
8969
Jeff Johnson295189b2012-06-20 16:38:30 -07008970 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05308971 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
8972 | BIT(NL80211_IFTYPE_ADHOC)
8973 | BIT(NL80211_IFTYPE_P2P_CLIENT)
8974 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308975 | BIT(NL80211_IFTYPE_AP)
8976 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07008977
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308978 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008979 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308980#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8981 if( pCfg->enableMCC )
8982 {
8983 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308984 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008985
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308986 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308987 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008988
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308989 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308990 wiphy->iface_combinations = wlan_hdd_iface_combination;
8991 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008992#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308993 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008994
Jeff Johnson295189b2012-06-20 16:38:30 -07008995 /* Before registering we need to update the ht capabilitied based
8996 * on ini values*/
8997 if( !pCfg->ShortGI20MhzEnable )
8998 {
8999 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
9000 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07009001 }
9002
9003 if( !pCfg->ShortGI40MhzEnable )
9004 {
9005 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9006 }
9007
9008 if( !pCfg->nChannelBondingMode5GHz )
9009 {
9010 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9011 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309012 /*
9013 * In case of static linked driver at the time of driver unload,
9014 * module exit doesn't happens. Module cleanup helps in cleaning
9015 * of static memory.
9016 * If driver load happens statically, at the time of driver unload,
9017 * wiphy flags don't get reset because of static memory.
9018 * It's better not to store channel in static memory.
9019 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309020 wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9021 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309022 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309023 if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309024 {
9025 hddLog(VOS_TRACE_LEVEL_ERROR,
9026 FL("Not enough memory to allocate channels"));
9027 return -ENOMEM;
9028 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309029 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309030 &hdd_channels_2_4_GHZ[0],
9031 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009032
Agrawal Ashish97dec502015-11-26 20:20:58 +05309033 if (true == hdd_is_5g_supported(pHddCtx))
9034 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309035 wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9036 wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309037 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309038 if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309039 {
9040 hddLog(VOS_TRACE_LEVEL_ERROR,
9041 FL("Not enough memory to allocate channels"));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309042 vos_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
9043 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
Agrawal Ashish97dec502015-11-26 20:20:58 +05309044 return -ENOMEM;
9045 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309046 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309047 &hdd_channels_5_GHZ[0],
9048 sizeof(hdd_channels_5_GHZ));
9049 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309050
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309051 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309052 {
9053
9054 if (NULL == wiphy->bands[i])
9055 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309056 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309057 __func__, i);
9058 continue;
9059 }
9060
9061 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9062 {
9063 struct ieee80211_supported_band *band = wiphy->bands[i];
9064
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309065 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309066 {
9067 // Enable social channels for P2P
9068 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9069 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9070 else
9071 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9072 continue;
9073 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309074 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309075 {
9076 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9077 continue;
9078 }
9079 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009080 }
9081 /*Initialise the supported cipher suite details*/
9082 wiphy->cipher_suites = hdd_cipher_suites;
9083 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9084
9085 /*signal strength in mBm (100*dBm) */
9086 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9087
9088#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309089 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009090#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009091
Sunil Duttc69bccb2014-05-26 21:30:20 +05309092 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9093 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009094 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9095 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9096
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309097 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
9098
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309099 EXIT();
9100 return 0;
9101}
9102
9103/* In this function we are registering wiphy. */
9104int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9105{
9106 ENTER();
9107 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009108 if (0 > wiphy_register(wiphy))
9109 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309110 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009111 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9112 return -EIO;
9113 }
9114
9115 EXIT();
9116 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309117}
Jeff Johnson295189b2012-06-20 16:38:30 -07009118
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309119/* In this function we are updating channel list when,
9120 regulatory domain is FCC and country code is US.
9121 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9122 As per FCC smart phone is not a indoor device.
9123 GO should not opeate on indoor channels */
9124void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9125{
9126 int j;
9127 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9128 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9129 //Default counrtycode from NV at the time of wiphy initialization.
9130 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9131 &defaultCountryCode[0]))
9132 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009133 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309134 }
9135 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9136 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309137 if (NULL == wiphy->bands[HDD_NL80211_BAND_5GHZ])
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309138 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309139 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[HDD_NL80211_BAND_5GHZ] is NULL",__func__ );
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309140 return;
9141 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309142 for (j = 0; j < wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels; j++)
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309143 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309144 struct ieee80211_supported_band *band = wiphy->bands[HDD_NL80211_BAND_5GHZ];
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309145 // Mark UNII -1 band channel as passive
9146 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9147 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9148 }
9149 }
9150}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309151/* This function registers for all frame which supplicant is interested in */
9152void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009153{
Jeff Johnson295189b2012-06-20 16:38:30 -07009154 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9155 /* Register for all P2P action, public action etc frames */
9156 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009157 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309158 /* Register frame indication call back */
9159 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009160 /* Right now we are registering these frame when driver is getting
9161 initialized. Once we will move to 2.6.37 kernel, in which we have
9162 frame register ops, we will move this code as a part of that */
9163 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309164 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009165 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9166
9167 /* GAS Initial Response */
9168 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9169 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309170
Jeff Johnson295189b2012-06-20 16:38:30 -07009171 /* GAS Comeback Request */
9172 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9173 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9174
9175 /* GAS Comeback Response */
9176 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9177 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9178
9179 /* P2P Public Action */
9180 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309181 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009182 P2P_PUBLIC_ACTION_FRAME_SIZE );
9183
9184 /* P2P Action */
9185 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9186 (v_U8_t*)P2P_ACTION_FRAME,
9187 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009188
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309189 /* WNM BSS Transition Request frame */
9190 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9191 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9192 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009193
9194 /* WNM-Notification */
9195 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9196 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9197 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009198}
9199
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309200void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009201{
Jeff Johnson295189b2012-06-20 16:38:30 -07009202 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9203 /* Register for all P2P action, public action etc frames */
9204 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9205
Jeff Johnsone7245742012-09-05 17:12:55 -07009206 ENTER();
9207
Jeff Johnson295189b2012-06-20 16:38:30 -07009208 /* Right now we are registering these frame when driver is getting
9209 initialized. Once we will move to 2.6.37 kernel, in which we have
9210 frame register ops, we will move this code as a part of that */
9211 /* GAS Initial Request */
9212
9213 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9214 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9215
9216 /* GAS Initial Response */
9217 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9218 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309219
Jeff Johnson295189b2012-06-20 16:38:30 -07009220 /* GAS Comeback Request */
9221 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9222 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9223
9224 /* GAS Comeback Response */
9225 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9226 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9227
9228 /* P2P Public Action */
9229 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309230 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009231 P2P_PUBLIC_ACTION_FRAME_SIZE );
9232
9233 /* P2P Action */
9234 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9235 (v_U8_t*)P2P_ACTION_FRAME,
9236 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009237 /* WNM-Notification */
9238 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9239 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9240 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009241}
9242
9243#ifdef FEATURE_WLAN_WAPI
9244void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309245 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009246{
9247 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9248 tCsrRoamSetKey setKey;
9249 v_BOOL_t isConnected = TRUE;
9250 int status = 0;
9251 v_U32_t roamId= 0xFF;
9252 tANI_U8 *pKeyPtr = NULL;
9253 int n = 0;
9254
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309255 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9256 __func__, hdd_device_modetoString(pAdapter->device_mode),
9257 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009258
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309259 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009260 setKey.keyId = key_index; // Store Key ID
9261 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9262 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9263 setKey.paeRole = 0 ; // the PAE role
9264 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9265 {
9266 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9267 }
9268 else
9269 {
9270 isConnected = hdd_connIsConnected(pHddStaCtx);
9271 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9272 }
9273 setKey.keyLength = key_Len;
9274 pKeyPtr = setKey.Key;
9275 memcpy( pKeyPtr, key, key_Len);
9276
Arif Hussain6d2a3322013-11-17 19:50:10 -08009277 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009278 __func__, key_Len);
9279 for (n = 0 ; n < key_Len; n++)
9280 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9281 __func__,n,setKey.Key[n]);
9282
9283 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9284 if ( isConnected )
9285 {
9286 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9287 pAdapter->sessionId, &setKey, &roamId );
9288 }
9289 if ( status != 0 )
9290 {
9291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9292 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9293 __LINE__, status );
9294 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9295 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309296 /* Need to clear any trace of key value in the memory.
9297 * Thus zero out the memory even though it is local
9298 * variable.
9299 */
9300 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009301}
9302#endif /* FEATURE_WLAN_WAPI*/
9303
9304#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309305int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009306 beacon_data_t **ppBeacon,
9307 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009308#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309309int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009310 beacon_data_t **ppBeacon,
9311 struct cfg80211_beacon_data *params,
9312 int dtim_period)
9313#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309314{
Jeff Johnson295189b2012-06-20 16:38:30 -07009315 int size;
9316 beacon_data_t *beacon = NULL;
9317 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309318 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9319 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009320
Jeff Johnsone7245742012-09-05 17:12:55 -07009321 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009322 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309323 {
9324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9325 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009326 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309327 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009328
9329 old = pAdapter->sessionCtx.ap.beacon;
9330
9331 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309332 {
9333 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9334 FL("session(%d) old and new heads points to NULL"),
9335 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009336 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309337 }
9338
9339 if (params->tail && !params->tail_len)
9340 {
9341 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9342 FL("tail_len is zero but tail is not NULL"));
9343 return -EINVAL;
9344 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009345
Jeff Johnson295189b2012-06-20 16:38:30 -07009346#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9347 /* Kernel 3.0 is not updating dtim_period for set beacon */
9348 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309349 {
9350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9351 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009352 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309353 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009354#endif
9355
Kapil Gupta137ef892016-12-13 19:38:00 +05309356 if (params->head)
9357 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009358 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309359 head = params->head;
9360 } else
9361 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009362 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309363 head = old->head;
9364 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009365
Kapil Gupta137ef892016-12-13 19:38:00 +05309366 if (params->tail || !old)
9367 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009368 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309369 tail = params->tail;
9370 } else
9371 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009372 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309373 tail = old->tail;
9374 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009375
Kapil Gupta137ef892016-12-13 19:38:00 +05309376 if (params->proberesp_ies || !old)
9377 {
9378 proberesp_ies_len = params->proberesp_ies_len;
9379 proberesp_ies = params->proberesp_ies;
9380 } else
9381 {
9382 proberesp_ies_len = old->proberesp_ies_len;
9383 proberesp_ies = old->proberesp_ies;
9384 }
9385
9386 if (params->assocresp_ies || !old)
9387 {
9388 assocresp_ies_len = params->assocresp_ies_len;
9389 assocresp_ies = params->assocresp_ies;
9390 } else
9391 {
9392 assocresp_ies_len = old->assocresp_ies_len;
9393 assocresp_ies = old->assocresp_ies;
9394 }
9395
9396 size = sizeof(beacon_data_t) + head_len + tail_len +
9397 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009398
9399 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009400 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309401 {
9402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9403 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009404 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309405 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009406
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009407#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309408 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009409 beacon->dtim_period = params->dtim_period;
9410 else
9411 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009412#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309413 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009414 beacon->dtim_period = dtim_period;
9415 else
9416 beacon->dtim_period = old->dtim_period;
9417#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309418
Jeff Johnson295189b2012-06-20 16:38:30 -07009419 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9420 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309421 beacon->proberesp_ies = beacon->tail + tail_len;
9422 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9423
Jeff Johnson295189b2012-06-20 16:38:30 -07009424 beacon->head_len = head_len;
9425 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309426 beacon->proberesp_ies_len = proberesp_ies_len;
9427 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009428
c_manjee527ecac2017-01-25 12:25:27 +05309429 if (head && head_len)
9430 memcpy(beacon->head, head, head_len);
9431 if (tail && tail_len)
9432 memcpy(beacon->tail, tail, tail_len);
9433 if (proberesp_ies && proberesp_ies_len)
9434 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9435 if (assocresp_ies && assocresp_ies_len)
9436 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009437
9438 *ppBeacon = beacon;
9439
9440 kfree(old);
9441
9442 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009443}
Jeff Johnson295189b2012-06-20 16:38:30 -07009444
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309445v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9446#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9447 const v_U8_t *pIes,
9448#else
9449 v_U8_t *pIes,
9450#endif
9451 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009452{
9453 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309454 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009455 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309456
Jeff Johnson295189b2012-06-20 16:38:30 -07009457 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309458 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009459 elem_id = ptr[0];
9460 elem_len = ptr[1];
9461 left -= 2;
9462 if(elem_len > left)
9463 {
9464 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009465 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009466 eid,elem_len,left);
9467 return NULL;
9468 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309469 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009470 {
9471 return ptr;
9472 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309473
Jeff Johnson295189b2012-06-20 16:38:30 -07009474 left -= elem_len;
9475 ptr += (elem_len + 2);
9476 }
9477 return NULL;
9478}
9479
Jeff Johnson295189b2012-06-20 16:38:30 -07009480/* Check if rate is 11g rate or not */
9481static int wlan_hdd_rate_is_11g(u8 rate)
9482{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009483 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009484 u8 i;
9485 for (i = 0; i < 8; i++)
9486 {
9487 if(rate == gRateArray[i])
9488 return TRUE;
9489 }
9490 return FALSE;
9491}
9492
9493/* Check for 11g rate and set proper 11g only mode */
9494static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9495 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9496{
9497 u8 i, num_rates = pIe[0];
9498
9499 pIe += 1;
9500 for ( i = 0; i < num_rates; i++)
9501 {
9502 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9503 {
9504 /* If rate set have 11g rate than change the mode to 11G */
9505 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9506 if (pIe[i] & BASIC_RATE_MASK)
9507 {
9508 /* If we have 11g rate as basic rate, it means mode
9509 is 11g only mode.
9510 */
9511 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9512 *pCheckRatesfor11g = FALSE;
9513 }
9514 }
9515 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9516 {
9517 *require_ht = TRUE;
9518 }
9519 }
9520 return;
9521}
9522
9523static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9524{
9525 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9526 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9527 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9528 u8 checkRatesfor11g = TRUE;
9529 u8 require_ht = FALSE;
9530 u8 *pIe=NULL;
9531
9532 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9533
9534 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9535 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9536 if (pIe != NULL)
9537 {
9538 pIe += 1;
9539 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9540 &pConfig->SapHw_mode);
9541 }
9542
9543 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9544 WLAN_EID_EXT_SUPP_RATES);
9545 if (pIe != NULL)
9546 {
9547
9548 pIe += 1;
9549 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9550 &pConfig->SapHw_mode);
9551 }
9552
9553 if( pConfig->channel > 14 )
9554 {
9555 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9556 }
9557
9558 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9559 WLAN_EID_HT_CAPABILITY);
9560
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309561 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009562 {
9563 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9564 if(require_ht)
9565 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9566 }
9567}
9568
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309569static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9570 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9571{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009572 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309573 v_U8_t *pIe = NULL;
9574 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9575
9576 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9577 pBeacon->tail, pBeacon->tail_len);
9578
9579 if (pIe)
9580 {
9581 ielen = pIe[1] + 2;
9582 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9583 {
9584 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9585 }
9586 else
9587 {
9588 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9589 return -EINVAL;
9590 }
9591 *total_ielen += ielen;
9592 }
9593 return 0;
9594}
9595
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009596static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9597 v_U8_t *genie, v_U8_t *total_ielen)
9598{
9599 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9600 int left = pBeacon->tail_len;
9601 v_U8_t *ptr = pBeacon->tail;
9602 v_U8_t elem_id, elem_len;
9603 v_U16_t ielen = 0;
9604
9605 if ( NULL == ptr || 0 == left )
9606 return;
9607
9608 while (left >= 2)
9609 {
9610 elem_id = ptr[0];
9611 elem_len = ptr[1];
9612 left -= 2;
9613 if (elem_len > left)
9614 {
9615 hddLog( VOS_TRACE_LEVEL_ERROR,
9616 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9617 elem_id, elem_len, left);
9618 return;
9619 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309620 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009621 {
9622 /* skipping the VSIE's which we don't want to include or
9623 * it will be included by existing code
9624 */
9625 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9626#ifdef WLAN_FEATURE_WFD
9627 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9628#endif
9629 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9630 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9631 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9632 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9633 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9634 {
9635 ielen = ptr[1] + 2;
9636 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9637 {
9638 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9639 *total_ielen += ielen;
9640 }
9641 else
9642 {
9643 hddLog( VOS_TRACE_LEVEL_ERROR,
9644 "IE Length is too big "
9645 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9646 elem_id, elem_len, *total_ielen);
9647 }
9648 }
9649 }
9650
9651 left -= elem_len;
9652 ptr += (elem_len + 2);
9653 }
9654 return;
9655}
9656
Kapil Gupta137ef892016-12-13 19:38:00 +05309657int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009658{
9659 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309660 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009661 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009662 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309663 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009664
9665 genie = vos_mem_malloc(MAX_GENIE_LEN);
9666
9667 if(genie == NULL) {
9668
9669 return -ENOMEM;
9670 }
9671
Kapil Gupta137ef892016-12-13 19:38:00 +05309672 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309673 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9674 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009675 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309676 hddLog(LOGE,
9677 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309678 ret = -EINVAL;
9679 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009680 }
9681
9682#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309683 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9684 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9685 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309686 hddLog(LOGE,
9687 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309688 ret = -EINVAL;
9689 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009690 }
9691#endif
9692
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309693 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9694 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009695 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309696 hddLog(LOGE,
9697 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309698 ret = -EINVAL;
9699 goto done;
9700 }
9701
9702 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9703 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009704 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009705 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009706
9707 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9708 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9709 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9710 {
9711 hddLog(LOGE,
9712 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009713 ret = -EINVAL;
9714 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009715 }
9716
9717 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9718 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9719 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9720 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9721 ==eHAL_STATUS_FAILURE)
9722 {
9723 hddLog(LOGE,
9724 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009725 ret = -EINVAL;
9726 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009727 }
9728
9729 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309730 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009731 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309732 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009733 u8 probe_rsp_ie_len[3] = {0};
9734 u8 counter = 0;
9735 /* Check Probe Resp Length if it is greater then 255 then Store
9736 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9737 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9738 Store More then 255 bytes into One Variable.
9739 */
9740 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9741 {
9742 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9743 {
9744 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9745 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9746 }
9747 else
9748 {
9749 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9750 rem_probe_resp_ie_len = 0;
9751 }
9752 }
9753
9754 rem_probe_resp_ie_len = 0;
9755
9756 if (probe_rsp_ie_len[0] > 0)
9757 {
9758 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9759 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05309760 (tANI_U8*)&pBeacon->
9761 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009762 probe_rsp_ie_len[0], NULL,
9763 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9764 {
9765 hddLog(LOGE,
9766 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009767 ret = -EINVAL;
9768 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009769 }
9770 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9771 }
9772
9773 if (probe_rsp_ie_len[1] > 0)
9774 {
9775 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9776 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +05309777 (tANI_U8*)&pBeacon->
9778 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009779 probe_rsp_ie_len[1], NULL,
9780 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9781 {
9782 hddLog(LOGE,
9783 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009784 ret = -EINVAL;
9785 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009786 }
9787 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9788 }
9789
9790 if (probe_rsp_ie_len[2] > 0)
9791 {
9792 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9793 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +05309794 (tANI_U8*)&pBeacon->
9795 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009796 probe_rsp_ie_len[2], NULL,
9797 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9798 {
9799 hddLog(LOGE,
9800 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009801 ret = -EINVAL;
9802 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009803 }
9804 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9805 }
9806
9807 if (probe_rsp_ie_len[1] == 0 )
9808 {
9809 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9810 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9811 eANI_BOOLEAN_FALSE) )
9812 {
9813 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009814 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009815 }
9816 }
9817
9818 if (probe_rsp_ie_len[2] == 0 )
9819 {
9820 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9821 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9822 eANI_BOOLEAN_FALSE) )
9823 {
9824 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009825 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009826 }
9827 }
9828
9829 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9830 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9831 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9832 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9833 == eHAL_STATUS_FAILURE)
9834 {
9835 hddLog(LOGE,
9836 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009837 ret = -EINVAL;
9838 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009839 }
9840 }
9841 else
9842 {
9843 // Reset WNI_CFG_PROBE_RSP Flags
9844 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
9845
9846 hddLog(VOS_TRACE_LEVEL_INFO,
9847 "%s: No Probe Response IE received in set beacon",
9848 __func__);
9849 }
9850
9851 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309852 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009853 {
9854 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05309855 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
9856 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07009857 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9858 {
9859 hddLog(LOGE,
9860 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009861 ret = -EINVAL;
9862 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009863 }
9864
9865 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9866 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
9867 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9868 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9869 == eHAL_STATUS_FAILURE)
9870 {
9871 hddLog(LOGE,
9872 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009873 ret = -EINVAL;
9874 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009875 }
9876 }
9877 else
9878 {
9879 hddLog(VOS_TRACE_LEVEL_INFO,
9880 "%s: No Assoc Response IE received in set beacon",
9881 __func__);
9882
9883 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9884 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9885 eANI_BOOLEAN_FALSE) )
9886 {
9887 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009888 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009889 }
9890 }
9891
Jeff Johnsone7245742012-09-05 17:12:55 -07009892done:
Jeff Johnson295189b2012-06-20 16:38:30 -07009893 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309894 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009895}
Jeff Johnson295189b2012-06-20 16:38:30 -07009896
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309897/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009898 * FUNCTION: wlan_hdd_validate_operation_channel
9899 * called by wlan_hdd_cfg80211_start_bss() and
9900 * wlan_hdd_cfg80211_set_channel()
9901 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309902 * channel list.
9903 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07009904VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009905{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309906
Jeff Johnson295189b2012-06-20 16:38:30 -07009907 v_U32_t num_ch = 0;
9908 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
9909 u32 indx = 0;
9910 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309911 v_U8_t fValidChannel = FALSE, count = 0;
9912 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309913
Jeff Johnson295189b2012-06-20 16:38:30 -07009914 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9915
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309916 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009917 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309918 /* Validate the channel */
9919 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009920 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309921 if ( channel == rfChannels[count].channelNum )
9922 {
9923 fValidChannel = TRUE;
9924 break;
9925 }
9926 }
9927 if (fValidChannel != TRUE)
9928 {
9929 hddLog(VOS_TRACE_LEVEL_ERROR,
9930 "%s: Invalid Channel [%d]", __func__, channel);
9931 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009932 }
9933 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309934 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009935 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309936 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
9937 valid_ch, &num_ch))
9938 {
9939 hddLog(VOS_TRACE_LEVEL_ERROR,
9940 "%s: failed to get valid channel list", __func__);
9941 return VOS_STATUS_E_FAILURE;
9942 }
9943 for (indx = 0; indx < num_ch; indx++)
9944 {
9945 if (channel == valid_ch[indx])
9946 {
9947 break;
9948 }
9949 }
9950
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309951 if (indx >= num_ch)
9952 {
9953 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9954 {
9955 eCsrBand band;
9956 unsigned int freq;
9957
9958 sme_GetFreqBand(hHal, &band);
9959
9960 if (eCSR_BAND_5G == band)
9961 {
9962#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9963 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9964 {
9965 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309966 HDD_NL80211_BAND_2GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309967 }
9968 else
9969 {
9970 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309971 HDD_NL80211_BAND_5GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309972 }
9973#else
9974 freq = ieee80211_channel_to_frequency(channel);
9975#endif
9976 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
9977 return VOS_STATUS_SUCCESS;
9978 }
9979 }
9980
9981 hddLog(VOS_TRACE_LEVEL_ERROR,
9982 "%s: Invalid Channel [%d]", __func__, channel);
9983 return VOS_STATUS_E_FAILURE;
9984 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009985 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309986
Jeff Johnson295189b2012-06-20 16:38:30 -07009987 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309988
Jeff Johnson295189b2012-06-20 16:38:30 -07009989}
9990
Viral Modi3a32cc52013-02-08 11:14:52 -08009991/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309992 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009993 * This function is used to set the channel number
9994 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309995static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009996 struct ieee80211_channel *chan,
9997 enum nl80211_channel_type channel_type
9998 )
9999{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010000 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -080010001 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -070010002 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -080010003 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010004 hdd_context_t *pHddCtx;
10005 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010006
10007 ENTER();
10008
10009 if( NULL == dev )
10010 {
10011 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010012 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010013 return -ENODEV;
10014 }
10015 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010016
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010017 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10018 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10019 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010020 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010021 "%s: device_mode = %s (%d) freq = %d", __func__,
10022 hdd_device_modetoString(pAdapter->device_mode),
10023 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010024
10025 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10026 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010027 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010028 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010029 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010030 }
10031
10032 /*
10033 * Do freq to chan conversion
10034 * TODO: for 11a
10035 */
10036
10037 channel = ieee80211_frequency_to_channel(freq);
10038
10039 /* Check freq range */
10040 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10041 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10042 {
10043 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010044 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010045 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10046 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10047 return -EINVAL;
10048 }
10049
10050 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10051
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010052 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10053 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010054 {
10055 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10056 {
10057 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010058 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010059 return -EINVAL;
10060 }
10061 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10062 "%s: set channel to [%d] for device mode =%d",
10063 __func__, channel,pAdapter->device_mode);
10064 }
10065 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010066 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010067 )
10068 {
10069 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10070 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10071 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10072
10073 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10074 {
10075 /* Link is up then return cant set channel*/
10076 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010077 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010078 return -EINVAL;
10079 }
10080
10081 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10082 pHddStaCtx->conn_info.operationChannel = channel;
10083 pRoamProfile->ChannelInfo.ChannelList =
10084 &pHddStaCtx->conn_info.operationChannel;
10085 }
10086 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010087 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010088 )
10089 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010090 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10091 {
10092 if(VOS_STATUS_SUCCESS !=
10093 wlan_hdd_validate_operation_channel(pAdapter,channel))
10094 {
10095 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010096 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010097 return -EINVAL;
10098 }
10099 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10100 }
10101 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010102 {
10103 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10104
10105 /* If auto channel selection is configured as enable/ 1 then ignore
10106 channel set by supplicant
10107 */
10108 if ( cfg_param->apAutoChannelSelection )
10109 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010110 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10111 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010112 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010113 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10114 __func__, hdd_device_modetoString(pAdapter->device_mode),
10115 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010116 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010117 else
10118 {
10119 if(VOS_STATUS_SUCCESS !=
10120 wlan_hdd_validate_operation_channel(pAdapter,channel))
10121 {
10122 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010123 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010124 return -EINVAL;
10125 }
10126 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10127 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010128 }
10129 }
10130 else
10131 {
10132 hddLog(VOS_TRACE_LEVEL_FATAL,
10133 "%s: Invalid device mode failed to set valid channel", __func__);
10134 return -EINVAL;
10135 }
10136 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010137 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010138}
10139
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010140static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10141 struct net_device *dev,
10142 struct ieee80211_channel *chan,
10143 enum nl80211_channel_type channel_type
10144 )
10145{
10146 int ret;
10147
10148 vos_ssr_protect(__func__);
10149 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10150 vos_ssr_unprotect(__func__);
10151
10152 return ret;
10153}
10154
Anurag Chouhan83026002016-12-13 22:46:21 +053010155#ifdef DHCP_SERVER_OFFLOAD
10156void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10157 VOS_STATUS status)
10158{
10159 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10160
10161 ENTER();
10162
10163 if (NULL == adapter)
10164 {
10165 hddLog(VOS_TRACE_LEVEL_ERROR,
10166 "%s: adapter is NULL",__func__);
10167 return;
10168 }
10169
10170 adapter->dhcp_status.dhcp_offload_status = status;
10171 vos_event_set(&adapter->dhcp_status.vos_event);
10172 return;
10173}
10174
10175/**
10176 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10177 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010178 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010179 *
10180 * Return: None
10181 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010182VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10183 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010184{
10185 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10186 sir_dhcp_srv_offload_info dhcp_srv_info;
10187 tANI_U8 num_entries = 0;
10188 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10189 tANI_U8 num;
10190 tANI_U32 temp;
10191 VOS_STATUS ret;
10192
10193 ENTER();
10194
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010195 if (!re_init) {
10196 ret = wlan_hdd_validate_context(hdd_ctx);
10197 if (0 != ret)
10198 return VOS_STATUS_E_INVAL;
10199 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010200
10201 /* Prepare the request to send to SME */
10202 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10203 if (NULL == dhcp_srv_info) {
10204 hddLog(VOS_TRACE_LEVEL_ERROR,
10205 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10206 return VOS_STATUS_E_NOMEM;
10207 }
10208
10209 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10210
10211 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10212 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10213 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10214 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10215 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10216 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10217
10218 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10219 srv_ip,
10220 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010221 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010222 if (num_entries != IPADDR_NUM_ENTRIES) {
10223 hddLog(VOS_TRACE_LEVEL_ERROR,
10224 "%s: incorrect IP address (%s) assigned for DHCP server!",
10225 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10226 vos_mem_free(dhcp_srv_info);
10227 return VOS_STATUS_E_FAILURE;
10228 }
10229
10230 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10231 hddLog(VOS_TRACE_LEVEL_ERROR,
10232 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10233 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10234 vos_mem_free(dhcp_srv_info);
10235 return VOS_STATUS_E_FAILURE;
10236 }
10237
10238 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10239 hddLog(VOS_TRACE_LEVEL_ERROR,
10240 "%s: invalid IP address (%s)! The last field must be less than 100!",
10241 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10242 vos_mem_free(dhcp_srv_info);
10243 return VOS_STATUS_E_FAILURE;
10244 }
10245
10246 for (num = 0; num < num_entries; num++) {
10247 temp = srv_ip[num];
10248 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10249 }
10250
10251 if (eHAL_STATUS_SUCCESS !=
10252 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10253 hddLog(VOS_TRACE_LEVEL_ERROR,
10254 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10255 vos_mem_free(dhcp_srv_info);
10256 return VOS_STATUS_E_FAILURE;
10257 }
10258
10259 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10260 "%s: enable DHCP Server offload successfully!", __func__);
10261
10262 vos_mem_free(dhcp_srv_info);
10263 return 0;
10264}
10265#endif /* DHCP_SERVER_OFFLOAD */
10266
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010267/*
10268 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10269 * @wiphy_chan: wiphy channel number
10270 * @rfChannel: channel hw value
10271 * @disable: Disable/enable the flags
10272 *
10273 * Modify wiphy flags and cds state if channel is indoor.
10274 *
10275 * Return: void
10276 */
10277void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
10278 v_U32_t rfChannel, bool disable)
10279{
10280 v_U32_t channelLoop;
10281 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10282
10283 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10284
10285 if (rfChannels[channelLoop].channelNum == rfChannel) {
10286 channelEnum = (eRfChannels)channelLoop;
10287 break;
10288 }
10289 }
10290
10291 if (INVALID_RF_CHANNEL == channelEnum)
10292 return;
10293
10294 if (disable) {
10295 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10296 wiphy_chan->flags |=
10297 IEEE80211_CHAN_DISABLED;
10298 regChannels[channelEnum].enabled =
10299 NV_CHANNEL_DISABLE;
10300 }
10301 } else {
10302 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10303 wiphy_chan->flags &=
10304 ~IEEE80211_CHAN_DISABLED;
10305 /*
10306 * Indoor channels are marked as DFS
10307 * during regulatory processing
10308 */
10309
10310 regChannels[channelEnum].enabled =
10311 NV_CHANNEL_DFS;
10312 }
10313 }
10314
10315}
10316
10317void hdd_update_indoor_channel(hdd_context_t *hdd_ctx,
10318 bool disable)
10319{
10320 int band_num;
10321 int chan_num;
10322 v_U32_t rfChannel;
10323 struct ieee80211_channel *wiphy_chan;
10324 struct wiphy *wiphy;
10325
10326 ENTER();
10327 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10328
10329 wiphy = hdd_ctx->wiphy;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010330 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010331
10332 if (wiphy->bands[band_num] == NULL)
10333 continue;
10334
10335 for (chan_num = 0;
10336 chan_num < wiphy->bands[band_num]->n_channels;
10337 chan_num++) {
10338
10339 wiphy_chan =
10340 &(wiphy->bands[band_num]->channels[chan_num]);
10341 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10342
10343 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
10344 disable);
10345 }
10346 }
10347 EXIT();
10348}
10349
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010350/*
10351 * FUNCTION: wlan_hdd_disconnect
10352 * This function is used to issue a disconnect request to SME
10353 */
10354int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10355{
10356 int status, result = 0;
10357 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10358 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10359 long ret;
10360 eConnectionState prev_conn_state;
10361 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
10362
10363 ENTER();
10364
10365 status = wlan_hdd_validate_context(pHddCtx);
10366 if (0 != status)
10367 {
10368 return status;
10369 }
10370 /* Indicate sme of disconnect so that in progress connection or preauth
10371 * can be aborted
10372 */
10373 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10374 pAdapter->sessionId);
10375 pHddCtx->isAmpAllowed = VOS_TRUE;
10376
10377 /* Need to apply spin lock before decreasing active sessions
10378 * as there can be chance for double decrement if context switch
10379 * Calls hdd_DisConnectHandler.
10380 */
10381
10382 prev_conn_state = pHddStaCtx->conn_info.connState;
10383
10384 spin_lock_bh(&pAdapter->lock_for_active_session);
10385 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10386 {
10387 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10388 }
10389 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10390 spin_unlock_bh(&pAdapter->lock_for_active_session);
10391 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
10392
10393 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10394 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10395
10396 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10397
10398 /*
10399 * stop tx queues before deleting STA/BSS context from the firmware.
10400 * tx has to be disabled because the firmware can get busy dropping
10401 * the tx frames after BSS/STA has been deleted and will not send
10402 * back a response resulting in WDI timeout
10403 */
10404 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10405 netif_tx_disable(pAdapter->dev);
10406 netif_carrier_off(pAdapter->dev);
10407
10408 wlan_hdd_check_and_stop_mon(pAdapter, true);
10409
10410 /*issue disconnect*/
10411 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10412 pAdapter->sessionId, reason);
10413 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
10414 prev_conn_state != eConnectionState_Connecting)
10415 {
10416 hddLog(LOG1,
10417 FL("status = %d, already disconnected"), status);
10418 result = 0;
10419 /*
10420 * Wait here instead of returning directly. This will block the
10421 * next connect command and allow processing of the disconnect
10422 * in SME else we might hit some race conditions leading to SME
10423 * and HDD out of sync. As disconnect is already in progress,
10424 * wait here for 1 sec instead of 5 sec.
10425 */
10426 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
10427 goto wait_for_disconnect;
10428 }
10429 /*
10430 * Wait here instead of returning directly, this will block the next
10431 * connect command and allow processing of the scan for ssid and
10432 * the previous connect command in CSR. Else we might hit some
10433 * race conditions leading to SME and HDD out of sync.
10434 */
10435 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10436 {
10437 hddLog(LOG1,
10438 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
10439 }
10440 else if ( 0 != status )
10441 {
10442 hddLog(LOGE,
10443 FL("csrRoamDisconnect failure, returned %d"),
10444 (int)status);
10445 result = -EINVAL;
10446 goto disconnected;
10447 }
10448wait_for_disconnect:
10449 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
10450 msecs_to_jiffies(wait_time));
10451 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
10452 {
10453 hddLog(LOGE,
10454 "%s: Failed to disconnect, timed out", __func__);
10455 result = -ETIMEDOUT;
10456 }
10457disconnected:
10458 hddLog(LOG1,
10459 FL("Set HDD connState to eConnectionState_NotConnected"));
10460 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10461#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
10462 /* Sending disconnect event to userspace for kernel version < 3.11
10463 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
10464 */
10465 hddLog(LOG1, FL("Send disconnected event to userspace"));
10466
10467 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
10468 WLAN_REASON_UNSPECIFIED);
10469#endif
10470
10471 EXIT();
10472 return result;
10473}
10474
10475/*
10476 * hdd_check_and_disconnect_sta_on_invalid_channel() - Disconnect STA if it is
10477 * on indoor channel
10478 * @hdd_ctx: pointer to hdd context
10479 *
10480 * STA should be disconnected before starting the SAP if it is on indoor
10481 * channel.
10482 *
10483 * Return: void
10484 */
10485void hdd_check_and_disconnect_sta_on_invalid_channel(hdd_context_t *hdd_ctx)
10486{
10487
10488 hdd_adapter_t *sta_adapter;
10489 tANI_U8 sta_chan;
10490
10491 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
10492
10493 if (!sta_chan) {
10494 hddLog(LOG1, FL("STA not connected"));
10495 return;
10496 }
10497
10498 hddLog(LOG1, FL("STA connected on chan %hu"), sta_chan);
10499
10500 if (sme_IsChannelValid(hdd_ctx->hHal, sta_chan)) {
10501 hddLog(LOG1, FL("STA connected on chan %hu and it is valid"),
10502 sta_chan);
10503 return;
10504 }
10505
10506 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
10507
10508 if (!sta_adapter) {
10509 hddLog(LOG1, FL("STA adapter doesn't exist"));
10510 return;
10511 }
10512
10513 hddLog(LOG1, FL("chan %hu not valid, issue disconnect"), sta_chan);
10514 /* Issue Disconnect request */
10515 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10516}
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010517
Jeff Johnson295189b2012-06-20 16:38:30 -070010518#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10519static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10520 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010521#else
10522static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10523 struct cfg80211_beacon_data *params,
10524 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010525 enum nl80211_hidden_ssid hidden_ssid,
10526 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010527#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010528{
10529 tsap_Config_t *pConfig;
10530 beacon_data_t *pBeacon = NULL;
10531 struct ieee80211_mgmt *pMgmt_frame;
10532 v_U8_t *pIe=NULL;
10533 v_U16_t capab_info;
10534 eCsrAuthType RSNAuthType;
10535 eCsrEncryptionType RSNEncryptType;
10536 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010537 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010538 tpWLAN_SAPEventCB pSapEventCallback;
10539 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070010540 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010541 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010542 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010543 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070010544 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080010545 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +053010546 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070010547 v_BOOL_t MFPCapable = VOS_FALSE;
10548 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010549 v_BOOL_t sapEnable11AC =
10550 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053010551 u_int16_t prev_rsn_length = 0;
10552
Jeff Johnson295189b2012-06-20 16:38:30 -070010553 ENTER();
10554
Nitesh Shah9b066282017-06-06 18:05:52 +053010555 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010556 iniConfig = pHddCtx->cfg_ini;
10557
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010558 /* Mark the indoor channel (passive) to disable */
10559 if (iniConfig->disable_indoor_channel) {
10560 hdd_update_indoor_channel(pHddCtx, true);
10561
10562 if (!VOS_IS_STATUS_SUCCESS(
10563 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
10564 hdd_update_indoor_channel(pHddCtx, false);
10565 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
10566 FL("Can't start BSS: update channel list failed"));
10567 return eHAL_STATUS_FAILURE;
10568 }
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010569
10570 /* check if STA is on indoor channel */
10571 if (hdd_is_sta_sap_scc_allowed_on_dfs_chan(pHddCtx))
10572 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010573 }
10574
Jeff Johnson295189b2012-06-20 16:38:30 -070010575 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
10576
10577 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
10578
10579 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
10580
10581 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
10582
10583 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
10584
10585 //channel is already set in the set_channel Call back
10586 //pConfig->channel = pCommitConfig->channel;
10587
10588 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010589 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070010590 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
10591
10592 pConfig->dtim_period = pBeacon->dtim_period;
10593
Arif Hussain6d2a3322013-11-17 19:50:10 -080010594 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070010595 pConfig->dtim_period);
10596
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080010597 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070010598 {
10599 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010600 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053010601 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
10602 {
10603 tANI_BOOLEAN restartNeeded;
10604 pConfig->ieee80211d = 1;
10605 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
10606 sme_setRegInfo(hHal, pConfig->countryCode);
10607 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
10608 }
10609 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070010610 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070010611 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070010612 pConfig->ieee80211d = 1;
10613 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
10614 sme_setRegInfo(hHal, pConfig->countryCode);
10615 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070010616 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010617 else
10618 {
10619 pConfig->ieee80211d = 0;
10620 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010621 /*
10622 * If auto channel is configured i.e. channel is 0,
10623 * so skip channel validation.
10624 */
10625 if( AUTO_CHANNEL_SELECT != pConfig->channel )
10626 {
10627 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
10628 {
10629 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010630 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010631 return -EINVAL;
10632 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010633 pConfig->user_config_channel = pConfig->channel;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010634 }
10635 else
10636 {
10637 if(1 != pHddCtx->is_dynamic_channel_range_set)
10638 {
10639 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
10640 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
10641 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
10642 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010643 pHddCtx->is_dynamic_channel_range_set = 0;
10644 pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010645 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010646 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010647 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010648 {
10649 pConfig->ieee80211d = 0;
10650 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010651
10652#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10653 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10654 pConfig->authType = eSAP_OPEN_SYSTEM;
10655 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10656 pConfig->authType = eSAP_SHARED_KEY;
10657 else
10658 pConfig->authType = eSAP_AUTO_SWITCH;
10659#else
10660 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10661 pConfig->authType = eSAP_OPEN_SYSTEM;
10662 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10663 pConfig->authType = eSAP_SHARED_KEY;
10664 else
10665 pConfig->authType = eSAP_AUTO_SWITCH;
10666#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010667
10668 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010669
10670 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070010671 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053010672#ifdef SAP_AUTH_OFFLOAD
10673 /* In case of sap offload, hostapd.conf is configuted with open mode and
10674 * security is configured from ini file. Due to open mode in hostapd.conf
10675 * privacy bit is set to false which will result in not sending,
10676 * data packets as encrypted.
10677 * If enable_sap_auth_offload is enabled in ini and
10678 * sap_auth_offload_sec_type is type of WPA2-PSK,
10679 * driver will set privacy bit to 1.
10680 */
10681 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
10682 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
10683 pConfig->privacy = VOS_TRUE;
10684#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010685
10686 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
10687
10688 /*Set wps station to configured*/
10689 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
10690
10691 if(pIe)
10692 {
10693 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
10694 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010695 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -070010696 return -EINVAL;
10697 }
10698 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
10699 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070010700 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070010701 /* Check 15 bit of WPS IE as it contain information for wps state
10702 * WPS state
10703 */
10704 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
10705 {
10706 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
10707 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
10708 {
10709 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
10710 }
10711 }
10712 }
10713 else
10714 {
10715 pConfig->wps_state = SAP_WPS_DISABLED;
10716 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010717 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070010718
c_hpothufe599e92014-06-16 11:38:55 +053010719 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10720 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10721 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
10722 eCSR_ENCRYPT_TYPE_NONE;
10723
Jeff Johnson295189b2012-06-20 16:38:30 -070010724 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053010725 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010726 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010727 WLAN_EID_RSN);
10728 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010729 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010730 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010731 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10732 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10733 pConfig->RSNWPAReqIELength);
10734 else
10735 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10736 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010737 /* The actual processing may eventually be more extensive than
10738 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070010739 * by the app.
10740 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010741 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010742 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10743 &RSNEncryptType,
10744 &mcRSNEncryptType,
10745 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010746 &MFPCapable,
10747 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010748 pConfig->RSNWPAReqIE[1]+2,
10749 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010750
10751 if( VOS_STATUS_SUCCESS == status )
10752 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010753 /* Now copy over all the security attributes you have
10754 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010755 * */
10756 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10757 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10758 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10759 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010760 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010761 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010762 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10763 }
10764 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010765
Jeff Johnson295189b2012-06-20 16:38:30 -070010766 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10767 pBeacon->tail, pBeacon->tail_len);
10768
10769 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
10770 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010771 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010772 {
10773 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053010774 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070010775 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010776 if (pConfig->RSNWPAReqIELength <=
10777 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
10778 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
10779 pIe[1] + 2);
10780 else
10781 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10782 pConfig->RSNWPAReqIELength);
10783
Jeff Johnson295189b2012-06-20 16:38:30 -070010784 }
10785 else
10786 {
10787 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010788 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10789 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10790 pConfig->RSNWPAReqIELength);
10791 else
10792 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10793 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010794 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010795 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10796 &RSNEncryptType,
10797 &mcRSNEncryptType,
10798 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010799 &MFPCapable,
10800 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010801 pConfig->RSNWPAReqIE[1]+2,
10802 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010803
10804 if( VOS_STATUS_SUCCESS == status )
10805 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010806 /* Now copy over all the security attributes you have
10807 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010808 * */
10809 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10810 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10811 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10812 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010813 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010814 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010815 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10816 }
10817 }
10818 }
10819
Kapil Gupta137ef892016-12-13 19:38:00 +053010820 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070010821 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
10822 return -EINVAL;
10823 }
10824
Jeff Johnson295189b2012-06-20 16:38:30 -070010825 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
10826
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010827#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010828 if (params->ssid != NULL)
10829 {
10830 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
10831 pConfig->SSIDinfo.ssid.length = params->ssid_len;
10832 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10833 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10834 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010835#else
10836 if (ssid != NULL)
10837 {
10838 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
10839 pConfig->SSIDinfo.ssid.length = ssid_len;
10840 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10841 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10842 }
10843#endif
10844
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010845 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070010846 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010847
Jeff Johnson295189b2012-06-20 16:38:30 -070010848 /* default value */
10849 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
10850 pConfig->num_accept_mac = 0;
10851 pConfig->num_deny_mac = 0;
10852
10853 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10854 pBeacon->tail, pBeacon->tail_len);
10855
10856 /* pIe for black list is following form:
10857 type : 1 byte
10858 length : 1 byte
10859 OUI : 4 bytes
10860 acl type : 1 byte
10861 no of mac addr in black list: 1 byte
10862 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010863 */
10864 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010865 {
10866 pConfig->SapMacaddr_acl = pIe[6];
10867 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010868 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010869 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010870 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
10871 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010872 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10873 for (i = 0; i < pConfig->num_deny_mac; i++)
10874 {
10875 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10876 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010877 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010878 }
10879 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10880 pBeacon->tail, pBeacon->tail_len);
10881
10882 /* pIe for white list is following form:
10883 type : 1 byte
10884 length : 1 byte
10885 OUI : 4 bytes
10886 acl type : 1 byte
10887 no of mac addr in white list: 1 byte
10888 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010889 */
10890 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010891 {
10892 pConfig->SapMacaddr_acl = pIe[6];
10893 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010894 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010895 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010896 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
10897 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010898 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10899 for (i = 0; i < pConfig->num_accept_mac; i++)
10900 {
10901 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10902 acl_entry++;
10903 }
10904 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010905
Jeff Johnson295189b2012-06-20 16:38:30 -070010906 wlan_hdd_set_sapHwmode(pHostapdAdapter);
10907
Jeff Johnsone7245742012-09-05 17:12:55 -070010908#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010909 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010910 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
10911 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053010912 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
10913 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010914 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
10915 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010916 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
10917 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070010918 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010919 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070010920 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010921 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010922
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010923 /* If ACS disable and selected channel <= 14
10924 * OR
10925 * ACS enabled and ACS operating band is choosen as 2.4
10926 * AND
10927 * VHT in 2.4G Disabled
10928 * THEN
10929 * Fallback to 11N mode
10930 */
10931 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
10932 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053010933 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010934 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010935 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010936 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
10937 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010938 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
10939 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010940 }
10941#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010942
Jeff Johnson295189b2012-06-20 16:38:30 -070010943 // ht_capab is not what the name conveys,this is used for protection bitmap
10944 pConfig->ht_capab =
10945 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
10946
Kapil Gupta137ef892016-12-13 19:38:00 +053010947 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010948 {
10949 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10950 return -EINVAL;
10951 }
10952
10953 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010954 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070010955 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
10956 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010957 pConfig->obssProtEnabled =
10958 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070010959
Chet Lanctot8cecea22014-02-11 19:09:36 -080010960#ifdef WLAN_FEATURE_11W
10961 pConfig->mfpCapable = MFPCapable;
10962 pConfig->mfpRequired = MFPRequired;
10963 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
10964 pConfig->mfpCapable, pConfig->mfpRequired);
10965#endif
10966
Arif Hussain6d2a3322013-11-17 19:50:10 -080010967 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070010968 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010969 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
10970 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
10971 (int)pConfig->channel);
10972 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
10973 pConfig->SapHw_mode, pConfig->privacy,
10974 pConfig->authType);
10975 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
10976 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
10977 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
10978 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070010979
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010980 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010981 {
10982 //Bss already started. just return.
10983 //TODO Probably it should update some beacon params.
10984 hddLog( LOGE, "Bss Already started...Ignore the request");
10985 EXIT();
10986 return 0;
10987 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010988
Agarwal Ashish51325b52014-06-16 16:50:49 +053010989 if (vos_max_concurrent_connections_reached()) {
10990 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10991 return -EINVAL;
10992 }
10993
Jeff Johnson295189b2012-06-20 16:38:30 -070010994 pConfig->persona = pHostapdAdapter->device_mode;
10995
Peng Xu2446a892014-09-05 17:21:18 +053010996 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
10997 if ( NULL != psmeConfig)
10998 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010999 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053011000 sme_GetConfigParam(hHal, psmeConfig);
11001 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011002#ifdef WLAN_FEATURE_AP_HT40_24G
11003 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11004 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
11005 && pHddCtx->cfg_ini->apHT40_24GEnabled)
11006 {
11007 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
11008 sme_UpdateConfig (hHal, psmeConfig);
11009 }
11010#endif
Peng Xu2446a892014-09-05 17:21:18 +053011011 vos_mem_free(psmeConfig);
11012 }
Peng Xuafc34e32014-09-25 13:23:55 +053011013 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053011014
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011015 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
11016
Jeff Johnson295189b2012-06-20 16:38:30 -070011017 pSapEventCallback = hdd_hostapd_SAPEventCB;
11018 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
11019 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
11020 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011021 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011022 ret = -EINVAL;
11023 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011024 }
11025
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011026 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070011027 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
11028
11029 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011030
Jeff Johnson295189b2012-06-20 16:38:30 -070011031 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011032 {
11033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011034 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070011035 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011036 VOS_ASSERT(0);
11037 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011038
Jeff Johnson295189b2012-06-20 16:38:30 -070011039 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053011040 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
11041 VOS_STATUS_SUCCESS)
11042 {
11043 hddLog(LOGE,FL("Fail to get Softap sessionID"));
11044 VOS_ASSERT(0);
11045 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053011046 /* Initialize WMM configuation */
11047 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011048 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011049
Anurag Chouhan83026002016-12-13 22:46:21 +053011050#ifdef DHCP_SERVER_OFFLOAD
11051 /* set dhcp server offload */
11052 if (iniConfig->enable_dhcp_srv_offload &&
11053 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011054 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053011055 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053011056 if (!VOS_IS_STATUS_SUCCESS(status))
11057 {
11058 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11059 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011060 vos_event_reset(&pHostapdState->vosEvent);
11061 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11062 status = vos_wait_single_event(&pHostapdState->vosEvent,
11063 10000);
11064 if (!VOS_IS_STATUS_SUCCESS(status)) {
11065 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011066 ret = -EINVAL;
11067 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011068 }
11069 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011070 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011071 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
11072 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
11073 {
11074 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11075 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
11076 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011077 vos_event_reset(&pHostapdState->vosEvent);
11078 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11079 status = vos_wait_single_event(&pHostapdState->vosEvent,
11080 10000);
11081 if (!VOS_IS_STATUS_SUCCESS(status)) {
11082 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011083 ret = -EINVAL;
11084 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011085 }
11086 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011087 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011088#ifdef MDNS_OFFLOAD
11089 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011090 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011091 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
11092 if (VOS_IS_STATUS_SUCCESS(status))
11093 {
11094 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11095 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011096 vos_event_reset(&pHostapdState->vosEvent);
11097 if (VOS_STATUS_SUCCESS ==
11098 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11099 status = vos_wait_single_event(&pHostapdState->vosEvent,
11100 10000);
11101 if (!VOS_IS_STATUS_SUCCESS(status)) {
11102 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011103 ret = -EINVAL;
11104 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011105 }
11106 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011107 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011108 status = vos_wait_single_event(&pHostapdAdapter->
11109 mdns_status.vos_event, 2000);
11110 if (!VOS_IS_STATUS_SUCCESS(status) ||
11111 pHostapdAdapter->mdns_status.mdns_enable_status ||
11112 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
11113 pHostapdAdapter->mdns_status.mdns_resp_status)
11114 {
11115 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11116 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
11117 pHostapdAdapter->mdns_status.mdns_enable_status,
11118 pHostapdAdapter->mdns_status.mdns_fqdn_status,
11119 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011120 vos_event_reset(&pHostapdState->vosEvent);
11121 if (VOS_STATUS_SUCCESS ==
11122 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11123 status = vos_wait_single_event(&pHostapdState->vosEvent,
11124 10000);
11125 if (!VOS_IS_STATUS_SUCCESS(status)) {
11126 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011127 ret = -EINVAL;
11128 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011129 }
11130 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011131 }
11132 }
11133#endif /* MDNS_OFFLOAD */
11134 } else {
11135 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11136 ("DHCP Disabled ini %d, FW %d"),
11137 iniConfig->enable_dhcp_srv_offload,
11138 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053011139 }
11140#endif /* DHCP_SERVER_OFFLOAD */
11141
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011142#ifdef WLAN_FEATURE_P2P_DEBUG
11143 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
11144 {
11145 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
11146 {
11147 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11148 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011149 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011150 }
11151 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
11152 {
11153 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11154 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011155 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011156 }
11157 }
11158#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053011159 /* Check and restart SAP if it is on Unsafe channel */
11160 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011161
Jeff Johnson295189b2012-06-20 16:38:30 -070011162 pHostapdState->bCommit = TRUE;
11163 EXIT();
11164
11165 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011166error:
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011167 /* Revert the indoor to passive marking if START BSS fails */
11168 if (iniConfig->disable_indoor_channel) {
11169 hdd_update_indoor_channel(pHddCtx, false);
11170 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
11171 }
11172
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011173 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
11174 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011175}
11176
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011177#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011178static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011179 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011180 struct beacon_parameters *params)
11181{
11182 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011183 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011184 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011185
11186 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011187
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011188 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11189 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11190 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011191 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11192 hdd_device_modetoString(pAdapter->device_mode),
11193 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011194
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011195 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11196 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011197 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011198 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011199 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011200 }
11201
Agarwal Ashish51325b52014-06-16 16:50:49 +053011202 if (vos_max_concurrent_connections_reached()) {
11203 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11204 return -EINVAL;
11205 }
11206
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011207 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011208 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011209 )
11210 {
11211 beacon_data_t *old,*new;
11212
11213 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011214
Jeff Johnson295189b2012-06-20 16:38:30 -070011215 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011216 {
11217 hddLog(VOS_TRACE_LEVEL_WARN,
11218 FL("already beacon info added to session(%d)"),
11219 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011220 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011221 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011222
11223 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11224
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011225 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011226 {
11227 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011228 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011229 return -EINVAL;
11230 }
11231
11232 pAdapter->sessionCtx.ap.beacon = new;
11233
11234 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11235 }
11236
11237 EXIT();
11238 return status;
11239}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011240
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011241static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11242 struct net_device *dev,
11243 struct beacon_parameters *params)
11244{
11245 int ret;
11246
11247 vos_ssr_protect(__func__);
11248 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11249 vos_ssr_unprotect(__func__);
11250
11251 return ret;
11252}
11253
11254static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011255 struct net_device *dev,
11256 struct beacon_parameters *params)
11257{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011258 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011259 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11260 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011261 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011262
11263 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011264
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011265 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11266 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11267 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11268 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11269 __func__, hdd_device_modetoString(pAdapter->device_mode),
11270 pAdapter->device_mode);
11271
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011272 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11273 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011274 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011275 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011276 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011277 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011278
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011279 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011280 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011281 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011282 {
11283 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011284
Jeff Johnson295189b2012-06-20 16:38:30 -070011285 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011286
Jeff Johnson295189b2012-06-20 16:38:30 -070011287 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011288 {
11289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11290 FL("session(%d) old and new heads points to NULL"),
11291 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011292 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011293 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011294
11295 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11296
11297 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011298 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011299 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011300 return -EINVAL;
11301 }
11302
11303 pAdapter->sessionCtx.ap.beacon = new;
11304
11305 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11306 }
11307
11308 EXIT();
11309 return status;
11310}
11311
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011312static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11313 struct net_device *dev,
11314 struct beacon_parameters *params)
11315{
11316 int ret;
11317
11318 vos_ssr_protect(__func__);
11319 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11320 vos_ssr_unprotect(__func__);
11321
11322 return ret;
11323}
11324
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011325#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11326
11327#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011328static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011329 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011330#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011331static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011332 struct net_device *dev)
11333#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011334{
11335 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070011336 hdd_context_t *pHddCtx = NULL;
11337 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011338 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011339 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011340
11341 ENTER();
11342
11343 if (NULL == pAdapter)
11344 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011346 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011347 return -ENODEV;
11348 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011349
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011350 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11351 TRACE_CODE_HDD_CFG80211_STOP_AP,
11352 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011353 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11354 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011355 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011356 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011357 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011358 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011359
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011360 pScanInfo = &pHddCtx->scan_info;
11361
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011362 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11363 __func__, hdd_device_modetoString(pAdapter->device_mode),
11364 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011365
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011366 ret = wlan_hdd_scan_abort(pAdapter);
11367
Girish Gowli4bf7a632014-06-12 13:42:11 +053011368 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011369 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11371 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011372
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011373 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011374 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11376 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011377
Jeff Johnsone7245742012-09-05 17:12:55 -070011378 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011379 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011380 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011381 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011382 }
11383
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011384 /* Delete all associated STAs before stopping AP/P2P GO */
11385 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011386 hdd_hostapd_stop(dev);
11387
Jeff Johnson295189b2012-06-20 16:38:30 -070011388 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011389 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011390 )
11391 {
11392 beacon_data_t *old;
11393
11394 old = pAdapter->sessionCtx.ap.beacon;
11395
11396 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011397 {
11398 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11399 FL("session(%d) beacon data points to NULL"),
11400 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011401 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011402 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011403
Jeff Johnson295189b2012-06-20 16:38:30 -070011404 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011405
11406 mutex_lock(&pHddCtx->sap_lock);
11407 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11408 {
Jeff Johnson4416a782013-03-25 14:17:50 -070011409 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011410 {
11411 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11412
11413 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11414
11415 if (!VOS_IS_STATUS_SUCCESS(status))
11416 {
11417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011418 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011419 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011420 }
11421 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011422 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011423 /* BSS stopped, clear the active sessions for this device mode */
11424 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011425 }
11426 mutex_unlock(&pHddCtx->sap_lock);
11427
11428 if(status != VOS_STATUS_SUCCESS)
11429 {
11430 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011431 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011432 return -EINVAL;
11433 }
11434
Jeff Johnson4416a782013-03-25 14:17:50 -070011435 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011436 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11437 ==eHAL_STATUS_FAILURE)
11438 {
11439 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011440 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011441 }
11442
Jeff Johnson4416a782013-03-25 14:17:50 -070011443 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011444 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11445 eANI_BOOLEAN_FALSE) )
11446 {
11447 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011448 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011449 }
11450
11451 // Reset WNI_CFG_PROBE_RSP Flags
11452 wlan_hdd_reset_prob_rspies(pAdapter);
11453
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011454 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11455
Jeff Johnson295189b2012-06-20 16:38:30 -070011456 pAdapter->sessionCtx.ap.beacon = NULL;
11457 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011458#ifdef WLAN_FEATURE_P2P_DEBUG
11459 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11460 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11461 {
11462 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11463 "GO got removed");
11464 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11465 }
11466#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011467 }
11468 EXIT();
11469 return status;
11470}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011471
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011472#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11473static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
11474 struct net_device *dev)
11475{
11476 int ret;
11477
11478 vos_ssr_protect(__func__);
11479 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
11480 vos_ssr_unprotect(__func__);
11481
11482 return ret;
11483}
11484#else
11485static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
11486 struct net_device *dev)
11487{
11488 int ret;
11489
11490 vos_ssr_protect(__func__);
11491 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
11492 vos_ssr_unprotect(__func__);
11493
11494 return ret;
11495}
11496#endif
11497
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011498#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
11499
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011500static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011501 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011502 struct cfg80211_ap_settings *params)
11503{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011504 hdd_adapter_t *pAdapter;
11505 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011506 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011507
11508 ENTER();
11509
Girish Gowlib143d7a2015-02-18 19:39:55 +053011510 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011511 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053011513 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011514 return -ENODEV;
11515 }
11516
11517 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11518 if (NULL == pAdapter)
11519 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011521 "%s: HDD adapter is Null", __func__);
11522 return -ENODEV;
11523 }
11524
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011525 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11526 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
11527 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011528 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
11529 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011531 "%s: HDD adapter magic is invalid", __func__);
11532 return -ENODEV;
11533 }
11534
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011535 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11536
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011537 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011538 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011539 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011540 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011541 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011542 }
11543
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011544 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
11545 __func__, hdd_device_modetoString(pAdapter->device_mode),
11546 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011547
11548 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011549 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011550 )
11551 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011552 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011553
11554 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011555
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011556 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011557 {
11558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
11559 FL("already beacon info added to session(%d)"),
11560 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011561 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011562 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011563
Girish Gowlib143d7a2015-02-18 19:39:55 +053011564#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11565 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11566 &new,
11567 &params->beacon);
11568#else
11569 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11570 &new,
11571 &params->beacon,
11572 params->dtim_period);
11573#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011574
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011575 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011576 {
11577 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011578 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011579 return -EINVAL;
11580 }
11581 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080011582#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070011583 wlan_hdd_cfg80211_set_channel(wiphy, dev,
11584#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
11585 params->channel, params->channel_type);
11586#else
11587 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
11588#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080011589#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011590 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011591 params->ssid_len, params->hidden_ssid,
11592 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011593 }
11594
11595 EXIT();
11596 return status;
11597}
11598
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011599static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
11600 struct net_device *dev,
11601 struct cfg80211_ap_settings *params)
11602{
11603 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011604
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011605 vos_ssr_protect(__func__);
11606 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
11607 vos_ssr_unprotect(__func__);
11608
11609 return ret;
11610}
11611
11612static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011613 struct net_device *dev,
11614 struct cfg80211_beacon_data *params)
11615{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011616 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011617 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011618 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011619
11620 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011621
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011622 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11623 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
11624 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011625 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011626 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011627
11628 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11629 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011630 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011631 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011632 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011633 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011634
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011635 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011636 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011637 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011638 {
11639 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011640
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011641 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011642
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011643 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011644 {
11645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11646 FL("session(%d) beacon data points to NULL"),
11647 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011648 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011649 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011650
11651 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
11652
11653 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011654 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011655 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011656 return -EINVAL;
11657 }
11658
11659 pAdapter->sessionCtx.ap.beacon = new;
11660
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011661 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
11662 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011663 }
11664
11665 EXIT();
11666 return status;
11667}
11668
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011669static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
11670 struct net_device *dev,
11671 struct cfg80211_beacon_data *params)
11672{
11673 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011674
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011675 vos_ssr_protect(__func__);
11676 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
11677 vos_ssr_unprotect(__func__);
11678
11679 return ret;
11680}
11681
11682#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011683
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011684static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011685 struct net_device *dev,
11686 struct bss_parameters *params)
11687{
11688 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011689 hdd_context_t *pHddCtx;
11690 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011691
11692 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011693
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011694 if (NULL == pAdapter)
11695 {
11696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11697 "%s: HDD adapter is Null", __func__);
11698 return -ENODEV;
11699 }
11700 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011701 ret = wlan_hdd_validate_context(pHddCtx);
11702 if (0 != ret)
11703 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011704 return ret;
11705 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011706 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11707 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
11708 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011709 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11710 __func__, hdd_device_modetoString(pAdapter->device_mode),
11711 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011712
11713 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011714 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011715 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011716 {
11717 /* ap_isolate == -1 means that in change bss, upper layer doesn't
11718 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011719 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070011720 {
11721 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011722 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011723 }
11724
11725 EXIT();
11726 return 0;
11727}
11728
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011729static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
11730 struct net_device *dev,
11731 struct bss_parameters *params)
11732{
11733 int ret;
11734
11735 vos_ssr_protect(__func__);
11736 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
11737 vos_ssr_unprotect(__func__);
11738
11739 return ret;
11740}
Kiet Lam10841362013-11-01 11:36:50 +053011741/* FUNCTION: wlan_hdd_change_country_code_cd
11742* to wait for contry code completion
11743*/
11744void* wlan_hdd_change_country_code_cb(void *pAdapter)
11745{
11746 hdd_adapter_t *call_back_pAdapter = pAdapter;
11747 complete(&call_back_pAdapter->change_country_code);
11748 return NULL;
11749}
11750
Jeff Johnson295189b2012-06-20 16:38:30 -070011751/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011752 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070011753 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
11754 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011755int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011756 struct net_device *ndev,
11757 enum nl80211_iftype type,
11758 u32 *flags,
11759 struct vif_params *params
11760 )
11761{
11762 struct wireless_dev *wdev;
11763 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011764 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070011765 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011766 tCsrRoamProfile *pRoamProfile = NULL;
11767 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011768 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011769 eMib_dot11DesiredBssType connectedBssType;
11770 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011771 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011772
11773 ENTER();
11774
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011775 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011776 {
11777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11778 "%s: Adapter context is null", __func__);
11779 return VOS_STATUS_E_FAILURE;
11780 }
11781
11782 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11783 if (!pHddCtx)
11784 {
11785 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11786 "%s: HDD context is null", __func__);
11787 return VOS_STATUS_E_FAILURE;
11788 }
11789
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011790 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11791 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
11792 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011793 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011794 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011795 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011796 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011797 }
11798
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011799 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11800 __func__, hdd_device_modetoString(pAdapter->device_mode),
11801 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011802
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053011803 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
11804 hddLog(VOS_TRACE_LEVEL_FATAL,
11805 "%s: STA + MON is in progress, cannot change interface",
11806 __func__);
11807 }
11808
Agarwal Ashish51325b52014-06-16 16:50:49 +053011809 if (vos_max_concurrent_connections_reached()) {
11810 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11811 return -EINVAL;
11812 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011813 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011814 wdev = ndev->ieee80211_ptr;
11815
11816#ifdef WLAN_BTAMP_FEATURE
11817 if((NL80211_IFTYPE_P2P_CLIENT == type)||
11818 (NL80211_IFTYPE_ADHOC == type)||
11819 (NL80211_IFTYPE_AP == type)||
11820 (NL80211_IFTYPE_P2P_GO == type))
11821 {
11822 pHddCtx->isAmpAllowed = VOS_FALSE;
11823 // stop AMP traffic
11824 status = WLANBAP_StopAmp();
11825 if(VOS_STATUS_SUCCESS != status )
11826 {
11827 pHddCtx->isAmpAllowed = VOS_TRUE;
11828 hddLog(VOS_TRACE_LEVEL_FATAL,
11829 "%s: Failed to stop AMP", __func__);
11830 return -EINVAL;
11831 }
11832 }
11833#endif //WLAN_BTAMP_FEATURE
11834 /* Reset the current device mode bit mask*/
11835 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
11836
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053011837 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
11838 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
11839 (type == NL80211_IFTYPE_P2P_GO)))
11840 {
11841 /* Notify Mode change in case of concurrency.
11842 * Below function invokes TDLS teardown Functionality Since TDLS is
11843 * not Supported in case of concurrency i.e Once P2P session
11844 * is detected disable offchannel and teardown TDLS links
11845 */
11846 hddLog(LOG1,
11847 FL("Device mode = %d Interface type = %d"),
11848 pAdapter->device_mode, type);
11849 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
11850 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053011851
Jeff Johnson295189b2012-06-20 16:38:30 -070011852 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011853 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070011854 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011855 )
11856 {
11857 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011858 if (!pWextState)
11859 {
11860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11861 "%s: pWextState is null", __func__);
11862 return VOS_STATUS_E_FAILURE;
11863 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011864 pRoamProfile = &pWextState->roamProfile;
11865 LastBSSType = pRoamProfile->BSSType;
11866
11867 switch (type)
11868 {
11869 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011870 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011871 hddLog(VOS_TRACE_LEVEL_INFO,
11872 "%s: setting interface Type to INFRASTRUCTURE", __func__);
11873 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011874#ifdef WLAN_FEATURE_11AC
11875 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
11876 {
11877 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
11878 }
11879#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011880 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070011881 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011882 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011883 //Check for sub-string p2p to confirm its a p2p interface
11884 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011885 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053011886#ifdef FEATURE_WLAN_TDLS
11887 mutex_lock(&pHddCtx->tdls_lock);
11888 wlan_hdd_tdls_exit(pAdapter, TRUE);
11889 mutex_unlock(&pHddCtx->tdls_lock);
11890#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011891 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11892 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11893 }
11894 else
11895 {
11896 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011897 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011898 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011899 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053011900
Jeff Johnson295189b2012-06-20 16:38:30 -070011901 case NL80211_IFTYPE_ADHOC:
11902 hddLog(VOS_TRACE_LEVEL_INFO,
11903 "%s: setting interface Type to ADHOC", __func__);
11904 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
11905 pRoamProfile->phyMode =
11906 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070011907 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011908 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053011909 hdd_set_ibss_ops( pAdapter );
11910 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053011911
11912 status = hdd_sta_id_hash_attach(pAdapter);
11913 if (VOS_STATUS_SUCCESS != status) {
11914 hddLog(VOS_TRACE_LEVEL_ERROR,
11915 FL("Failed to initialize hash for IBSS"));
11916 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011917 break;
11918
11919 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011920 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011921 {
11922 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11923 "%s: setting interface Type to %s", __func__,
11924 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
11925
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011926 //Cancel any remain on channel for GO mode
11927 if (NL80211_IFTYPE_P2P_GO == type)
11928 {
11929 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
11930 }
Mohit Khanna0f232092012-09-11 14:46:08 -070011931 if (NL80211_IFTYPE_AP == type)
11932 {
11933 /* As Loading WLAN Driver one interface being created for p2p device
11934 * address. This will take one HW STA and the max number of clients
11935 * that can connect to softAP will be reduced by one. so while changing
11936 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
11937 * interface as it is not required in SoftAP mode.
11938 */
11939
11940 // Get P2P Adapter
11941 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
11942
11943 if (pP2pAdapter)
11944 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053011945 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053011946 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070011947 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
11948 }
11949 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053011950 //Disable IMPS & BMPS for SAP/GO
11951 if(VOS_STATUS_E_FAILURE ==
11952 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
11953 {
11954 //Fail to Exit BMPS
11955 VOS_ASSERT(0);
11956 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053011957
11958 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
11959
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011960#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070011961
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011962 /* A Mutex Lock is introduced while changing the mode to
11963 * protect the concurrent access for the Adapters by TDLS
11964 * module.
11965 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011966 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011967#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011968 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053011969 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011970 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070011971 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11972 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011973#ifdef FEATURE_WLAN_TDLS
11974 mutex_unlock(&pHddCtx->tdls_lock);
11975#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011976 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
11977 (pConfig->apRandomBssidEnabled))
11978 {
11979 /* To meet Android requirements create a randomized
11980 MAC address of the form 02:1A:11:Fx:xx:xx */
11981 get_random_bytes(&ndev->dev_addr[3], 3);
11982 ndev->dev_addr[0] = 0x02;
11983 ndev->dev_addr[1] = 0x1A;
11984 ndev->dev_addr[2] = 0x11;
11985 ndev->dev_addr[3] |= 0xF0;
11986 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
11987 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080011988 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
11989 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011990 }
11991
Jeff Johnson295189b2012-06-20 16:38:30 -070011992 hdd_set_ap_ops( pAdapter->dev );
11993
Kiet Lam10841362013-11-01 11:36:50 +053011994 /* This is for only SAP mode where users can
11995 * control country through ini.
11996 * P2P GO follows station country code
11997 * acquired during the STA scanning. */
11998 if((NL80211_IFTYPE_AP == type) &&
11999 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
12000 {
12001 int status = 0;
12002 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
12003 "%s: setting country code from INI ", __func__);
12004 init_completion(&pAdapter->change_country_code);
12005 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
12006 (void *)(tSmeChangeCountryCallback)
12007 wlan_hdd_change_country_code_cb,
12008 pConfig->apCntryCode, pAdapter,
12009 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012010 eSIR_FALSE,
12011 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053012012 if (eHAL_STATUS_SUCCESS == status)
12013 {
12014 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012015 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053012016 &pAdapter->change_country_code,
12017 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012018 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053012019 {
12020 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012021 FL("SME Timed out while setting country code %ld"),
12022 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080012023
12024 if (pHddCtx->isLogpInProgress)
12025 {
12026 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12027 "%s: LOGP in Progress. Ignore!!!", __func__);
12028 return -EAGAIN;
12029 }
Kiet Lam10841362013-11-01 11:36:50 +053012030 }
12031 }
12032 else
12033 {
12034 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012035 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053012036 return -EINVAL;
12037 }
12038 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053012039 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070012040 if(status != VOS_STATUS_SUCCESS)
12041 {
12042 hddLog(VOS_TRACE_LEVEL_FATAL,
12043 "%s: Error initializing the ap mode", __func__);
12044 return -EINVAL;
12045 }
12046 hdd_set_conparam(1);
12047
Nirav Shah7e3c8132015-06-22 23:51:42 +053012048 status = hdd_sta_id_hash_attach(pAdapter);
12049 if (VOS_STATUS_SUCCESS != status)
12050 {
12051 hddLog(VOS_TRACE_LEVEL_ERROR,
12052 FL("Failed to initialize hash for AP"));
12053 return -EINVAL;
12054 }
12055
Jeff Johnson295189b2012-06-20 16:38:30 -070012056 /*interface type changed update in wiphy structure*/
12057 if(wdev)
12058 {
12059 wdev->iftype = type;
12060 pHddCtx->change_iface = type;
12061 }
12062 else
12063 {
12064 hddLog(VOS_TRACE_LEVEL_ERROR,
12065 "%s: ERROR !!!! Wireless dev is NULL", __func__);
12066 return -EINVAL;
12067 }
12068 goto done;
12069 }
12070
12071 default:
12072 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12073 __func__);
12074 return -EOPNOTSUPP;
12075 }
12076 }
12077 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012078 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070012079 )
12080 {
12081 switch(type)
12082 {
12083 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012084 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012085 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053012086
12087 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012088#ifdef FEATURE_WLAN_TDLS
12089
12090 /* A Mutex Lock is introduced while changing the mode to
12091 * protect the concurrent access for the Adapters by TDLS
12092 * module.
12093 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012094 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012095#endif
c_hpothu002231a2015-02-05 14:58:51 +053012096 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012097 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012098 //Check for sub-string p2p to confirm its a p2p interface
12099 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012100 {
12101 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12102 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12103 }
12104 else
12105 {
12106 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012107 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012108 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053012109
12110 /* set con_mode to STA only when no SAP concurrency mode */
12111 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
12112 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012113 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012114 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
12115 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012116#ifdef FEATURE_WLAN_TDLS
12117 mutex_unlock(&pHddCtx->tdls_lock);
12118#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053012119 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070012120 if( VOS_STATUS_SUCCESS != status )
12121 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070012122 /* In case of JB, for P2P-GO, only change interface will be called,
12123 * This is the right place to enable back bmps_imps()
12124 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012125 if (pHddCtx->hdd_wlan_suspended)
12126 {
12127 hdd_set_pwrparams(pHddCtx);
12128 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012129 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012130 goto done;
12131 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012132 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012133 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012134 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12135 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012136 goto done;
12137 default:
12138 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12139 __func__);
12140 return -EOPNOTSUPP;
12141
12142 }
12143
12144 }
12145 else
12146 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012147 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
12148 __func__, hdd_device_modetoString(pAdapter->device_mode),
12149 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012150 return -EOPNOTSUPP;
12151 }
12152
12153
12154 if(pRoamProfile)
12155 {
12156 if ( LastBSSType != pRoamProfile->BSSType )
12157 {
12158 /*interface type changed update in wiphy structure*/
12159 wdev->iftype = type;
12160
12161 /*the BSS mode changed, We need to issue disconnect
12162 if connected or in IBSS disconnect state*/
12163 if ( hdd_connGetConnectedBssType(
12164 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
12165 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
12166 {
12167 /*need to issue a disconnect to CSR.*/
12168 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12169 if( eHAL_STATUS_SUCCESS ==
12170 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12171 pAdapter->sessionId,
12172 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12173 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012174 ret = wait_for_completion_interruptible_timeout(
12175 &pAdapter->disconnect_comp_var,
12176 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12177 if (ret <= 0)
12178 {
12179 hddLog(VOS_TRACE_LEVEL_ERROR,
12180 FL("wait on disconnect_comp_var failed %ld"), ret);
12181 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012182 }
12183 }
12184 }
12185 }
12186
12187done:
12188 /*set bitmask based on updated value*/
12189 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012190
12191 /* Only STA mode support TM now
12192 * all other mode, TM feature should be disabled */
12193 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12194 (~VOS_STA & pHddCtx->concurrency_mode) )
12195 {
12196 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12197 }
12198
Jeff Johnson295189b2012-06-20 16:38:30 -070012199#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012200 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012201 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012202 {
12203 //we are ok to do AMP
12204 pHddCtx->isAmpAllowed = VOS_TRUE;
12205 }
12206#endif //WLAN_BTAMP_FEATURE
12207 EXIT();
12208 return 0;
12209}
12210
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012211/*
12212 * FUNCTION: wlan_hdd_cfg80211_change_iface
12213 * wrapper function to protect the actual implementation from SSR.
12214 */
12215int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12216 struct net_device *ndev,
12217 enum nl80211_iftype type,
12218 u32 *flags,
12219 struct vif_params *params
12220 )
12221{
12222 int ret;
12223
12224 vos_ssr_protect(__func__);
12225 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12226 vos_ssr_unprotect(__func__);
12227
12228 return ret;
12229}
12230
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012231#ifdef FEATURE_WLAN_TDLS
12232static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012233 struct net_device *dev,
12234#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12235 const u8 *mac,
12236#else
12237 u8 *mac,
12238#endif
12239 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012240{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012241 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012242 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012243 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012244 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012245 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012246 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012247
12248 ENTER();
12249
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012250 if (!dev) {
12251 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12252 return -EINVAL;
12253 }
12254
12255 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12256 if (!pAdapter) {
12257 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12258 return -EINVAL;
12259 }
12260
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012261 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012262 {
12263 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12264 "Invalid arguments");
12265 return -EINVAL;
12266 }
Hoonki Lee27511902013-03-14 18:19:06 -070012267
12268 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12269 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12270 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012272 "%s: TDLS mode is disabled OR not enabled in FW."
12273 MAC_ADDRESS_STR " Request declined.",
12274 __func__, MAC_ADDR_ARRAY(mac));
12275 return -ENOTSUPP;
12276 }
12277
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012278 if (pHddCtx->isLogpInProgress)
12279 {
12280 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12281 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012282 wlan_hdd_tdls_set_link_status(pAdapter,
12283 mac,
12284 eTDLS_LINK_IDLE,
12285 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012286 return -EBUSY;
12287 }
12288
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012289 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012290 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012291
12292 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012294 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12295 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012296 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012297 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012298 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012299
12300 /* in add station, we accept existing valid staId if there is */
12301 if ((0 == update) &&
12302 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12303 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012304 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012305 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012306 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012307 " link_status %d. staId %d. add station ignored.",
12308 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012309 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012310 return 0;
12311 }
12312 /* in change station, we accept only when staId is valid */
12313 if ((1 == update) &&
12314 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12315 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12316 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012317 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012319 "%s: " MAC_ADDRESS_STR
12320 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012321 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12322 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12323 mutex_unlock(&pHddCtx->tdls_lock);
12324 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012325 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012326 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012327
12328 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012329 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012330 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012331 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12332 "%s: " MAC_ADDRESS_STR
12333 " TDLS setup is ongoing. Request declined.",
12334 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012335 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012336 }
12337
12338 /* first to check if we reached to maximum supported TDLS peer.
12339 TODO: for now, return -EPERM looks working fine,
12340 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012341 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12342 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012343 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12345 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012346 " TDLS Max peer already connected. Request declined."
12347 " Num of peers (%d), Max allowed (%d).",
12348 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12349 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012350 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012351 }
12352 else
12353 {
12354 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012355 mutex_lock(&pHddCtx->tdls_lock);
12356 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012357 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012358 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012359 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12361 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12362 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012363 return -EPERM;
12364 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012365 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012366 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012367 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012368 wlan_hdd_tdls_set_link_status(pAdapter,
12369 mac,
12370 eTDLS_LINK_CONNECTING,
12371 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012372
Jeff Johnsond75fe012013-04-06 10:53:06 -070012373 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012374 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012375 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012377 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012378 if(StaParams->htcap_present)
12379 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012381 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012383 "ht_capa->extended_capabilities: %0x",
12384 StaParams->HTCap.extendedHtCapInfo);
12385 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012387 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012388 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012389 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012390 if(StaParams->vhtcap_present)
12391 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012393 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12394 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12395 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12396 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012397 {
12398 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012399 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012400 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012402 "[%d]: %x ", i, StaParams->supported_rates[i]);
12403 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012404 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012405 else if ((1 == update) && (NULL == StaParams))
12406 {
12407 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12408 "%s : update is true, but staParams is NULL. Error!", __func__);
12409 return -EPERM;
12410 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012411
12412 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12413
12414 if (!update)
12415 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012416 /*Before adding sta make sure that device exited from BMPS*/
12417 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12418 {
12419 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12420 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12421 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12422 if (status != VOS_STATUS_SUCCESS) {
12423 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12424 }
12425 }
12426
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012427 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012428 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012429 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012430 hddLog(VOS_TRACE_LEVEL_ERROR,
12431 FL("Failed to add TDLS peer STA. Enable Bmps"));
12432 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012433 return -EPERM;
12434 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012435 }
12436 else
12437 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012438 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012439 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012440 if (ret != eHAL_STATUS_SUCCESS) {
12441 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12442 return -EPERM;
12443 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012444 }
12445
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012446 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012447 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12448
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012449 mutex_lock(&pHddCtx->tdls_lock);
12450 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12451
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012452 if ((pTdlsPeer != NULL) &&
12453 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012454 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012455 hddLog(VOS_TRACE_LEVEL_ERROR,
12456 FL("peer link status %u"), pTdlsPeer->link_status);
12457 mutex_unlock(&pHddCtx->tdls_lock);
12458 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012459 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012460 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012461
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012462 if (ret <= 0)
12463 {
12464 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12465 "%s: timeout waiting for tdls add station indication %ld",
12466 __func__, ret);
12467 goto error;
12468 }
12469
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012470 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12471 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012472 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012473 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012474 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012475 }
12476
12477 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012478
12479error:
Atul Mittal115287b2014-07-08 13:26:33 +053012480 wlan_hdd_tdls_set_link_status(pAdapter,
12481 mac,
12482 eTDLS_LINK_IDLE,
12483 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012484 return -EPERM;
12485
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012486}
12487#endif
12488
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012489static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012490 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012491#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12492 const u8 *mac,
12493#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012494 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012495#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012496 struct station_parameters *params)
12497{
12498 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012499 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012500 hdd_context_t *pHddCtx;
12501 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012502 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012503 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012504#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012505 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012506 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012507 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012508 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012509#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012510
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012511 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012512
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012513 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012514 if ((NULL == pAdapter))
12515 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012516 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012517 "invalid adapter ");
12518 return -EINVAL;
12519 }
12520
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012521 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12522 TRACE_CODE_HDD_CHANGE_STATION,
12523 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053012524 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012525
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012526 ret = wlan_hdd_validate_context(pHddCtx);
12527 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053012528 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012529 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012530 }
12531
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012532 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12533
12534 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012535 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12537 "invalid HDD station context");
12538 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012539 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012540 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
12541
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012542 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
12543 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070012544 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012545 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070012546 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012547 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070012548 WLANTL_STA_AUTHENTICATED);
12549
Gopichand Nakkala29149562013-05-10 21:43:41 +053012550 if (status != VOS_STATUS_SUCCESS)
12551 {
12552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12553 "%s: Not able to change TL state to AUTHENTICATED", __func__);
12554 return -EINVAL;
12555 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012556 }
12557 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070012558 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
12559 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012560#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012561 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12562 StaParams.capability = params->capability;
12563 StaParams.uapsd_queues = params->uapsd_queues;
12564 StaParams.max_sp = params->max_sp;
12565
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012566 /* Convert (first channel , number of channels) tuple to
12567 * the total list of channels. This goes with the assumption
12568 * that if the first channel is < 14, then the next channels
12569 * are an incremental of 1 else an incremental of 4 till the number
12570 * of channels.
12571 */
12572 if (0 != params->supported_channels_len) {
12573 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
12574 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
12575 {
12576 int wifi_chan_index;
12577 StaParams.supported_channels[j] = params->supported_channels[i];
12578 wifi_chan_index =
12579 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
12580 no_of_channels = params->supported_channels[i+1];
12581 for(k=1; k <= no_of_channels; k++)
12582 {
12583 StaParams.supported_channels[j+1] =
12584 StaParams.supported_channels[j] + wifi_chan_index;
12585 j+=1;
12586 }
12587 }
12588 StaParams.supported_channels_len = j;
12589 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053012590 if (params->supported_oper_classes_len >
12591 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
12592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12593 "received oper classes:%d, resetting it to max supported %d",
12594 params->supported_oper_classes_len,
12595 SIR_MAC_MAX_SUPP_OPER_CLASSES);
12596 params->supported_oper_classes_len =
12597 SIR_MAC_MAX_SUPP_OPER_CLASSES;
12598 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012599 vos_mem_copy(StaParams.supported_oper_classes,
12600 params->supported_oper_classes,
12601 params->supported_oper_classes_len);
12602 StaParams.supported_oper_classes_len =
12603 params->supported_oper_classes_len;
12604
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012605 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
12606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12607 "received extn capabilities:%d, resetting it to max supported",
12608 params->ext_capab_len);
12609 params->ext_capab_len = sizeof(StaParams.extn_capability);
12610 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012611 if (0 != params->ext_capab_len)
12612 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012613 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012614
12615 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012616 {
12617 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012618 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012619 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012620
12621 StaParams.supported_rates_len = params->supported_rates_len;
12622
12623 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
12624 * The supported_rates array , for all the structures propogating till Add Sta
12625 * to the firmware has to be modified , if the supplicant (ieee80211) is
12626 * modified to send more rates.
12627 */
12628
12629 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
12630 */
12631 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
12632 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
12633
12634 if (0 != StaParams.supported_rates_len) {
12635 int i = 0;
12636 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
12637 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012639 "Supported Rates with Length %d", StaParams.supported_rates_len);
12640 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012641 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012642 "[%d]: %0x", i, StaParams.supported_rates[i]);
12643 }
12644
12645 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012646 {
12647 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012648 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012649 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012650
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012651 if (0 != params->ext_capab_len ) {
12652 /*Define A Macro : TODO Sunil*/
12653 if ((1<<4) & StaParams.extn_capability[3]) {
12654 isBufSta = 1;
12655 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012656 /* TDLS Channel Switching Support */
12657 if ((1<<6) & StaParams.extn_capability[3]) {
12658 isOffChannelSupported = 1;
12659 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012660 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012661
12662 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053012663 (params->ht_capa || params->vht_capa ||
12664 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012665 /* TDLS Peer is WME/QoS capable */
12666 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012667
12668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12669 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
12670 __func__, isQosWmmSta, StaParams.htcap_present);
12671
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012672 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
12673 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012674 isOffChannelSupported,
12675 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012676
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012677 if (VOS_STATUS_SUCCESS != status) {
12678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12679 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
12680 return -EINVAL;
12681 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012682 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
12683
12684 if (VOS_STATUS_SUCCESS != status) {
12685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12686 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
12687 return -EINVAL;
12688 }
12689 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012690#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053012691 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012692 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012693 return status;
12694}
12695
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012696#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
12697static int wlan_hdd_change_station(struct wiphy *wiphy,
12698 struct net_device *dev,
12699 const u8 *mac,
12700 struct station_parameters *params)
12701#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012702static int wlan_hdd_change_station(struct wiphy *wiphy,
12703 struct net_device *dev,
12704 u8 *mac,
12705 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012706#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012707{
12708 int ret;
12709
12710 vos_ssr_protect(__func__);
12711 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
12712 vos_ssr_unprotect(__func__);
12713
12714 return ret;
12715}
12716
Jeff Johnson295189b2012-06-20 16:38:30 -070012717/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012718 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012719 * This function is used to initialize the key information
12720 */
12721#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012722static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012723 struct net_device *ndev,
12724 u8 key_index, bool pairwise,
12725 const u8 *mac_addr,
12726 struct key_params *params
12727 )
12728#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012729static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012730 struct net_device *ndev,
12731 u8 key_index, const u8 *mac_addr,
12732 struct key_params *params
12733 )
12734#endif
12735{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012736 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012737 tCsrRoamSetKey setKey;
12738 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012739 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012740 v_U32_t roamId= 0xFF;
12741 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012742 hdd_hostapd_state_t *pHostapdState;
12743 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012744 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012745 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012746 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012747 v_MACADDR_t *peerMacAddr;
12748 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012749 uint8_t staid = HDD_MAX_STA_COUNT;
12750 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012751
12752 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012753
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012754 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12755 TRACE_CODE_HDD_CFG80211_ADD_KEY,
12756 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012757 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12758 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012759 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012760 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012761 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012762 }
12763
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012764 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12765 __func__, hdd_device_modetoString(pAdapter->device_mode),
12766 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012767
12768 if (CSR_MAX_NUM_KEY <= key_index)
12769 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012770 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012771 key_index);
12772
12773 return -EINVAL;
12774 }
12775
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012776 if (CSR_MAX_KEY_LEN < params->key_len)
12777 {
12778 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
12779 params->key_len);
12780
12781 return -EINVAL;
12782 }
12783
Jingxiang Gec438aea2017-10-26 16:44:00 +080012784 if (CSR_MAX_RSC_LEN < params->seq_len)
12785 {
12786 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
12787 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053012788
12789 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080012790 }
12791
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012792 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080012793 "%s: called with key index = %d & key length %d & seq length %d",
12794 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012795
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012796 peerMacAddr = (v_MACADDR_t *)mac_addr;
12797
Jeff Johnson295189b2012-06-20 16:38:30 -070012798 /*extract key idx, key len and key*/
12799 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12800 setKey.keyId = key_index;
12801 setKey.keyLength = params->key_len;
12802 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080012803 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012804
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012805 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012806 {
12807 case WLAN_CIPHER_SUITE_WEP40:
12808 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12809 break;
12810
12811 case WLAN_CIPHER_SUITE_WEP104:
12812 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
12813 break;
12814
12815 case WLAN_CIPHER_SUITE_TKIP:
12816 {
12817 u8 *pKey = &setKey.Key[0];
12818 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
12819
12820 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
12821
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012822 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070012823
12824 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012825 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012826 |--------------|----------|----------|
12827 <---16bytes---><--8bytes--><--8bytes-->
12828
12829 */
12830 /*Sme expects the 32 bytes key to be in the below order
12831
12832 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012833 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012834 |--------------|----------|----------|
12835 <---16bytes---><--8bytes--><--8bytes-->
12836 */
12837 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012838 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070012839
12840 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012841 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012842
12843 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012844 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012845
12846
12847 break;
12848 }
12849
12850 case WLAN_CIPHER_SUITE_CCMP:
12851 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
12852 break;
12853
12854#ifdef FEATURE_WLAN_WAPI
12855 case WLAN_CIPHER_SUITE_SMS4:
12856 {
12857 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12858 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
12859 params->key, params->key_len);
12860 return 0;
12861 }
12862#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012863
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012864#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012865 case WLAN_CIPHER_SUITE_KRK:
12866 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
12867 break;
12868#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012869
12870#ifdef WLAN_FEATURE_11W
12871 case WLAN_CIPHER_SUITE_AES_CMAC:
12872 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070012873 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070012874#endif
12875
Jeff Johnson295189b2012-06-20 16:38:30 -070012876 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012877 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012878 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012879 status = -EOPNOTSUPP;
12880 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012881 }
12882
12883 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
12884 __func__, setKey.encType);
12885
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012886 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070012887#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12888 (!pairwise)
12889#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012890 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070012891#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012892 )
12893 {
12894 /* set group key*/
12895 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12896 "%s- %d: setting Broadcast key",
12897 __func__, __LINE__);
12898 setKey.keyDirection = eSIR_RX_ONLY;
12899 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12900 }
12901 else
12902 {
12903 /* set pairwise key*/
12904 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12905 "%s- %d: setting pairwise key",
12906 __func__, __LINE__);
12907 setKey.keyDirection = eSIR_TX_RX;
12908 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012909 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012910 }
12911 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
12912 {
12913 setKey.keyDirection = eSIR_TX_RX;
12914 /*Set the group key*/
12915 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12916 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070012917
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012918 if ( 0 != status )
12919 {
12920 hddLog(VOS_TRACE_LEVEL_ERROR,
12921 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012922 status = -EINVAL;
12923 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012924 }
12925 /*Save the keys here and call sme_RoamSetKey for setting
12926 the PTK after peer joins the IBSS network*/
12927 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
12928 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012929 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012930 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053012931 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
12932 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
12933 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012934 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012935 if( pHostapdState->bssState == BSS_START )
12936 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012937 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12938 vos_status = wlan_hdd_check_ula_done(pAdapter);
12939
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012940 if (peerMacAddr && (pairwise_set_key == true))
12941 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012942
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012943 if ( vos_status != VOS_STATUS_SUCCESS )
12944 {
12945 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12946 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12947 __LINE__, vos_status );
12948
12949 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12950
12951 status = -EINVAL;
12952 goto end;
12953 }
12954
Jeff Johnson295189b2012-06-20 16:38:30 -070012955 status = WLANSAP_SetKeySta( pVosContext, &setKey);
12956
12957 if ( status != eHAL_STATUS_SUCCESS )
12958 {
12959 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12960 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12961 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012962 status = -EINVAL;
12963 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012964 }
12965 }
12966
12967 /* Saving WEP keys */
12968 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
12969 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
12970 {
12971 //Save the wep key in ap context. Issue setkey after the BSS is started.
12972 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12973 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
12974 }
12975 else
12976 {
12977 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012978 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012979 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
12980 }
12981 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012982 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
12983 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012984 {
12985 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12986 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12987
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012988#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12989 if (!pairwise)
12990#else
12991 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
12992#endif
12993 {
12994 /* set group key*/
12995 if (pHddStaCtx->roam_info.deferKeyComplete)
12996 {
12997 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12998 "%s- %d: Perform Set key Complete",
12999 __func__, __LINE__);
13000 hdd_PerformRoamSetKeyComplete(pAdapter);
13001 }
13002 }
13003
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013004 if (pairwise_set_key == true)
13005 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013006
Jeff Johnson295189b2012-06-20 16:38:30 -070013007 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
13008
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080013009 pWextState->roamProfile.Keys.defaultIndex = key_index;
13010
13011
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013012 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013013 params->key, params->key_len);
13014
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013015
Jeff Johnson295189b2012-06-20 16:38:30 -070013016 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13017
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013018 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013019 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013020 __func__, setKey.peerMac[0], setKey.peerMac[1],
13021 setKey.peerMac[2], setKey.peerMac[3],
13022 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013023 setKey.keyDirection);
13024
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013025 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053013026
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013027 if ( vos_status != VOS_STATUS_SUCCESS )
13028 {
13029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013030 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13031 __LINE__, vos_status );
13032
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013033 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013034
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013035 status = -EINVAL;
13036 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013037
13038 }
13039
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013040#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013041 /* The supplicant may attempt to set the PTK once pre-authentication
13042 is done. Save the key in the UMAC and include it in the ADD BSS
13043 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013044 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013045 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013046 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013047 hddLog(VOS_TRACE_LEVEL_INFO_MED,
13048 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013049 status = 0;
13050 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013051 }
13052 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
13053 {
13054 hddLog(VOS_TRACE_LEVEL_ERROR,
13055 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013056 status = -EINVAL;
13057 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013058 }
13059#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070013060
13061 /* issue set key request to SME*/
13062 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13063 pAdapter->sessionId, &setKey, &roamId );
13064
13065 if ( 0 != status )
13066 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013067 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013068 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
13069 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013070 status = -EINVAL;
13071 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013072 }
13073
13074
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013075 /* in case of IBSS as there was no information available about WEP keys during
13076 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070013077 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013078 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
13079 !( ( IW_AUTH_KEY_MGMT_802_1X
13080 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070013081 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
13082 )
13083 &&
13084 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
13085 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
13086 )
13087 )
13088 {
13089 setKey.keyDirection = eSIR_RX_ONLY;
13090 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13091
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013092 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013093 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013094 __func__, setKey.peerMac[0], setKey.peerMac[1],
13095 setKey.peerMac[2], setKey.peerMac[3],
13096 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013097 setKey.keyDirection);
13098
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013099 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013100 pAdapter->sessionId, &setKey, &roamId );
13101
13102 if ( 0 != status )
13103 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013104 hddLog(VOS_TRACE_LEVEL_ERROR,
13105 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013106 __func__, status);
13107 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013108 status = -EINVAL;
13109 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013110 }
13111 }
13112 }
13113
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013114 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013115 for (i = 0; i < params->seq_len; i++) {
13116 rsc_counter |= (params->seq[i] << i*8);
13117 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013118 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
13119 }
13120
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013121end:
13122 /* Need to clear any trace of key value in the memory.
13123 * Thus zero out the memory even though it is local
13124 * variable.
13125 */
13126 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013127 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013128 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013129}
13130
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013131#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13132static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13133 struct net_device *ndev,
13134 u8 key_index, bool pairwise,
13135 const u8 *mac_addr,
13136 struct key_params *params
13137 )
13138#else
13139static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13140 struct net_device *ndev,
13141 u8 key_index, const u8 *mac_addr,
13142 struct key_params *params
13143 )
13144#endif
13145{
13146 int ret;
13147 vos_ssr_protect(__func__);
13148#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13149 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
13150 mac_addr, params);
13151#else
13152 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
13153 params);
13154#endif
13155 vos_ssr_unprotect(__func__);
13156
13157 return ret;
13158}
13159
Jeff Johnson295189b2012-06-20 16:38:30 -070013160/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013161 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013162 * This function is used to get the key information
13163 */
13164#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013165static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013166 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013167 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013168 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013169 const u8 *mac_addr, void *cookie,
13170 void (*callback)(void *cookie, struct key_params*)
13171 )
13172#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013173static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013174 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013175 struct net_device *ndev,
13176 u8 key_index, const u8 *mac_addr, void *cookie,
13177 void (*callback)(void *cookie, struct key_params*)
13178 )
13179#endif
13180{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013181 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013182 hdd_wext_state_t *pWextState = NULL;
13183 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013184 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013185 hdd_context_t *pHddCtx;
13186 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013187
13188 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013189
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013190 if (NULL == pAdapter)
13191 {
13192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13193 "%s: HDD adapter is Null", __func__);
13194 return -ENODEV;
13195 }
13196
13197 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13198 ret = wlan_hdd_validate_context(pHddCtx);
13199 if (0 != ret)
13200 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013201 return ret;
13202 }
13203
13204 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13205 pRoamProfile = &(pWextState->roamProfile);
13206
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013207 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13208 __func__, hdd_device_modetoString(pAdapter->device_mode),
13209 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013210
Jeff Johnson295189b2012-06-20 16:38:30 -070013211 memset(&params, 0, sizeof(params));
13212
13213 if (CSR_MAX_NUM_KEY <= key_index)
13214 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013215 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013216 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013217 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013218
13219 switch(pRoamProfile->EncryptionType.encryptionType[0])
13220 {
13221 case eCSR_ENCRYPT_TYPE_NONE:
13222 params.cipher = IW_AUTH_CIPHER_NONE;
13223 break;
13224
13225 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13226 case eCSR_ENCRYPT_TYPE_WEP40:
13227 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13228 break;
13229
13230 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13231 case eCSR_ENCRYPT_TYPE_WEP104:
13232 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13233 break;
13234
13235 case eCSR_ENCRYPT_TYPE_TKIP:
13236 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13237 break;
13238
13239 case eCSR_ENCRYPT_TYPE_AES:
13240 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13241 break;
13242
13243 default:
13244 params.cipher = IW_AUTH_CIPHER_NONE;
13245 break;
13246 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013247
c_hpothuaaf19692014-05-17 17:01:48 +053013248 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13249 TRACE_CODE_HDD_CFG80211_GET_KEY,
13250 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013251
Jeff Johnson295189b2012-06-20 16:38:30 -070013252 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13253 params.seq_len = 0;
13254 params.seq = NULL;
13255 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13256 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013257 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013258 return 0;
13259}
13260
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013261#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13262static int wlan_hdd_cfg80211_get_key(
13263 struct wiphy *wiphy,
13264 struct net_device *ndev,
13265 u8 key_index, bool pairwise,
13266 const u8 *mac_addr, void *cookie,
13267 void (*callback)(void *cookie, struct key_params*)
13268 )
13269#else
13270static int wlan_hdd_cfg80211_get_key(
13271 struct wiphy *wiphy,
13272 struct net_device *ndev,
13273 u8 key_index, const u8 *mac_addr, void *cookie,
13274 void (*callback)(void *cookie, struct key_params*)
13275 )
13276#endif
13277{
13278 int ret;
13279
13280 vos_ssr_protect(__func__);
13281#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13282 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13283 mac_addr, cookie, callback);
13284#else
13285 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13286 callback);
13287#endif
13288 vos_ssr_unprotect(__func__);
13289
13290 return ret;
13291}
13292
Jeff Johnson295189b2012-06-20 16:38:30 -070013293/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013294 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013295 * This function is used to delete the key information
13296 */
13297#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013298static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013299 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013300 u8 key_index,
13301 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013302 const u8 *mac_addr
13303 )
13304#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013305static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013306 struct net_device *ndev,
13307 u8 key_index,
13308 const u8 *mac_addr
13309 )
13310#endif
13311{
13312 int status = 0;
13313
13314 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013315 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013316 //it is observed that this is invalidating peer
13317 //key index whenever re-key is done. This is affecting data link.
13318 //It should be ok to ignore del_key.
13319#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013320 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13321 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013322 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13323 tCsrRoamSetKey setKey;
13324 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013325
Jeff Johnson295189b2012-06-20 16:38:30 -070013326 ENTER();
13327
13328 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13329 __func__,pAdapter->device_mode);
13330
13331 if (CSR_MAX_NUM_KEY <= key_index)
13332 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013333 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013334 key_index);
13335
13336 return -EINVAL;
13337 }
13338
13339 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13340 setKey.keyId = key_index;
13341
13342 if (mac_addr)
13343 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13344 else
13345 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13346
13347 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13348
13349 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013350 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013351 )
13352 {
13353
13354 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013355 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13356 if( pHostapdState->bssState == BSS_START)
13357 {
13358 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013359
Jeff Johnson295189b2012-06-20 16:38:30 -070013360 if ( status != eHAL_STATUS_SUCCESS )
13361 {
13362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13363 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13364 __LINE__, status );
13365 }
13366 }
13367 }
13368 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013369 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013370 )
13371 {
13372 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13373
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013374 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13375
13376 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013377 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013378 __func__, setKey.peerMac[0], setKey.peerMac[1],
13379 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013380 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013381 if(pAdapter->sessionCtx.station.conn_info.connState ==
13382 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013383 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013384 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013385 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013386
Jeff Johnson295189b2012-06-20 16:38:30 -070013387 if ( 0 != status )
13388 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013389 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013390 "%s: sme_RoamSetKey failure, returned %d",
13391 __func__, status);
13392 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13393 return -EINVAL;
13394 }
13395 }
13396 }
13397#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013398 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013399 return status;
13400}
13401
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013402#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13403static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13404 struct net_device *ndev,
13405 u8 key_index,
13406 bool pairwise,
13407 const u8 *mac_addr
13408 )
13409#else
13410static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13411 struct net_device *ndev,
13412 u8 key_index,
13413 const u8 *mac_addr
13414 )
13415#endif
13416{
13417 int ret;
13418
13419 vos_ssr_protect(__func__);
13420#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13421 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
13422 mac_addr);
13423#else
13424 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
13425#endif
13426 vos_ssr_unprotect(__func__);
13427
13428 return ret;
13429}
13430
Jeff Johnson295189b2012-06-20 16:38:30 -070013431/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013432 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013433 * This function is used to set the default tx key index
13434 */
13435#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013436static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013437 struct net_device *ndev,
13438 u8 key_index,
13439 bool unicast, bool multicast)
13440#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013441static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013442 struct net_device *ndev,
13443 u8 key_index)
13444#endif
13445{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013446 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013447 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013448 hdd_wext_state_t *pWextState;
13449 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013450 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013451
13452 ENTER();
13453
Gopichand Nakkala29149562013-05-10 21:43:41 +053013454 if ((NULL == pAdapter))
13455 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013456 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013457 "invalid adapter");
13458 return -EINVAL;
13459 }
13460
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013461 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13462 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
13463 pAdapter->sessionId, key_index));
13464
Gopichand Nakkala29149562013-05-10 21:43:41 +053013465 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13466 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13467
13468 if ((NULL == pWextState) || (NULL == pHddStaCtx))
13469 {
13470 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13471 "invalid Wext state or HDD context");
13472 return -EINVAL;
13473 }
13474
Arif Hussain6d2a3322013-11-17 19:50:10 -080013475 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013476 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013477
Jeff Johnson295189b2012-06-20 16:38:30 -070013478 if (CSR_MAX_NUM_KEY <= key_index)
13479 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013480 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013481 key_index);
13482
13483 return -EINVAL;
13484 }
13485
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013486 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13487 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013488 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013489 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013490 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013491 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013492
Jeff Johnson295189b2012-06-20 16:38:30 -070013493 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070013494 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013495 )
Jeff Johnson295189b2012-06-20 16:38:30 -070013496 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013497 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080013498 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080013499#ifdef FEATURE_WLAN_WAPI
13500 (eCSR_ENCRYPT_TYPE_WPI !=
13501 pHddStaCtx->conn_info.ucEncryptionType) &&
13502#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013503 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080013504 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070013505 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013506 {
13507 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070013508 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013509
Jeff Johnson295189b2012-06-20 16:38:30 -070013510 tCsrRoamSetKey setKey;
13511 v_U32_t roamId= 0xFF;
13512 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013513
13514 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013515 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013516
Jeff Johnson295189b2012-06-20 16:38:30 -070013517 Keys->defaultIndex = (u8)key_index;
13518 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13519 setKey.keyId = key_index;
13520 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013521
13522 vos_mem_copy(&setKey.Key[0],
13523 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013524 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013525
Gopichand Nakkala29149562013-05-10 21:43:41 +053013526 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013527
13528 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070013529 &pHddStaCtx->conn_info.bssId[0],
13530 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013531
Gopichand Nakkala29149562013-05-10 21:43:41 +053013532 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
13533 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
13534 eCSR_ENCRYPT_TYPE_WEP104)
13535 {
13536 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
13537 even though ap is configured for WEP-40 encryption. In this canse the key length
13538 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
13539 type(104) and switching encryption type to 40*/
13540 pWextState->roamProfile.EncryptionType.encryptionType[0] =
13541 eCSR_ENCRYPT_TYPE_WEP40;
13542 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
13543 eCSR_ENCRYPT_TYPE_WEP40;
13544 }
13545
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013546 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013547 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013548
Jeff Johnson295189b2012-06-20 16:38:30 -070013549 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013550 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013551 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013552
Jeff Johnson295189b2012-06-20 16:38:30 -070013553 if ( 0 != status )
13554 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013555 hddLog(VOS_TRACE_LEVEL_ERROR,
13556 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013557 status);
13558 return -EINVAL;
13559 }
13560 }
13561 }
13562
13563 /* In SoftAp mode setting key direction for default mode */
13564 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
13565 {
13566 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
13567 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
13568 (eCSR_ENCRYPT_TYPE_AES !=
13569 pWextState->roamProfile.EncryptionType.encryptionType[0])
13570 )
13571 {
13572 /* Saving key direction for default key index to TX default */
13573 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13574 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
13575 }
13576 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013577 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013578 return status;
13579}
13580
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013581#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13582static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13583 struct net_device *ndev,
13584 u8 key_index,
13585 bool unicast, bool multicast)
13586#else
13587static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13588 struct net_device *ndev,
13589 u8 key_index)
13590#endif
13591{
13592 int ret;
13593 vos_ssr_protect(__func__);
13594#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13595 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
13596 multicast);
13597#else
13598 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
13599#endif
13600 vos_ssr_unprotect(__func__);
13601
13602 return ret;
13603}
13604
Jeff Johnson295189b2012-06-20 16:38:30 -070013605/*
13606 * FUNCTION: wlan_hdd_cfg80211_inform_bss
13607 * This function is used to inform the BSS details to nl80211 interface.
13608 */
13609static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
13610 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
13611{
13612 struct net_device *dev = pAdapter->dev;
13613 struct wireless_dev *wdev = dev->ieee80211_ptr;
13614 struct wiphy *wiphy = wdev->wiphy;
13615 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
13616 int chan_no;
13617 int ie_length;
13618 const char *ie;
13619 unsigned int freq;
13620 struct ieee80211_channel *chan;
13621 int rssi = 0;
13622 struct cfg80211_bss *bss = NULL;
13623
Jeff Johnson295189b2012-06-20 16:38:30 -070013624 if( NULL == pBssDesc )
13625 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013626 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013627 return bss;
13628 }
13629
13630 chan_no = pBssDesc->channelId;
13631 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
13632 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
13633
13634 if( NULL == ie )
13635 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013636 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013637 return bss;
13638 }
13639
13640#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
13641 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
13642 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013643 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070013644 }
13645 else
13646 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013647 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070013648 }
13649#else
13650 freq = ieee80211_channel_to_frequency(chan_no);
13651#endif
13652
13653 chan = __ieee80211_get_channel(wiphy, freq);
13654
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053013655 if (!chan) {
13656 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
13657 return NULL;
13658 }
13659
Abhishek Singhaee43942014-06-16 18:55:47 +053013660 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070013661
Anand N Sunkad9f80b742015-07-30 20:05:51 +053013662 return cfg80211_inform_bss(wiphy, chan,
13663#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13664 CFG80211_BSS_FTYPE_UNKNOWN,
13665#endif
13666 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013667 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070013668 pBssDesc->capabilityInfo,
13669 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053013670 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070013671}
13672
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053013673/*
13674 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
13675 * interface that BSS might have been lost.
13676 * @pAdapter: adaptor
13677 * @bssid: bssid which might have been lost
13678 *
13679 * Return: bss which is unlinked from kernel cache
13680 */
13681struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
13682 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
13683{
13684 struct net_device *dev = pAdapter->dev;
13685 struct wireless_dev *wdev = dev->ieee80211_ptr;
13686 struct wiphy *wiphy = wdev->wiphy;
13687 struct cfg80211_bss *bss = NULL;
13688
Abhishek Singh5a597e62016-12-05 15:16:30 +053013689 bss = hdd_get_bss_entry(wiphy,
13690 NULL, bssid,
13691 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053013692 if (bss == NULL) {
13693 hddLog(LOGE, FL("BSS not present"));
13694 } else {
13695 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
13696 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
13697 cfg80211_unlink_bss(wiphy, bss);
13698 }
13699 return bss;
13700}
Jeff Johnson295189b2012-06-20 16:38:30 -070013701
13702
13703/*
13704 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
13705 * This function is used to inform the BSS details to nl80211 interface.
13706 */
13707struct cfg80211_bss*
13708wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
13709 tSirBssDescription *bss_desc
13710 )
13711{
13712 /*
13713 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
13714 already exists in bss data base of cfg80211 for that particular BSS ID.
13715 Using cfg80211_inform_bss_frame to update the bss entry instead of
13716 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
13717 now there is no possibility to get the mgmt(probe response) frame from PE,
13718 converting bss_desc to ieee80211_mgmt(probe response) and passing to
13719 cfg80211_inform_bss_frame.
13720 */
13721 struct net_device *dev = pAdapter->dev;
13722 struct wireless_dev *wdev = dev->ieee80211_ptr;
13723 struct wiphy *wiphy = wdev->wiphy;
13724 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013725#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13726 qcom_ie_age *qie_age = NULL;
13727 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
13728#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013729 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013730#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013731 const char *ie =
13732 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
13733 unsigned int freq;
13734 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013735 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013736 struct cfg80211_bss *bss_status = NULL;
13737 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
13738 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070013739 hdd_context_t *pHddCtx;
13740 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070013741#ifdef WLAN_OPEN_SOURCE
13742 struct timespec ts;
13743#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013744
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013745
Wilson Yangf80a0542013-10-07 13:02:37 -070013746 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13747 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070013748 if (0 != status)
13749 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013750 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013751 }
13752
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013753 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070013754 if (!mgmt)
13755 {
13756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13757 "%s: memory allocation failed ", __func__);
13758 return NULL;
13759 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013760
Jeff Johnson295189b2012-06-20 16:38:30 -070013761 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013762
13763#ifdef WLAN_OPEN_SOURCE
13764 /* Android does not want the timestamp from the frame.
13765 Instead it wants a monotonic increasing value */
13766 get_monotonic_boottime(&ts);
13767 mgmt->u.probe_resp.timestamp =
13768 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
13769#else
13770 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070013771 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
13772 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070013773
13774#endif
13775
Jeff Johnson295189b2012-06-20 16:38:30 -070013776 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
13777 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013778
13779#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13780 /* GPS Requirement: need age ie per entry. Using vendor specific. */
13781 /* Assuming this is the last IE, copy at the end */
13782 ie_length -=sizeof(qcom_ie_age);
13783 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
13784 qie_age->element_id = QCOM_VENDOR_IE_ID;
13785 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
13786 qie_age->oui_1 = QCOM_OUI1;
13787 qie_age->oui_2 = QCOM_OUI2;
13788 qie_age->oui_3 = QCOM_OUI3;
13789 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053013790 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
13791 * bss related timestamp is in units of ms. Due to this when scan results
13792 * are sent to lowi the scan age is high.To address this, send age in units
13793 * of 1/10 ms.
13794 */
13795 qie_age->age = (vos_timer_get_system_time() -
13796 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013797#endif
13798
Jeff Johnson295189b2012-06-20 16:38:30 -070013799 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053013800 if (bss_desc->fProbeRsp)
13801 {
13802 mgmt->frame_control |=
13803 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
13804 }
13805 else
13806 {
13807 mgmt->frame_control |=
13808 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
13809 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013810
13811#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013812 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013813 (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070013814 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013815 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070013816 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013817 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013818 (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070013819
13820 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013821 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070013822 }
13823 else
13824 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013825 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
13826 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070013827 kfree(mgmt);
13828 return NULL;
13829 }
13830#else
13831 freq = ieee80211_channel_to_frequency(chan_no);
13832#endif
13833 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013834 /*when the band is changed on the fly using the GUI, three things are done
13835 * 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)
13836 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
13837 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
13838 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
13839 * and discards the channels correponding to previous band and calls back with zero bss results.
13840 * 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
13841 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
13842 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
13843 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
13844 * So drop the bss and continue to next bss.
13845 */
13846 if(chan == NULL)
13847 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053013848 hddLog(VOS_TRACE_LEVEL_ERROR,
13849 FL("chan pointer is NULL, chan_no: %d freq: %d"),
13850 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070013851 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013852 return NULL;
13853 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053013854 /*To keep the rssi icon of the connected AP in the scan window
13855 *and the rssi icon of the wireless networks in sync
13856 * */
13857 if (( eConnectionState_Associated ==
13858 pAdapter->sessionCtx.station.conn_info.connState ) &&
13859 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
13860 pAdapter->sessionCtx.station.conn_info.bssId,
13861 WNI_CFG_BSSID_LEN)) &&
13862 (pHddCtx->hdd_wlan_suspended == FALSE))
13863 {
13864 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
13865 rssi = (pAdapter->rssi * 100);
13866 }
13867 else
13868 {
13869 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
13870 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013871
Nirav Shah20ac06f2013-12-12 18:14:06 +053013872 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053013873 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
13874 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053013875
Jeff Johnson295189b2012-06-20 16:38:30 -070013876 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
13877 frame_len, rssi, GFP_KERNEL);
13878 kfree(mgmt);
13879 return bss_status;
13880}
13881
13882/*
13883 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
13884 * This function is used to update the BSS data base of CFG8011
13885 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013886struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013887 tCsrRoamInfo *pRoamInfo
13888 )
13889{
13890 tCsrRoamConnectedProfile roamProfile;
13891 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13892 struct cfg80211_bss *bss = NULL;
13893
13894 ENTER();
13895
13896 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
13897 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
13898
13899 if (NULL != roamProfile.pBssDesc)
13900 {
Girish Gowlif4b68022014-08-28 23:18:57 +053013901 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13902 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070013903
13904 if (NULL == bss)
13905 {
13906 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
13907 __func__);
13908 }
13909
13910 sme_RoamFreeConnectProfile(hHal, &roamProfile);
13911 }
13912 else
13913 {
13914 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
13915 __func__);
13916 }
13917 return bss;
13918}
13919
13920/*
13921 * FUNCTION: wlan_hdd_cfg80211_update_bss
13922 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013923static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
13924 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070013925 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013926{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013927 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013928 tCsrScanResultInfo *pScanResult;
13929 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013930 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013931 tScanResultHandle pResult;
13932 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013933 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013934 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013935 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013936
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013937 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13938 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
13939 NO_SESSION, pAdapter->sessionId));
13940
Wilson Yangf80a0542013-10-07 13:02:37 -070013941 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013942 ret = wlan_hdd_validate_context(pHddCtx);
13943 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070013944 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013945 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070013946 }
13947
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013948 if (pAdapter->request != NULL)
13949 {
13950 if ((pAdapter->request->n_ssids == 1)
13951 && (pAdapter->request->ssids != NULL)
13952 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
13953 is_p2p_scan = true;
13954 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013955 /*
13956 * start getting scan results and populate cgf80211 BSS database
13957 */
13958 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
13959
13960 /* no scan results */
13961 if (NULL == pResult)
13962 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013963 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
13964 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013965 wlan_hdd_get_frame_logs(pAdapter,
13966 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070013967 return status;
13968 }
13969
13970 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
13971
13972 while (pScanResult)
13973 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013974 /*
13975 * cfg80211_inform_bss() is not updating ie field of bss entry, if
13976 * entry already exists in bss data base of cfg80211 for that
13977 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
13978 * bss entry instead of cfg80211_inform_bss, But this call expects
13979 * mgmt packet as input. As of now there is no possibility to get
13980 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070013981 * ieee80211_mgmt(probe response) and passing to c
13982 * fg80211_inform_bss_frame.
13983 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013984 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
13985 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
13986 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013987 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13988 continue; //Skip the non p2p bss entries
13989 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013990 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13991 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013992
Jeff Johnson295189b2012-06-20 16:38:30 -070013993
13994 if (NULL == bss_status)
13995 {
13996 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013997 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013998 }
13999 else
14000 {
Yue Maf49ba872013-08-19 12:04:25 -070014001 cfg80211_put_bss(
14002#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
14003 wiphy,
14004#endif
14005 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070014006 }
14007
14008 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14009 }
14010
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014011 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014012 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014013 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014014}
14015
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014016void
14017hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
14018{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014019 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080014020 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014021} /****** end hddPrintMacAddr() ******/
14022
14023void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014024hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014025{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014026 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014027 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014028 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
14029 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
14030 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014031} /****** end hddPrintPmkId() ******/
14032
14033//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
14034//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
14035
14036//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
14037//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
14038
14039#define dump_bssid(bssid) \
14040 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014041 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
14042 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014043 }
14044
14045#define dump_pmkid(pMac, pmkid) \
14046 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014047 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
14048 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014049 }
14050
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070014051#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014052/*
14053 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
14054 * This function is used to notify the supplicant of a new PMKSA candidate.
14055 */
14056int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014057 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014058 int index, bool preauth )
14059{
Jeff Johnsone7245742012-09-05 17:12:55 -070014060#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014061 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014062 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014063
14064 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070014065 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014066
14067 if( NULL == pRoamInfo )
14068 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014069 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014070 return -EINVAL;
14071 }
14072
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014073 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
14074 {
14075 dump_bssid(pRoamInfo->bssid);
14076 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014077 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014078 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014079#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014080 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014081}
14082#endif //FEATURE_WLAN_LFR
14083
Yue Maef608272013-04-08 23:09:17 -070014084#ifdef FEATURE_WLAN_LFR_METRICS
14085/*
14086 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
14087 * 802.11r/LFR metrics reporting function to report preauth initiation
14088 *
14089 */
14090#define MAX_LFR_METRICS_EVENT_LENGTH 100
14091VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
14092 tCsrRoamInfo *pRoamInfo)
14093{
14094 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14095 union iwreq_data wrqu;
14096
14097 ENTER();
14098
14099 if (NULL == pAdapter)
14100 {
14101 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14102 return VOS_STATUS_E_FAILURE;
14103 }
14104
14105 /* create the event */
14106 memset(&wrqu, 0, sizeof(wrqu));
14107 memset(metrics_notification, 0, sizeof(metrics_notification));
14108
14109 wrqu.data.pointer = metrics_notification;
14110 wrqu.data.length = scnprintf(metrics_notification,
14111 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
14112 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14113
14114 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14115
14116 EXIT();
14117
14118 return VOS_STATUS_SUCCESS;
14119}
14120
14121/*
14122 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
14123 * 802.11r/LFR metrics reporting function to report preauth completion
14124 * or failure
14125 */
14126VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
14127 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
14128{
14129 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14130 union iwreq_data wrqu;
14131
14132 ENTER();
14133
14134 if (NULL == pAdapter)
14135 {
14136 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14137 return VOS_STATUS_E_FAILURE;
14138 }
14139
14140 /* create the event */
14141 memset(&wrqu, 0, sizeof(wrqu));
14142 memset(metrics_notification, 0, sizeof(metrics_notification));
14143
14144 scnprintf(metrics_notification, sizeof(metrics_notification),
14145 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
14146 MAC_ADDR_ARRAY(pRoamInfo->bssid));
14147
14148 if (1 == preauth_status)
14149 strncat(metrics_notification, " TRUE", 5);
14150 else
14151 strncat(metrics_notification, " FALSE", 6);
14152
14153 wrqu.data.pointer = metrics_notification;
14154 wrqu.data.length = strlen(metrics_notification);
14155
14156 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14157
14158 EXIT();
14159
14160 return VOS_STATUS_SUCCESS;
14161}
14162
14163/*
14164 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
14165 * 802.11r/LFR metrics reporting function to report handover initiation
14166 *
14167 */
14168VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
14169 tCsrRoamInfo *pRoamInfo)
14170{
14171 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14172 union iwreq_data wrqu;
14173
14174 ENTER();
14175
14176 if (NULL == pAdapter)
14177 {
14178 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14179 return VOS_STATUS_E_FAILURE;
14180 }
14181
14182 /* create the event */
14183 memset(&wrqu, 0, sizeof(wrqu));
14184 memset(metrics_notification, 0, sizeof(metrics_notification));
14185
14186 wrqu.data.pointer = metrics_notification;
14187 wrqu.data.length = scnprintf(metrics_notification,
14188 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14189 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14190
14191 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14192
14193 EXIT();
14194
14195 return VOS_STATUS_SUCCESS;
14196}
14197#endif
14198
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014199
14200/**
14201 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14202 * @scan_req: scan request to be checked
14203 *
14204 * Return: true or false
14205 */
14206#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14207static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14208 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014209 *scan_req, hdd_context_t
14210 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014211{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014212 if (!scan_req || !scan_req->wiphy ||
14213 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014214 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14215 return false;
14216 }
14217 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14218 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14219 return false;
14220 }
14221 return true;
14222}
14223#else
14224static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14225 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014226 *scan_req, hdd_context_t
14227 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014228{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014229 if (!scan_req || !scan_req->wiphy ||
14230 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014231 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14232 return false;
14233 }
14234 return true;
14235}
14236#endif
14237
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014238#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
14239/**
14240 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14241 * @adapter: Pointer to the adapter
14242 * @req : Scan request
14243 * @aborted : true scan aborted false scan success
14244 *
14245 * This function notifies scan done to cfg80211
14246 *
14247 * Return: none
14248 */
14249static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14250 struct cfg80211_scan_request *req,
14251 bool aborted)
14252{
14253 struct cfg80211_scan_info info = {
14254 .aborted = aborted
14255 };
14256
14257 if (adapter->dev->flags & IFF_UP)
14258 cfg80211_scan_done(req, &info);
14259 else
14260 hddLog(LOGW,
14261 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14262}
14263#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14264/**
14265 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14266 * @adapter: Pointer to the adapter
14267 * @req : Scan request
14268 * @aborted : true scan aborted false scan success
14269 *
14270 * This function notifies scan done to cfg80211
14271 *
14272 * Return: none
14273 */
14274static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14275 struct cfg80211_scan_request *req,
14276 bool aborted)
14277{
14278 if (adapter->dev->flags & IFF_UP)
14279 cfg80211_scan_done(req, aborted);
14280 else
14281 hddLog(LOGW,
14282 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14283}
14284#else
14285/**
14286 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14287 * @adapter: Pointer to the adapter
14288 * @req : Scan request
14289 * @aborted : true scan aborted false scan success
14290 *
14291 * This function notifies scan done to cfg80211
14292 *
14293 * Return: none
14294 */
14295static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14296 struct cfg80211_scan_request *req,
14297 bool aborted)
14298{
14299 cfg80211_scan_done(req, aborted);
14300}
14301#endif
14302
Mukul Sharmab392b642017-08-17 17:45:29 +053014303#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014304/*
14305 * FUNCTION: hdd_cfg80211_scan_done_callback
14306 * scanning callback function, called after finishing scan
14307 *
14308 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014309static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014310 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14311{
14312 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014313 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014314 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014315 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014316 struct cfg80211_scan_request *req = NULL;
14317 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014318 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014319 long waitRet = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014320 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014321
14322 ENTER();
14323
c_manjee1b4ab9a2016-10-26 11:36:55 +053014324 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14325 !pAdapter->dev) {
14326 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14327 return 0;
14328 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014329 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014330 if (NULL == pHddCtx) {
14331 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014332 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014333 }
14334
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014335#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014336 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014337 {
14338 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014339 }
14340#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014341 pScanInfo = &pHddCtx->scan_info;
14342
Jeff Johnson295189b2012-06-20 16:38:30 -070014343 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014344 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014345 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014346 __func__, halHandle, pContext, (int) scanId, (int) status);
14347
Kiet Lamac06e2c2013-10-23 16:25:07 +053014348 pScanInfo->mScanPendingCounter = 0;
14349
Jeff Johnson295189b2012-06-20 16:38:30 -070014350 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014351 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014352 &pScanInfo->scan_req_completion_event,
14353 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014354 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014355 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014356 hddLog(VOS_TRACE_LEVEL_ERROR,
14357 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014358 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014359 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014360 }
14361
Yue Maef608272013-04-08 23:09:17 -070014362 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014363 {
14364 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014365 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014366 }
14367
14368 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014369 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014370 {
14371 hddLog(VOS_TRACE_LEVEL_INFO,
14372 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014373 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014374 (int) scanId);
14375 }
14376
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014377#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014378 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014379#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014380 {
14381 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14382 pAdapter);
14383 if (0 > ret)
14384 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014385 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014386
Jeff Johnson295189b2012-06-20 16:38:30 -070014387 /* If any client wait scan result through WEXT
14388 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014389 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014390 {
14391 /* The other scan request waiting for current scan finish
14392 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014393 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014394 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014395 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014396 }
14397 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014398 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014399 {
14400 struct net_device *dev = pAdapter->dev;
14401 union iwreq_data wrqu;
14402 int we_event;
14403 char *msg;
14404
14405 memset(&wrqu, '\0', sizeof(wrqu));
14406 we_event = SIOCGIWSCAN;
14407 msg = NULL;
14408 wireless_send_event(dev, we_event, &wrqu, msg);
14409 }
14410 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014411 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014412
14413 /* Get the Scan Req */
14414 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014415 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014416
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014417 /* Scan is no longer pending */
14418 pScanInfo->mScanPending = VOS_FALSE;
14419
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014420 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070014421 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014422#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
14423 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053014424 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014425#endif
14426
14427 if (pAdapter->dev) {
14428 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
14429 pAdapter->dev->name);
14430 }
mukul sharmae7041822015-12-03 15:09:21 +053014431 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070014432 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014433 }
14434
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014435 /* last_scan_timestamp is used to decide if new scan
14436 * is needed or not on station interface. If last station
14437 * scan time and new station scan time is less then
14438 * last_scan_timestamp ; driver will return cached scan.
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014439 * Also only last_scan_timestamp is updated here last_scan_channellist
14440 * is updated on receiving scan request itself to make sure kernel
14441 * allocated scan request(scan_req) object is not dereferenced here,
14442 * because interface down, where kernel frees scan_req, may happen any
14443 * time while driver is processing scan_done_callback. So it's better
14444 * not to access scan_req in this routine.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014445 */
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014446 if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
14447 if (status == eCSR_SCAN_SUCCESS)
14448 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
14449 else {
14450 vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
14451 sizeof(pHddCtx->scan_info.last_scan_channelList));
14452 pHddCtx->scan_info.last_scan_numChannels = 0;
14453 pScanInfo->last_scan_timestamp = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014454 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014455 }
14456
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070014457 /*
14458 * cfg80211_scan_done informing NL80211 about completion
14459 * of scanning
14460 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014461 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
14462 {
14463 aborted = true;
14464 }
mukul sharmae7041822015-12-03 15:09:21 +053014465
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014466#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014467 if (NET_DEV_IS_IFF_UP(pAdapter) &&
14468 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014469#endif
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014470 hdd_cfg80211_scan_done(pAdapter, req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053014471
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080014472 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070014473
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014474allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014475 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
14476 ) && (pHddCtx->spoofMacAddr.isEnabled
14477 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053014478 /* Generate new random mac addr for next scan */
14479 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053014480
14481 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
14482 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053014483 }
14484
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014485 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014486 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014487
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014488 /* Acquire wakelock to handle the case where APP's tries to suspend
14489 * immediatly after the driver gets connect request(i.e after scan)
14490 * from supplicant, this result in app's is suspending and not able
14491 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014492 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014493
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014494#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014495 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014496#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014497#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014498 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014499#endif
14500
Jeff Johnson295189b2012-06-20 16:38:30 -070014501 EXIT();
14502 return 0;
14503}
14504
14505/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053014506 * FUNCTION: hdd_isConnectionInProgress
14507 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014508 *
14509 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014510v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
14511 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014512{
14513 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14514 hdd_station_ctx_t *pHddStaCtx = NULL;
14515 hdd_adapter_t *pAdapter = NULL;
14516 VOS_STATUS status = 0;
14517 v_U8_t staId = 0;
14518 v_U8_t *staMac = NULL;
14519
14520 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14521
14522 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14523 {
14524 pAdapter = pAdapterNode->pAdapter;
14525
14526 if( pAdapter )
14527 {
14528 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014529 "%s: Adapter with device mode %s (%d) exists",
14530 __func__, hdd_device_modetoString(pAdapter->device_mode),
14531 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014532 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053014533 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14534 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
14535 (eConnectionState_Connecting ==
14536 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14537 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014538 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014539 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053014540 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014541 if (session_id && reason)
14542 {
14543 *session_id = pAdapter->sessionId;
14544 *reason = eHDD_CONNECTION_IN_PROGRESS;
14545 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014546 return VOS_TRUE;
14547 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014548 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053014549 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014550 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014551 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014552 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014553 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014554 if (session_id && reason)
14555 {
14556 *session_id = pAdapter->sessionId;
14557 *reason = eHDD_REASSOC_IN_PROGRESS;
14558 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014559 return VOS_TRUE;
14560 }
14561 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014562 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14563 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014564 {
14565 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14566 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014567 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014568 {
14569 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014570 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014571 "%s: client " MAC_ADDRESS_STR
14572 " is in the middle of WPS/EAPOL exchange.", __func__,
14573 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014574 if (session_id && reason)
14575 {
14576 *session_id = pAdapter->sessionId;
14577 *reason = eHDD_EAPOL_IN_PROGRESS;
14578 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014579 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014580 }
14581 }
14582 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
14583 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
14584 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014585 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14586 ptSapContext pSapCtx = NULL;
14587 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14588 if(pSapCtx == NULL){
14589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14590 FL("psapCtx is NULL"));
14591 return VOS_FALSE;
14592 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014593 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
14594 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014595 if ((pSapCtx->aStaInfo[staId].isUsed) &&
14596 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014597 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014598 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014599
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014600 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014601 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
14602 "middle of WPS/EAPOL exchange.", __func__,
14603 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014604 if (session_id && reason)
14605 {
14606 *session_id = pAdapter->sessionId;
14607 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
14608 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014609 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014610 }
14611 }
14612 }
14613 }
14614 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14615 pAdapterNode = pNext;
14616 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014617 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014618}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014619
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014620/**
14621 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
14622 * to the Scan request
14623 * @scanRequest: Pointer to the csr scan request
14624 * @request: Pointer to the scan request from supplicant
14625 *
14626 * Return: None
14627 */
14628#ifdef CFG80211_SCAN_BSSID
14629static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14630 struct cfg80211_scan_request *request)
14631{
14632 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
14633}
14634#else
14635static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14636 struct cfg80211_scan_request *request)
14637{
14638}
14639#endif
14640
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014641/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014642 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070014643 * this scan respond to scan trigger and update cfg80211 scan database
14644 * later, scan dump command can be used to recieve scan results
14645 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014646int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014647#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14648 struct net_device *dev,
14649#endif
14650 struct cfg80211_scan_request *request)
14651{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014652 hdd_adapter_t *pAdapter = NULL;
14653 hdd_context_t *pHddCtx = NULL;
14654 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014655 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014656 tCsrScanRequest scanRequest;
14657 tANI_U8 *channelList = NULL, i;
14658 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014659 int status;
14660 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014661 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014662 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053014663 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014664 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014665 v_U8_t curr_session_id;
14666 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070014667
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014668#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
14669 struct net_device *dev = NULL;
14670 if (NULL == request)
14671 {
14672 hddLog(VOS_TRACE_LEVEL_ERROR,
14673 "%s: scan req param null", __func__);
14674 return -EINVAL;
14675 }
14676 dev = request->wdev->netdev;
14677#endif
14678
14679 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
14680 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
14681 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14682
Jeff Johnson295189b2012-06-20 16:38:30 -070014683 ENTER();
14684
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014685 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
14686 __func__, hdd_device_modetoString(pAdapter->device_mode),
14687 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014688
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014689 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014690 if (0 != status)
14691 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014692 return status;
14693 }
14694
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014695 if (NULL == pwextBuf)
14696 {
14697 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
14698 __func__);
14699 return -EIO;
14700 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014701 cfg_param = pHddCtx->cfg_ini;
14702 pScanInfo = &pHddCtx->scan_info;
14703
Jeff Johnson295189b2012-06-20 16:38:30 -070014704#ifdef WLAN_BTAMP_FEATURE
14705 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014706 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070014707 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080014708 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014709 "%s: No scanning when AMP is on", __func__);
14710 return -EOPNOTSUPP;
14711 }
14712#endif
14713 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014714 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014715 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014716 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014717 "%s: Not scanning on device_mode = %s (%d)",
14718 __func__, hdd_device_modetoString(pAdapter->device_mode),
14719 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014720 return -EOPNOTSUPP;
14721 }
14722
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053014723 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
14724 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
14725 return -EOPNOTSUPP;
14726 }
14727
Jeff Johnson295189b2012-06-20 16:38:30 -070014728 if (TRUE == pScanInfo->mScanPending)
14729 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053014730 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
14731 {
14732 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
14733 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014734 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070014735 }
14736
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053014737 // Don't allow scan if PNO scan is going on.
14738 if (pHddCtx->isPnoEnable)
14739 {
14740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14741 FL("pno scan in progress"));
14742 return -EBUSY;
14743 }
14744
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014745 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070014746 //Channel and action frame is pending
14747 //Otherwise Cancel Remain On Channel and allow Scan
14748 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014749 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070014750 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053014751 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070014752 return -EBUSY;
14753 }
14754
Jeff Johnson295189b2012-06-20 16:38:30 -070014755 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
14756 {
14757 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080014758 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014759 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014760 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014761 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
14762 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014763 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014764 "%s: MAX TM Level Scan not allowed", __func__);
14765 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014766 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070014767 }
14768 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
14769
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014770 /* Check if scan is allowed at this point of time.
14771 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053014772 if (TRUE == pHddCtx->btCoexModeSet)
14773 {
14774 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14775 FL("BTCoex Mode operation in progress"));
14776 return -EBUSY;
14777 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014778 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014779 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014780
14781 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
14782 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
14783 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014784 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
14785 pHddCtx->last_scan_reject_reason != curr_reason ||
14786 !pHddCtx->last_scan_reject_timestamp)
14787 {
14788 pHddCtx->last_scan_reject_session_id = curr_session_id;
14789 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053014790 pHddCtx->last_scan_reject_timestamp =
14791 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014792 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053014793 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053014794 else
14795 {
14796 pHddCtx->scan_reject_cnt++;
14797
Abhishek Singhe4b12562017-06-20 16:53:39 +053014798 if ((pHddCtx->scan_reject_cnt >=
14799 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053014800 vos_system_time_after(jiffies_to_msecs(jiffies),
14801 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014802 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014803 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
14804 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
14805 vos_system_time_after(jiffies_to_msecs(jiffies),
14806 pHddCtx->last_scan_reject_timestamp));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014807 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014808 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014809 if (pHddCtx->cfg_ini->enableFatalEvent)
14810 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
14811 WLAN_LOG_INDICATOR_HOST_DRIVER,
14812 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
14813 FALSE, FALSE);
14814 else
14815 {
14816 hddLog(LOGE, FL("Triggering SSR"));
14817 vos_wlanRestart();
14818 }
14819 }
14820 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014821 return -EBUSY;
14822 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014823 pHddCtx->last_scan_reject_timestamp = 0;
14824 pHddCtx->last_scan_reject_session_id = 0xFF;
14825 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014826 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014827
Jeff Johnson295189b2012-06-20 16:38:30 -070014828 vos_mem_zero( &scanRequest, sizeof(scanRequest));
14829
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014830 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
14831 * Becasue of this, driver is assuming that this is not wildcard scan and so
14832 * is not aging out the scan results.
14833 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053014834 if ((request->ssids) && (request->n_ssids == 1) &&
14835 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014836 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014837 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014838
14839 if ((request->ssids) && (0 < request->n_ssids))
14840 {
14841 tCsrSSIDInfo *SsidInfo;
14842 int j;
14843 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
14844 /* Allocate num_ssid tCsrSSIDInfo structure */
14845 SsidInfo = scanRequest.SSIDs.SSIDList =
14846 ( tCsrSSIDInfo *)vos_mem_malloc(
14847 request->n_ssids*sizeof(tCsrSSIDInfo));
14848
14849 if(NULL == scanRequest.SSIDs.SSIDList)
14850 {
14851 hddLog(VOS_TRACE_LEVEL_ERROR,
14852 "%s: memory alloc failed SSIDInfo buffer", __func__);
14853 return -ENOMEM;
14854 }
14855
14856 /* copy all the ssid's and their length */
14857 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
14858 {
14859 /* get the ssid length */
14860 SsidInfo->SSID.length = request->ssids[j].ssid_len;
14861 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
14862 SsidInfo->SSID.length);
14863 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
14864 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
14865 j, SsidInfo->SSID.ssId);
14866 }
14867 /* set the scan type to active */
14868 scanRequest.scanType = eSIR_ACTIVE_SCAN;
14869 }
14870 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014871 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014872 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14873 TRACE_CODE_HDD_CFG80211_SCAN,
14874 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070014875 /* set the scan type to active */
14876 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070014877 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014878 else
14879 {
14880 /*Set the scan type to default type, in this case it is ACTIVE*/
14881 scanRequest.scanType = pScanInfo->scan_mode;
14882 }
14883 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
14884 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070014885
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014886 csr_scan_request_assign_bssid(&scanRequest, request);
14887
Jeff Johnson295189b2012-06-20 16:38:30 -070014888 /* set BSSType to default type */
14889 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
14890
14891 /*TODO: scan the requested channels only*/
14892
14893 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014894 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070014895 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014896 hddLog(VOS_TRACE_LEVEL_WARN,
14897 "No of Scan Channels exceeded limit: %d", request->n_channels);
14898 request->n_channels = MAX_CHANNEL;
14899 }
14900
14901 hddLog(VOS_TRACE_LEVEL_INFO,
14902 "No of Scan Channels: %d", request->n_channels);
14903
14904
14905 if( request->n_channels )
14906 {
14907 char chList [(request->n_channels*5)+1];
14908 int len;
14909 channelList = vos_mem_malloc( request->n_channels );
14910 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053014911 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014912 hddLog(VOS_TRACE_LEVEL_ERROR,
14913 "%s: memory alloc failed channelList", __func__);
14914 status = -ENOMEM;
14915 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053014916 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014917
14918 for( i = 0, len = 0; i < request->n_channels ; i++ )
14919 {
14920 channelList[i] = request->channels[i]->hw_value;
14921 len += snprintf(chList+len, 5, "%d ", channelList[i]);
14922 }
14923
Nirav Shah20ac06f2013-12-12 18:14:06 +053014924 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014925 "Channel-List: %s ", chList);
14926 }
c_hpothu53512302014-04-15 18:49:53 +053014927
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014928 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
14929 scanRequest.ChannelInfo.ChannelList = channelList;
14930
14931 /* set requestType to full scan */
14932 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
14933
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014934 /* if there is back to back scan happening in driver with in
14935 * nDeferScanTimeInterval interval driver should defer new scan request
14936 * and should provide last cached scan results instead of new channel list.
14937 * This rule is not applicable if scan is p2p scan.
14938 * This condition will work only in case when last request no of channels
14939 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053014940 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053014941 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014942 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014943
Sushant Kaushik86592172015-04-27 16:35:03 +053014944 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
14945 /* if wps ie is NULL , then only defer scan */
14946 if ( pWpsIe == NULL &&
14947 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053014948 {
14949 if ( pScanInfo->last_scan_timestamp !=0 &&
14950 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
14951 {
14952 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
14953 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
14954 vos_mem_compare(pScanInfo->last_scan_channelList,
14955 channelList, pScanInfo->last_scan_numChannels))
14956 {
14957 hddLog(VOS_TRACE_LEVEL_WARN,
14958 " New and old station scan time differ is less then %u",
14959 pHddCtx->cfg_ini->nDeferScanTimeInterval);
14960
14961 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014962 pAdapter);
14963
Agarwal Ashish57e84372014-12-05 18:26:53 +053014964 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014965 "Return old cached scan as all channels and no of channels are same");
14966
Agarwal Ashish57e84372014-12-05 18:26:53 +053014967 if (0 > ret)
14968 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014969
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014970 hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014971
14972 status = eHAL_STATUS_SUCCESS;
14973 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053014974 }
14975 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014976 }
14977
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014978 /* Flush the scan results(only p2p beacons) for STA scan and P2P
14979 * search (Flush on both full scan and social scan but not on single
14980 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
14981 */
14982
14983 /* Supplicant does single channel scan after 8-way handshake
14984 * and in that case driver shoudnt flush scan results. If
14985 * driver flushes the scan results here and unfortunately if
14986 * the AP doesnt respond to our probe req then association
14987 * fails which is not desired
14988 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014989 if ((request->n_ssids == 1)
14990 && (request->ssids != NULL)
14991 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
14992 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014993
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014994 if( is_p2p_scan ||
14995 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014996 {
14997 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
14998 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
14999 pAdapter->sessionId );
15000 }
15001
15002 if( request->ie_len )
15003 {
15004 /* save this for future association (join requires this) */
15005 /*TODO: Array needs to be converted to dynamic allocation,
15006 * as multiple ie.s can be sent in cfg80211_scan_request structure
15007 * CR 597966
15008 */
15009 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
15010 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
15011 pScanInfo->scanAddIE.length = request->ie_len;
15012
15013 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15014 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15015 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015016 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015017 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070015018 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015019 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
15020 memcpy( pwextBuf->roamProfile.addIEScan,
15021 request->ie, request->ie_len);
15022 }
15023 else
15024 {
15025 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
15026 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070015027 }
15028
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015029 }
15030 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
15031 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
15032
15033 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
15034 request->ie_len);
15035 if (pP2pIe != NULL)
15036 {
15037#ifdef WLAN_FEATURE_P2P_DEBUG
15038 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
15039 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
15040 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053015041 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015042 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
15043 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15044 "Go nego completed to Connection is started");
15045 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15046 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053015047 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015048 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
15049 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015050 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015051 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
15052 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15053 "Disconnected state to Connection is started");
15054 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15055 "for 4way Handshake");
15056 }
15057#endif
15058
15059 /* no_cck will be set during p2p find to disable 11b rates */
15060 if(TRUE == request->no_cck)
15061 {
15062 hddLog(VOS_TRACE_LEVEL_INFO,
15063 "%s: This is a P2P Search", __func__);
15064 scanRequest.p2pSearch = 1;
15065
15066 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053015067 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015068 /* set requestType to P2P Discovery */
15069 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
15070 }
15071
15072 /*
15073 Skip Dfs Channel in case of P2P Search
15074 if it is set in ini file
15075 */
15076 if(cfg_param->skipDfsChnlInP2pSearch)
15077 {
15078 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015079 }
15080 else
15081 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015082 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015083 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015084
Agarwal Ashish4f616132013-12-30 23:32:50 +053015085 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015086 }
15087 }
15088
15089 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
15090
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015091#ifdef FEATURE_WLAN_TDLS
15092 /* if tdls disagree scan right now, return immediately.
15093 tdls will schedule the scan when scan is allowed. (return SUCCESS)
15094 or will reject the scan if any TDLS is in progress. (return -EBUSY)
15095 */
15096 status = wlan_hdd_tdls_scan_callback (pAdapter,
15097 wiphy,
15098#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15099 dev,
15100#endif
15101 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015102 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015103 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053015104 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015105 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
15106 "scan rejected %d", __func__, status);
15107 else
15108 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
15109 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015110 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053015111 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015112 }
15113#endif
15114
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015115 /* acquire the wakelock to avoid the apps suspend during the scan. To
15116 * address the following issues.
15117 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
15118 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
15119 * for long time, this result in apps running at full power for long time.
15120 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
15121 * be stuck in full power because of resume BMPS
15122 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015123 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015124
Nirav Shah20ac06f2013-12-12 18:14:06 +053015125 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
15126 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015127 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
15128 scanRequest.requestType, scanRequest.scanType,
15129 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053015130 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
15131
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015132 if (pHddCtx->spoofMacAddr.isEnabled &&
15133 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053015134 {
15135 hddLog(VOS_TRACE_LEVEL_INFO,
15136 "%s: MAC Spoofing enabled for current scan", __func__);
15137 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15138 * to fill TxBds for probe request during current scan
15139 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015140 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053015141 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015142
15143 if(status != VOS_STATUS_SUCCESS)
15144 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015145 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015146 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053015147#ifdef FEATURE_WLAN_TDLS
15148 wlan_hdd_tdls_scan_done_callback(pAdapter);
15149#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015150 goto free_mem;
15151 }
Siddharth Bhal76972212014-10-15 16:22:51 +053015152 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053015153 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070015154 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015155 pAdapter->sessionId, &scanRequest, &scanId,
15156 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070015157
Jeff Johnson295189b2012-06-20 16:38:30 -070015158 if (eHAL_STATUS_SUCCESS != status)
15159 {
15160 hddLog(VOS_TRACE_LEVEL_ERROR,
15161 "%s: sme_ScanRequest returned error %d", __func__, status);
15162 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015163 if(eHAL_STATUS_RESOURCES == status)
15164 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015165 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
15166 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015167 status = -EBUSY;
15168 } else {
15169 status = -EIO;
15170 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015171 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015172
15173#ifdef FEATURE_WLAN_TDLS
15174 wlan_hdd_tdls_scan_done_callback(pAdapter);
15175#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015176 goto free_mem;
15177 }
15178
15179 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015180 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070015181 pAdapter->request = request;
15182 pScanInfo->scanId = scanId;
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015183 pScanInfo->no_cck = request->no_cck;
15184 pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
15185 for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
15186 pHddCtx->scan_info.last_scan_channelList[i] =
15187 request->channels[i]->hw_value;
15188 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015189
15190 complete(&pScanInfo->scan_req_completion_event);
15191
15192free_mem:
15193 if( scanRequest.SSIDs.SSIDList )
15194 {
15195 vos_mem_free(scanRequest.SSIDs.SSIDList);
15196 }
15197
15198 if( channelList )
15199 vos_mem_free( channelList );
15200
15201 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015202 return status;
15203}
15204
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015205int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
15206#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15207 struct net_device *dev,
15208#endif
15209 struct cfg80211_scan_request *request)
15210{
15211 int ret;
15212
15213 vos_ssr_protect(__func__);
15214 ret = __wlan_hdd_cfg80211_scan(wiphy,
15215#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15216 dev,
15217#endif
15218 request);
15219 vos_ssr_unprotect(__func__);
15220
15221 return ret;
15222}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015223
15224void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
15225{
15226 v_U8_t iniDot11Mode =
15227 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
15228 eHddDot11Mode hddDot11Mode = iniDot11Mode;
15229
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015230 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
15231 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015232 switch ( iniDot11Mode )
15233 {
15234 case eHDD_DOT11_MODE_AUTO:
15235 case eHDD_DOT11_MODE_11ac:
15236 case eHDD_DOT11_MODE_11ac_ONLY:
15237#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053015238 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
15239 sme_IsFeatureSupportedByFW(DOT11AC) )
15240 hddDot11Mode = eHDD_DOT11_MODE_11ac;
15241 else
15242 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015243#else
15244 hddDot11Mode = eHDD_DOT11_MODE_11n;
15245#endif
15246 break;
15247 case eHDD_DOT11_MODE_11n:
15248 case eHDD_DOT11_MODE_11n_ONLY:
15249 hddDot11Mode = eHDD_DOT11_MODE_11n;
15250 break;
15251 default:
15252 hddDot11Mode = iniDot11Mode;
15253 break;
15254 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015255#ifdef WLAN_FEATURE_AP_HT40_24G
15256 if (operationChannel > SIR_11B_CHANNEL_END)
15257#endif
15258 {
15259 /* This call decides required channel bonding mode */
15260 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015261 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053015262 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015263 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015264}
15265
Jeff Johnson295189b2012-06-20 16:38:30 -070015266/*
15267 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015268 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015269 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015270int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053015271 const u8 *ssid, size_t ssid_len, const u8 *bssid,
15272 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070015273{
15274 int status = 0;
15275 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080015276 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015277 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015278 v_U32_t roamId;
15279 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070015280 eCsrAuthType RSNAuthType;
15281
15282 ENTER();
15283
15284 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015285 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015286 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015287
15288 status = wlan_hdd_validate_context(pHddCtx);
15289 if (status)
15290 {
Yue Mae36e3552014-03-05 17:06:20 -080015291 return status;
15292 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015293
Jeff Johnson295189b2012-06-20 16:38:30 -070015294 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
15295 {
15296 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
15297 return -EINVAL;
15298 }
15299
Nitesh Shah9b066282017-06-06 18:05:52 +053015300 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
15301
Jeff Johnson295189b2012-06-20 16:38:30 -070015302 pRoamProfile = &pWextState->roamProfile;
15303
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015304 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070015305 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015306 hdd_station_ctx_t *pHddStaCtx;
15307 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053015308 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015309
Siddharth Bhalda0d1622015-04-24 15:47:49 +053015310 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
15311
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015312 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070015313 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
15314 {
15315 /*QoS not enabled in cfg file*/
15316 pRoamProfile->uapsd_mask = 0;
15317 }
15318 else
15319 {
15320 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015321 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070015322 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
15323 }
15324
15325 pRoamProfile->SSIDs.numOfSSIDs = 1;
15326 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
15327 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015328 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070015329 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
15330 ssid, ssid_len);
15331
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015332 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
15333 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
15334
Jeff Johnson295189b2012-06-20 16:38:30 -070015335 if (bssid)
15336 {
15337 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015338 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015339 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015340 /* Save BSSID in seperate variable as well, as RoamProfile
15341 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070015342 case of join failure we should send valid BSSID to supplicant
15343 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015344 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015345 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015346
Jeff Johnson295189b2012-06-20 16:38:30 -070015347 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015348 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070015349 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015350 /* Store bssid_hint to use in the scan filter. */
15351 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15352 WNI_CFG_BSSID_LEN);
15353 /*
15354 * Save BSSID in seperate variable as well, as RoamProfile
15355 * BSSID is getting zeroed out in the association process. And in
15356 * case of join failure we should send valid BSSID to supplicant
15357 */
15358 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15359 WNI_CFG_BSSID_LEN);
15360 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15361 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015362 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015363
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015364
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015365 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15366 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015367 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15368 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015369 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015370 /*set gen ie*/
15371 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15372 /*set auth*/
15373 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15374 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015375#ifdef FEATURE_WLAN_WAPI
15376 if (pAdapter->wapi_info.nWapiMode)
15377 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015378 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015379 switch (pAdapter->wapi_info.wapiAuthMode)
15380 {
15381 case WAPI_AUTH_MODE_PSK:
15382 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015383 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015384 pAdapter->wapi_info.wapiAuthMode);
15385 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15386 break;
15387 }
15388 case WAPI_AUTH_MODE_CERT:
15389 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015390 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015391 pAdapter->wapi_info.wapiAuthMode);
15392 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15393 break;
15394 }
15395 } // End of switch
15396 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15397 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15398 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015399 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015400 pRoamProfile->AuthType.numEntries = 1;
15401 pRoamProfile->EncryptionType.numEntries = 1;
15402 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15403 pRoamProfile->mcEncryptionType.numEntries = 1;
15404 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15405 }
15406 }
15407#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015408#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015409 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015410 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15411 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
15412 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015413 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
15414 sizeof (tSirGtkOffloadParams));
15415 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015416 }
15417#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015418 pRoamProfile->csrPersona = pAdapter->device_mode;
15419
Jeff Johnson32d95a32012-09-10 13:15:23 -070015420 if( operatingChannel )
15421 {
15422 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
15423 pRoamProfile->ChannelInfo.numOfChannels = 1;
15424 }
Chet Lanctot186b5732013-03-18 10:26:30 -070015425 else
15426 {
15427 pRoamProfile->ChannelInfo.ChannelList = NULL;
15428 pRoamProfile->ChannelInfo.numOfChannels = 0;
15429 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015430 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
15431 {
15432 hdd_select_cbmode(pAdapter,operatingChannel);
15433 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015434
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015435 /*
15436 * Change conn_state to connecting before sme_RoamConnect(),
15437 * because sme_RoamConnect() has a direct path to call
15438 * hdd_smeRoamCallback(), which will change the conn_state
15439 * If direct path, conn_state will be accordingly changed
15440 * to NotConnected or Associated by either
15441 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
15442 * in sme_RoamCallback()
15443 * if sme_RomConnect is to be queued,
15444 * Connecting state will remain until it is completed.
15445 * If connection state is not changed,
15446 * connection state will remain in eConnectionState_NotConnected state.
15447 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
15448 * if conn state is eConnectionState_NotConnected.
15449 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
15450 * informed of connect result indication which is an issue.
15451 */
15452
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015453 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15454 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053015455 {
15456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015457 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015458 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
15459 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053015460 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015461 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015462 pAdapter->sessionId, pRoamProfile, &roamId);
15463
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015464 if ((eHAL_STATUS_SUCCESS != status) &&
15465 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15466 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015467
15468 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015469 hddLog(VOS_TRACE_LEVEL_ERROR,
15470 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
15471 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015472 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015473 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015474 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015475 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015476
15477 pRoamProfile->ChannelInfo.ChannelList = NULL;
15478 pRoamProfile->ChannelInfo.numOfChannels = 0;
15479
Jeff Johnson295189b2012-06-20 16:38:30 -070015480 }
15481 else
15482 {
15483 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
15484 return -EINVAL;
15485 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015486 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015487 return status;
15488}
15489
15490/*
15491 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
15492 * This function is used to set the authentication type (OPEN/SHARED).
15493 *
15494 */
15495static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
15496 enum nl80211_auth_type auth_type)
15497{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015498 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015499 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15500
15501 ENTER();
15502
15503 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015504 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070015505 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015506 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015507 hddLog(VOS_TRACE_LEVEL_INFO,
15508 "%s: set authentication type to AUTOSWITCH", __func__);
15509 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
15510 break;
15511
15512 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015513#ifdef WLAN_FEATURE_VOWIFI_11R
15514 case NL80211_AUTHTYPE_FT:
15515#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015516 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015517 "%s: set authentication type to OPEN", __func__);
15518 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
15519 break;
15520
15521 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015522 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015523 "%s: set authentication type to SHARED", __func__);
15524 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
15525 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015526#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015527 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015528 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015529 "%s: set authentication type to CCKM WPA", __func__);
15530 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
15531 break;
15532#endif
15533
15534
15535 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015536 hddLog(VOS_TRACE_LEVEL_ERROR,
15537 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015538 auth_type);
15539 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
15540 return -EINVAL;
15541 }
15542
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015543 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015544 pHddStaCtx->conn_info.authType;
15545 return 0;
15546}
15547
15548/*
15549 * FUNCTION: wlan_hdd_set_akm_suite
15550 * This function is used to set the key mgmt type(PSK/8021x).
15551 *
15552 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015553static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015554 u32 key_mgmt
15555 )
15556{
15557 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15558 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053015559 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015560#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015561#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015562#endif
15563#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015564#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015565#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015566 /*set key mgmt type*/
15567 switch(key_mgmt)
15568 {
15569 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053015570 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015571#ifdef WLAN_FEATURE_VOWIFI_11R
15572 case WLAN_AKM_SUITE_FT_PSK:
15573#endif
15574 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070015575 __func__);
15576 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
15577 break;
15578
15579 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053015580 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015581#ifdef WLAN_FEATURE_VOWIFI_11R
15582 case WLAN_AKM_SUITE_FT_8021X:
15583#endif
15584 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070015585 __func__);
15586 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15587 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015588#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015589#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
15590#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
15591 case WLAN_AKM_SUITE_CCKM:
15592 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
15593 __func__);
15594 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
15595 break;
15596#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070015597#ifndef WLAN_AKM_SUITE_OSEN
15598#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
15599 case WLAN_AKM_SUITE_OSEN:
15600 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
15601 __func__);
15602 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15603 break;
15604#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015605
15606 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015607 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015608 __func__, key_mgmt);
15609 return -EINVAL;
15610
15611 }
15612 return 0;
15613}
15614
15615/*
15616 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015617 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070015618 * (NONE/WEP40/WEP104/TKIP/CCMP).
15619 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015620static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
15621 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070015622 bool ucast
15623 )
15624{
15625 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015626 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015627 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15628
15629 ENTER();
15630
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015631 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015632 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053015633 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070015634 __func__, cipher);
15635 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15636 }
15637 else
15638 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015639
Jeff Johnson295189b2012-06-20 16:38:30 -070015640 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015641 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015642 {
15643 case IW_AUTH_CIPHER_NONE:
15644 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15645 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015646
Jeff Johnson295189b2012-06-20 16:38:30 -070015647 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015648 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070015649 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015650
Jeff Johnson295189b2012-06-20 16:38:30 -070015651 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015652 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070015653 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015654
Jeff Johnson295189b2012-06-20 16:38:30 -070015655 case WLAN_CIPHER_SUITE_TKIP:
15656 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
15657 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015658
Jeff Johnson295189b2012-06-20 16:38:30 -070015659 case WLAN_CIPHER_SUITE_CCMP:
15660 encryptionType = eCSR_ENCRYPT_TYPE_AES;
15661 break;
15662#ifdef FEATURE_WLAN_WAPI
15663 case WLAN_CIPHER_SUITE_SMS4:
15664 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
15665 break;
15666#endif
15667
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015668#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015669 case WLAN_CIPHER_SUITE_KRK:
15670 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
15671 break;
15672#endif
15673 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015674 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015675 __func__, cipher);
15676 return -EOPNOTSUPP;
15677 }
15678 }
15679
15680 if (ucast)
15681 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015682 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015683 __func__, encryptionType);
15684 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15685 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015686 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015687 encryptionType;
15688 }
15689 else
15690 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015691 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015692 __func__, encryptionType);
15693 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
15694 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
15695 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
15696 }
15697
15698 return 0;
15699}
15700
15701
15702/*
15703 * FUNCTION: wlan_hdd_cfg80211_set_ie
15704 * This function is used to parse WPA/RSN IE's.
15705 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015706int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015707#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15708 const u8 *ie,
15709#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015710 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015711#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015712 size_t ie_len
15713 )
15714{
15715 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015716#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15717 const u8 *genie = ie;
15718#else
Jeff Johnson295189b2012-06-20 16:38:30 -070015719 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015720#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015721 v_U16_t remLen = ie_len;
15722#ifdef FEATURE_WLAN_WAPI
15723 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
15724 u16 *tmp;
15725 v_U16_t akmsuiteCount;
15726 int *akmlist;
15727#endif
15728 ENTER();
15729
15730 /* clear previous assocAddIE */
15731 pWextState->assocAddIE.length = 0;
15732 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015733 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015734
15735 while (remLen >= 2)
15736 {
15737 v_U16_t eLen = 0;
15738 v_U8_t elementId;
15739 elementId = *genie++;
15740 eLen = *genie++;
15741 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015742
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053015743 /* Sanity check on eLen */
15744 if (eLen > remLen) {
15745 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
15746 __func__, eLen, elementId);
15747 VOS_ASSERT(0);
15748 return -EINVAL;
15749 }
15750
Arif Hussain6d2a3322013-11-17 19:50:10 -080015751 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070015752 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015753
15754 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070015755 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015756 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015757 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 -070015758 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015759 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015760 "%s: Invalid WPA IE", __func__);
15761 return -EINVAL;
15762 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015763 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070015764 {
15765 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015766 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015767 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015768
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015769 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015770 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015771 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
15772 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015773 VOS_ASSERT(0);
15774 return -ENOMEM;
15775 }
15776 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15777 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15778 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015779
Jeff Johnson295189b2012-06-20 16:38:30 -070015780 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
15781 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15782 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15783 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015784 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
15785 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053015786 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
15787 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
15788 __func__, eLen);
15789 VOS_ASSERT(0);
15790 return -EINVAL;
15791 }
15792
Jeff Johnson295189b2012-06-20 16:38:30 -070015793 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
15794 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15795 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
15796 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
15797 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
15798 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015799 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053015800 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070015801 {
15802 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015803 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015804 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015805
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015806 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015807 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015808 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15809 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015810 VOS_ASSERT(0);
15811 return -ENOMEM;
15812 }
15813 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15814 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15815 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015816
Jeff Johnson295189b2012-06-20 16:38:30 -070015817 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15818 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15819 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015820#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015821 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
15822 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015823 /*Consider WFD IE, only for P2P Client */
15824 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15825 {
15826 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015827 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015828 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015829
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015830 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015831 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015832 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15833 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015834 VOS_ASSERT(0);
15835 return -ENOMEM;
15836 }
15837 // WFD IE is saved to Additional IE ; it should be accumulated to handle
15838 // WPS IE + P2P IE + WFD IE
15839 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15840 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015841
Jeff Johnson295189b2012-06-20 16:38:30 -070015842 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15843 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15844 }
15845#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015846 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015847 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015848 HS20_OUI_TYPE_SIZE)) )
15849 {
15850 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015851 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015852 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015853
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015854 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015855 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015856 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15857 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015858 VOS_ASSERT(0);
15859 return -ENOMEM;
15860 }
15861 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15862 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015863
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015864 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15865 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15866 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015867 /* Appending OSEN Information Element in Assiciation Request */
15868 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
15869 OSEN_OUI_TYPE_SIZE)) )
15870 {
15871 v_U16_t curAddIELen = pWextState->assocAddIE.length;
15872 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
15873 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015874
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015875 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015876 {
15877 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15878 "Need bigger buffer space");
15879 VOS_ASSERT(0);
15880 return -ENOMEM;
15881 }
15882 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15883 pWextState->assocAddIE.length += eLen + 2;
15884
15885 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
15886 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15887 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15888 }
15889
Abhishek Singh4322e622015-06-10 15:42:54 +053015890 /* Update only for WPA IE */
15891 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
15892 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015893
15894 /* populating as ADDIE in beacon frames */
15895 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015896 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015897 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
15898 {
15899 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15900 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
15901 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15902 {
15903 hddLog(LOGE,
15904 "Coldn't pass "
15905 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
15906 }
15907 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
15908 else
15909 hddLog(LOGE,
15910 "Could not pass on "
15911 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
15912
15913 /* IBSS mode doesn't contain params->proberesp_ies still
15914 beaconIE's need to be populated in probe response frames */
15915 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
15916 {
15917 u16 rem_probe_resp_ie_len = eLen + 2;
15918 u8 probe_rsp_ie_len[3] = {0};
15919 u8 counter = 0;
15920
15921 /* Check Probe Resp Length if it is greater then 255 then
15922 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
15923 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
15924 not able Store More then 255 bytes into One Variable */
15925
15926 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
15927 {
15928 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
15929 {
15930 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
15931 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
15932 }
15933 else
15934 {
15935 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
15936 rem_probe_resp_ie_len = 0;
15937 }
15938 }
15939
15940 rem_probe_resp_ie_len = 0;
15941
15942 if (probe_rsp_ie_len[0] > 0)
15943 {
15944 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15945 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
15946 (tANI_U8*)(genie - 2),
15947 probe_rsp_ie_len[0], NULL,
15948 eANI_BOOLEAN_FALSE)
15949 == eHAL_STATUS_FAILURE)
15950 {
15951 hddLog(LOGE,
15952 "Could not pass"
15953 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
15954 }
15955 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
15956 }
15957
15958 if (probe_rsp_ie_len[1] > 0)
15959 {
15960 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15961 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
15962 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15963 probe_rsp_ie_len[1], NULL,
15964 eANI_BOOLEAN_FALSE)
15965 == eHAL_STATUS_FAILURE)
15966 {
15967 hddLog(LOGE,
15968 "Could not pass"
15969 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
15970 }
15971 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
15972 }
15973
15974 if (probe_rsp_ie_len[2] > 0)
15975 {
15976 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15977 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
15978 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15979 probe_rsp_ie_len[2], NULL,
15980 eANI_BOOLEAN_FALSE)
15981 == eHAL_STATUS_FAILURE)
15982 {
15983 hddLog(LOGE,
15984 "Could not pass"
15985 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
15986 }
15987 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
15988 }
15989
15990 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15991 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
15992 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15993 {
15994 hddLog(LOGE,
15995 "Could not pass"
15996 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
15997 }
15998 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015999 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070016000 break;
16001 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053016002 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16003 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
16004 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
16005 VOS_ASSERT(0);
16006 return -EINVAL;
16007 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016008 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
16009 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16010 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
16011 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
16012 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16013 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016014
Abhishek Singhb16f3562016-01-20 11:08:32 +053016015 /* Appending extended capabilities with Interworking or
16016 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016017 *
16018 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016019 * interworkingService or bsstransition bit is set to 1.
16020 * Driver is only interested in interworkingService and
16021 * bsstransition capability from supplicant.
16022 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016023 * required from supplicat, it needs to be handled while
16024 * sending Assoc Req in LIM.
16025 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016026 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016027 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016028 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016029 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016030 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016031
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016032 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016033 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016034 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16035 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016036 VOS_ASSERT(0);
16037 return -ENOMEM;
16038 }
16039 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16040 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016041
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016042 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16043 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16044 break;
16045 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016046#ifdef FEATURE_WLAN_WAPI
16047 case WLAN_EID_WAPI:
16048 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016049 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016050 pAdapter->wapi_info.nWapiMode);
16051 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016052 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016053 akmsuiteCount = WPA_GET_LE16(tmp);
16054 tmp = tmp + 1;
16055 akmlist = (int *)(tmp);
16056 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16057 {
16058 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16059 }
16060 else
16061 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016062 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016063 VOS_ASSERT(0);
16064 return -EINVAL;
16065 }
16066
16067 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16068 {
16069 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016070 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016071 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016072 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016073 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016074 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016075 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016076 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016077 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
16078 }
16079 break;
16080#endif
16081 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016082 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016083 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016084 /* when Unknown IE is received we should break and continue
16085 * to the next IE in the buffer instead we were returning
16086 * so changing this to break */
16087 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016088 }
16089 genie += eLen;
16090 remLen -= eLen;
16091 }
16092 EXIT();
16093 return 0;
16094}
16095
16096/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016097 * FUNCTION: hdd_isWPAIEPresent
16098 * Parse the received IE to find the WPA IE
16099 *
16100 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016101static bool hdd_isWPAIEPresent(
16102#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16103 const u8 *ie,
16104#else
16105 u8 *ie,
16106#endif
16107 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016108{
16109 v_U8_t eLen = 0;
16110 v_U16_t remLen = ie_len;
16111 v_U8_t elementId = 0;
16112
16113 while (remLen >= 2)
16114 {
16115 elementId = *ie++;
16116 eLen = *ie++;
16117 remLen -= 2;
16118 if (eLen > remLen)
16119 {
16120 hddLog(VOS_TRACE_LEVEL_ERROR,
16121 "%s: IE length is wrong %d", __func__, eLen);
16122 return FALSE;
16123 }
16124 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16125 {
16126 /* OUI - 0x00 0X50 0XF2
16127 WPA Information Element - 0x01
16128 WPA version - 0x01*/
16129 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16130 return TRUE;
16131 }
16132 ie += eLen;
16133 remLen -= eLen;
16134 }
16135 return FALSE;
16136}
16137
16138/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016139 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016140 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016141 * parameters during connect operation.
16142 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016143int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016144 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016145 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016146{
16147 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016148 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016149 ENTER();
16150
16151 /*set wpa version*/
16152 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
16153
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016154 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016155 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053016156 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016157 {
16158 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16159 }
16160 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
16161 {
16162 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16163 }
16164 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016165
16166 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016167 pWextState->wpaVersion);
16168
16169 /*set authentication type*/
16170 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
16171
16172 if (0 > status)
16173 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016174 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016175 "%s: failed to set authentication type ", __func__);
16176 return status;
16177 }
16178
16179 /*set key mgmt type*/
16180 if (req->crypto.n_akm_suites)
16181 {
16182 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
16183 if (0 > status)
16184 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016185 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070016186 __func__);
16187 return status;
16188 }
16189 }
16190
16191 /*set pairwise cipher type*/
16192 if (req->crypto.n_ciphers_pairwise)
16193 {
16194 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
16195 req->crypto.ciphers_pairwise[0], true);
16196 if (0 > status)
16197 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016198 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016199 "%s: failed to set unicast cipher type", __func__);
16200 return status;
16201 }
16202 }
16203 else
16204 {
16205 /*Reset previous cipher suite to none*/
16206 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
16207 if (0 > status)
16208 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016209 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016210 "%s: failed to set unicast cipher type", __func__);
16211 return status;
16212 }
16213 }
16214
16215 /*set group cipher type*/
16216 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
16217 false);
16218
16219 if (0 > status)
16220 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016221 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070016222 __func__);
16223 return status;
16224 }
16225
Chet Lanctot186b5732013-03-18 10:26:30 -070016226#ifdef WLAN_FEATURE_11W
16227 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
16228#endif
16229
Jeff Johnson295189b2012-06-20 16:38:30 -070016230 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
16231 if (req->ie_len)
16232 {
16233 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
16234 if ( 0 > status)
16235 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016236 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016237 __func__);
16238 return status;
16239 }
16240 }
16241
16242 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016243 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016244 {
16245 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
16246 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
16247 )
16248 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016249 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070016250 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
16251 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016252 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016253 __func__);
16254 return -EOPNOTSUPP;
16255 }
16256 else
16257 {
16258 u8 key_len = req->key_len;
16259 u8 key_idx = req->key_idx;
16260
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016261 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016262 && (CSR_MAX_NUM_KEY > key_idx)
16263 )
16264 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016265 hddLog(VOS_TRACE_LEVEL_INFO,
16266 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016267 __func__, key_idx, key_len);
16268 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016269 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070016270 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016271 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016272 (u8)key_len;
16273 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
16274 }
16275 }
16276 }
16277 }
16278
16279 return status;
16280}
16281
16282/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016283 * FUNCTION: wlan_hdd_try_disconnect
16284 * This function is used to disconnect from previous
16285 * connection
16286 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053016287int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016288{
16289 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016290 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016291 hdd_station_ctx_t *pHddStaCtx;
16292 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016293 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016294
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016295 ret = wlan_hdd_validate_context(pHddCtx);
16296 if (0 != ret)
16297 {
16298 return ret;
16299 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016300 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16301
16302 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
16303
16304 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
16305 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053016306 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016307 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
16308 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053016309 /* Indicate disconnect to SME so that in-progress connection or preauth
16310 * can be aborted
16311 */
16312 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
16313 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016314 spin_lock_bh(&pAdapter->lock_for_active_session);
16315 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16316 {
16317 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16318 }
16319 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053016320 hdd_connSetConnectionState(pHddStaCtx,
16321 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016322 /* Issue disconnect to CSR */
16323 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016324 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016325 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016326 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16327 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
16328 hddLog(LOG1,
16329 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
16330 } else if ( 0 != status ) {
16331 hddLog(LOGE,
16332 FL("csrRoamDisconnect failure, returned %d"),
16333 (int)status );
16334 result = -EINVAL;
16335 goto disconnected;
16336 }
16337 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016338 &pAdapter->disconnect_comp_var,
16339 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016340 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
16341 hddLog(LOGE,
16342 "%s: Failed to disconnect, timed out", __func__);
16343 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016344 }
16345 }
16346 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
16347 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016348 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016349 &pAdapter->disconnect_comp_var,
16350 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016351 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016352 {
16353 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016354 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016355 }
16356 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016357disconnected:
16358 hddLog(LOG1,
16359 FL("Set HDD connState to eConnectionState_NotConnected"));
16360 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16361 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016362}
16363
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016364/**
16365 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16366 * @adapter: Pointer to the HDD adapter
16367 * @req: Pointer to the structure cfg_connect_params receieved from user space
16368 *
16369 * This function will start reassociation if bssid hint, channel hint and
16370 * previous bssid parameters are present in the connect request
16371 *
16372 * Return: success if reassociation is happening
16373 * Error code if reassociation is not permitted or not happening
16374 */
16375#ifdef CFG80211_CONNECT_PREV_BSSID
16376static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16377 struct cfg80211_connect_params *req)
16378{
16379 int status = -EPERM;
16380 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
16381 hddLog(VOS_TRACE_LEVEL_INFO,
16382 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
16383 req->channel_hint->hw_value,
16384 MAC_ADDR_ARRAY(req->bssid_hint));
16385 status = hdd_reassoc(adapter, req->bssid_hint,
16386 req->channel_hint->hw_value,
16387 CONNECT_CMD_USERSPACE);
16388 }
16389 return status;
16390}
16391#else
16392static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16393 struct cfg80211_connect_params *req)
16394{
16395 return -EPERM;
16396}
16397#endif
16398
Abhishek Singhe3beee22017-07-31 15:35:40 +053016399/**
16400 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
16401 * connect in HT20 mode
16402 * @hdd_ctx: hdd context
16403 * @adapter: Pointer to the HDD adapter
16404 * @req: Pointer to the structure cfg_connect_params receieved from user space
16405 *
16406 * This function will check if supplicant has indicated to to connect in HT20
16407 * mode. this is currently applicable only for 2.4Ghz mode only.
16408 * if feature is enabled and supplicant indicate HT20 set
16409 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
16410 *
16411 * Return: void
16412 */
16413#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
16414static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16415 hdd_adapter_t *adapter,
16416 struct cfg80211_connect_params *req)
16417{
16418 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16419 tCsrRoamProfile *roam_profile;
16420
16421 roam_profile = &wext_state->roamProfile;
16422 roam_profile->force_24ghz_in_ht20 = false;
16423 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
16424 !(req->ht_capa.cap_info &
16425 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
16426 roam_profile->force_24ghz_in_ht20 = true;
16427
16428 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
16429 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
16430}
16431#else
16432static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16433 hdd_adapter_t *adapter,
16434 struct cfg80211_connect_params *req)
16435{
16436 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16437 tCsrRoamProfile *roam_profile;
16438
16439 roam_profile = &wext_state->roamProfile;
16440 roam_profile->force_24ghz_in_ht20 = false;
16441}
16442#endif
16443
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016444/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053016445 * FUNCTION: __wlan_hdd_cfg80211_connect
16446 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070016447 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016448static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016449 struct net_device *ndev,
16450 struct cfg80211_connect_params *req
16451 )
16452{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016453 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016454 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053016455#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
16456 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016457 const u8 *bssid_hint = req->bssid_hint;
16458#else
16459 const u8 *bssid_hint = NULL;
16460#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016461 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016462 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053016463 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016464
16465 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016466
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016467 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16468 TRACE_CODE_HDD_CFG80211_CONNECT,
16469 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016470 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016471 "%s: device_mode = %s (%d)", __func__,
16472 hdd_device_modetoString(pAdapter->device_mode),
16473 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016474
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016475 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016476 if (!pHddCtx)
16477 {
16478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16479 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053016480 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016481 }
16482
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016483 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016484 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016485 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016486 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016487 }
16488
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053016489 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
16490 return -EINVAL;
16491
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016492 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
16493 if (0 == status)
16494 return status;
16495
Agarwal Ashish51325b52014-06-16 16:50:49 +053016496
Jeff Johnson295189b2012-06-20 16:38:30 -070016497#ifdef WLAN_BTAMP_FEATURE
16498 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016499 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070016500 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016501 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016502 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080016503 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070016504 }
16505#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016506
16507 //If Device Mode is Station Concurrent Sessions Exit BMps
16508 //P2P Mode will be taken care in Open/close adapter
16509 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053016510 (vos_concurrent_open_sessions_running())) {
16511 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
16512 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016513 }
16514
16515 /*Try disconnecting if already in connected state*/
16516 status = wlan_hdd_try_disconnect(pAdapter);
16517 if ( 0 > status)
16518 {
16519 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16520 " connection"));
16521 return -EALREADY;
16522 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053016523 /* Check for max concurrent connections after doing disconnect if any*/
16524 if (vos_max_concurrent_connections_reached()) {
16525 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16526 return -ECONNREFUSED;
16527 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016528
Jeff Johnson295189b2012-06-20 16:38:30 -070016529 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016530 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070016531
16532 if ( 0 > status)
16533 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016534 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070016535 __func__);
16536 return status;
16537 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053016538
16539 if (pHddCtx->spoofMacAddr.isEnabled)
16540 {
16541 hddLog(VOS_TRACE_LEVEL_INFO,
16542 "%s: MAC Spoofing enabled ", __func__);
16543 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
16544 * to fill TxBds for probe request during SSID scan which may happen
16545 * as part of connect command
16546 */
16547 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
16548 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
16549 if (status != VOS_STATUS_SUCCESS)
16550 return -ECONNREFUSED;
16551 }
16552
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016553 if (req->channel)
16554 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070016555 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016556 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053016557
16558 /* Abort if any scan is going on */
16559 status = wlan_hdd_scan_abort(pAdapter);
16560 if (0 != status)
16561 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
16562
Abhishek Singhe3beee22017-07-31 15:35:40 +053016563 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
16564
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016565 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
16566 req->ssid_len, req->bssid,
16567 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016568
Sushant Kaushikd7083982015-03-18 14:33:24 +053016569 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016570 {
16571 //ReEnable BMPS if disabled
16572 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
16573 (NULL != pHddCtx))
16574 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053016575 if (pHddCtx->hdd_wlan_suspended)
16576 {
16577 hdd_set_pwrparams(pHddCtx);
16578 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016579 //ReEnable Bmps and Imps back
16580 hdd_enable_bmps_imps(pHddCtx);
16581 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053016582 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070016583 return status;
16584 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016585 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016586 EXIT();
16587 return status;
16588}
16589
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016590static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
16591 struct net_device *ndev,
16592 struct cfg80211_connect_params *req)
16593{
16594 int ret;
16595 vos_ssr_protect(__func__);
16596 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
16597 vos_ssr_unprotect(__func__);
16598
16599 return ret;
16600}
Jeff Johnson295189b2012-06-20 16:38:30 -070016601
16602/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016603 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070016604 * This function is used to issue a disconnect request to SME
16605 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016606static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016607 struct net_device *dev,
16608 u16 reason
16609 )
16610{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016611 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016612 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016613 tCsrRoamProfile *pRoamProfile;
16614 hdd_station_ctx_t *pHddStaCtx;
16615 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016616#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016617 tANI_U8 staIdx;
16618#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016619
Jeff Johnson295189b2012-06-20 16:38:30 -070016620 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016621
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016622 if (!pAdapter) {
16623 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16624 return -EINVAL;
16625 }
16626
16627 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16628 if (!pHddStaCtx) {
16629 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
16630 return -EINVAL;
16631 }
16632
16633 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16634 status = wlan_hdd_validate_context(pHddCtx);
16635 if (0 != status)
16636 {
16637 return status;
16638 }
16639
16640 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
16641
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016642 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16643 TRACE_CODE_HDD_CFG80211_DISCONNECT,
16644 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016645 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
16646 __func__, hdd_device_modetoString(pAdapter->device_mode),
16647 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016648
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016649 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
16650 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070016651
Jeff Johnson295189b2012-06-20 16:38:30 -070016652 if (NULL != pRoamProfile)
16653 {
16654 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053016655 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
16656 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070016657 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016658 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070016659 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016660 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070016661 switch(reason)
16662 {
16663 case WLAN_REASON_MIC_FAILURE:
16664 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
16665 break;
16666
16667 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
16668 case WLAN_REASON_DISASSOC_AP_BUSY:
16669 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
16670 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
16671 break;
16672
16673 case WLAN_REASON_PREV_AUTH_NOT_VALID:
16674 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053016675 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070016676 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
16677 break;
16678
Jeff Johnson295189b2012-06-20 16:38:30 -070016679 default:
16680 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
16681 break;
16682 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016683 pScanInfo = &pHddCtx->scan_info;
16684 if (pScanInfo->mScanPending)
16685 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016686 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016687 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053016688 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016689 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016690 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053016691 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016692#ifdef FEATURE_WLAN_TDLS
16693 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016694 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016695 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016696 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
16697 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016698 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016699 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016700 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016702 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016703 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016704 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016705 status = sme_DeleteTdlsPeerSta(
16706 WLAN_HDD_GET_HAL_CTX(pAdapter),
16707 pAdapter->sessionId,
16708 mac);
16709 if (status != eHAL_STATUS_SUCCESS) {
16710 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16711 return -EPERM;
16712 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016713 }
16714 }
16715#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016716
16717 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
16718 reasonCode,
16719 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016720 status = wlan_hdd_disconnect(pAdapter, reasonCode);
16721 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070016722 {
16723 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016724 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016725 __func__, (int)status );
16726 return -EINVAL;
16727 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016728 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053016729 else
16730 {
16731 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
16732 "called while in %d state", __func__,
16733 pHddStaCtx->conn_info.connState);
16734 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016735 }
16736 else
16737 {
16738 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
16739 }
16740
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016741 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016742 return status;
16743}
16744
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016745static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
16746 struct net_device *dev,
16747 u16 reason
16748 )
16749{
16750 int ret;
16751 vos_ssr_protect(__func__);
16752 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
16753 vos_ssr_unprotect(__func__);
16754
16755 return ret;
16756}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016757
Jeff Johnson295189b2012-06-20 16:38:30 -070016758/*
16759 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016760 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016761 * settings in IBSS mode.
16762 */
16763static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016764 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016765 struct cfg80211_ibss_params *params
16766 )
16767{
16768 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016769 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016770 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16771 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016772
Jeff Johnson295189b2012-06-20 16:38:30 -070016773 ENTER();
16774
16775 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070016776 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070016777
16778 if (params->ie_len && ( NULL != params->ie) )
16779 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016780 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16781 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016782 {
16783 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16784 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16785 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016786 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016787 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016788 tDot11fIEWPA dot11WPAIE;
16789 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016790 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016791
Wilson Yang00256342013-10-10 23:13:38 -070016792 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016793 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16794 params->ie_len, DOT11F_EID_WPA);
16795 if ( NULL != ie )
16796 {
16797 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16798 // Unpack the WPA IE
16799 //Skip past the EID byte and length byte - and four byte WiFi OUI
16800 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
16801 &ie[2+4],
16802 ie[1] - 4,
16803 &dot11WPAIE);
16804 /*Extract the multicast cipher, the encType for unicast
16805 cipher for wpa-none is none*/
16806 encryptionType =
16807 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
16808 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016809 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016810
Jeff Johnson295189b2012-06-20 16:38:30 -070016811 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
16812
16813 if (0 > status)
16814 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016815 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016816 __func__);
16817 return status;
16818 }
16819 }
16820
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016821 pWextState->roamProfile.AuthType.authType[0] =
16822 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070016823 eCSR_AUTH_TYPE_OPEN_SYSTEM;
16824
16825 if (params->privacy)
16826 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016827 /* Security enabled IBSS, At this time there is no information available
16828 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070016829 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016830 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070016831 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016832 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070016833 *enable privacy bit in beacons */
16834
16835 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
16836 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016837 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
16838 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070016839 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16840 pWextState->roamProfile.EncryptionType.numEntries = 1;
16841 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070016842 return status;
16843}
16844
16845/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016846 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016847 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016848 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016849static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016850 struct net_device *dev,
16851 struct cfg80211_ibss_params *params
16852 )
16853{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016854 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016855 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16856 tCsrRoamProfile *pRoamProfile;
16857 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016858 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16859 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016860 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070016861
16862 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016863
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016864 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16865 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
16866 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016867 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016868 "%s: device_mode = %s (%d)", __func__,
16869 hdd_device_modetoString(pAdapter->device_mode),
16870 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016871
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016872 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016873 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016874 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016875 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016876 }
16877
16878 if (NULL == pWextState)
16879 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016880 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016881 __func__);
16882 return -EIO;
16883 }
16884
Agarwal Ashish51325b52014-06-16 16:50:49 +053016885 if (vos_max_concurrent_connections_reached()) {
16886 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16887 return -ECONNREFUSED;
16888 }
16889
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016890 /*Try disconnecting if already in connected state*/
16891 status = wlan_hdd_try_disconnect(pAdapter);
16892 if ( 0 > status)
16893 {
16894 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16895 " IBSS connection"));
16896 return -EALREADY;
16897 }
16898
Jeff Johnson295189b2012-06-20 16:38:30 -070016899 pRoamProfile = &pWextState->roamProfile;
16900
16901 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
16902 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016903 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016904 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016905 return -EINVAL;
16906 }
16907
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016908 /* BSSID is provided by upper layers hence no need to AUTO generate */
16909 if (NULL != params->bssid) {
16910 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16911 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
16912 hddLog (VOS_TRACE_LEVEL_ERROR,
16913 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16914 return -EIO;
16915 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016916 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016917 }
krunal sonie9002db2013-11-25 14:24:17 -080016918 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
16919 {
16920 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16921 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
16922 {
16923 hddLog (VOS_TRACE_LEVEL_ERROR,
16924 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16925 return -EIO;
16926 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016927
16928 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080016929 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016930 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080016931 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016932
Jeff Johnson295189b2012-06-20 16:38:30 -070016933 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070016934 if (NULL !=
16935#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16936 params->chandef.chan)
16937#else
16938 params->channel)
16939#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016940 {
16941 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016942 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16943 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
16944 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16945 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016946
16947 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016948 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070016949 ieee80211_frequency_to_channel(
16950#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16951 params->chandef.chan->center_freq);
16952#else
16953 params->channel->center_freq);
16954#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016955
16956 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16957 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070016958 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016959 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
16960 __func__);
16961 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070016962 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016963
16964 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016965 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016966 if (channelNum == validChan[indx])
16967 {
16968 break;
16969 }
16970 }
16971 if (indx >= numChans)
16972 {
16973 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016974 __func__, channelNum);
16975 return -EINVAL;
16976 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016977 /* Set the Operational Channel */
16978 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
16979 channelNum);
16980 pRoamProfile->ChannelInfo.numOfChannels = 1;
16981 pHddStaCtx->conn_info.operationChannel = channelNum;
16982 pRoamProfile->ChannelInfo.ChannelList =
16983 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070016984 }
16985
16986 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016987 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070016988 if (status < 0)
16989 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016990 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070016991 __func__);
16992 return status;
16993 }
16994
16995 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016996 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053016997 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016998 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016999
17000 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017001 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017002
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017003 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017004 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017005}
17006
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017007static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17008 struct net_device *dev,
17009 struct cfg80211_ibss_params *params
17010 )
17011{
17012 int ret = 0;
17013
17014 vos_ssr_protect(__func__);
17015 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17016 vos_ssr_unprotect(__func__);
17017
17018 return ret;
17019}
17020
Jeff Johnson295189b2012-06-20 16:38:30 -070017021/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017022 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017023 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017024 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017025static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017026 struct net_device *dev
17027 )
17028{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017029 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017030 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17031 tCsrRoamProfile *pRoamProfile;
17032 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017033 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017034 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017035#ifdef WLAN_FEATURE_RMC
17036 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17037#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017038
17039 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017040
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017041 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17042 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17043 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017044 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017045 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017046 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017047 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017048 }
17049
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017050 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17051 hdd_device_modetoString(pAdapter->device_mode),
17052 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017053 if (NULL == pWextState)
17054 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017055 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017056 __func__);
17057 return -EIO;
17058 }
17059
17060 pRoamProfile = &pWextState->roamProfile;
17061
17062 /* Issue disconnect only if interface type is set to IBSS */
17063 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17064 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017065 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017066 __func__);
17067 return -EINVAL;
17068 }
17069
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017070#ifdef WLAN_FEATURE_RMC
17071 /* Clearing add IE of beacon */
17072 if (ccmCfgSetStr(pHddCtx->hHal,
17073 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17074 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17075 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17076 {
17077 hddLog (VOS_TRACE_LEVEL_ERROR,
17078 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17079 return -EINVAL;
17080 }
17081 if (ccmCfgSetInt(pHddCtx->hHal,
17082 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17083 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17084 {
17085 hddLog (VOS_TRACE_LEVEL_ERROR,
17086 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17087 __func__);
17088 return -EINVAL;
17089 }
17090
17091 // Reset WNI_CFG_PROBE_RSP Flags
17092 wlan_hdd_reset_prob_rspies(pAdapter);
17093
17094 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17095 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17096 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17097 {
17098 hddLog (VOS_TRACE_LEVEL_ERROR,
17099 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17100 __func__);
17101 return -EINVAL;
17102 }
17103#endif
17104
Jeff Johnson295189b2012-06-20 16:38:30 -070017105 /* Issue Disconnect request */
17106 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017107 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17108 pAdapter->sessionId,
17109 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17110 if (!HAL_STATUS_SUCCESS(hal_status)) {
17111 hddLog(LOGE,
17112 FL("sme_RoamDisconnect failed hal_status(%d)"),
17113 hal_status);
17114 return -EAGAIN;
17115 }
17116 status = wait_for_completion_timeout(
17117 &pAdapter->disconnect_comp_var,
17118 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17119 if (!status) {
17120 hddLog(LOGE,
17121 FL("wait on disconnect_comp_var failed"));
17122 return -ETIMEDOUT;
17123 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017124
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017125 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017126 return 0;
17127}
17128
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017129static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17130 struct net_device *dev
17131 )
17132{
17133 int ret = 0;
17134
17135 vos_ssr_protect(__func__);
17136 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17137 vos_ssr_unprotect(__func__);
17138
17139 return ret;
17140}
17141
Jeff Johnson295189b2012-06-20 16:38:30 -070017142/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017143 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017144 * This function is used to set the phy parameters
17145 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17146 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017147static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017148 u32 changed)
17149{
17150 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17151 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017152 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017153
17154 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017155
17156 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017157 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17158 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017159
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017160 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017161 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017162 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017163 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017164 }
17165
Jeff Johnson295189b2012-06-20 16:38:30 -070017166 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17167 {
17168 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17169 WNI_CFG_RTS_THRESHOLD_STAMAX :
17170 wiphy->rts_threshold;
17171
17172 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017173 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017174 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017175 hddLog(VOS_TRACE_LEVEL_ERROR,
17176 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017177 __func__, rts_threshold);
17178 return -EINVAL;
17179 }
17180
17181 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17182 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017183 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017184 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017185 hddLog(VOS_TRACE_LEVEL_ERROR,
17186 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017187 __func__, rts_threshold);
17188 return -EIO;
17189 }
17190
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017191 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017192 rts_threshold);
17193 }
17194
17195 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17196 {
17197 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17198 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17199 wiphy->frag_threshold;
17200
17201 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017202 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017203 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017204 hddLog(VOS_TRACE_LEVEL_ERROR,
17205 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017206 frag_threshold);
17207 return -EINVAL;
17208 }
17209
17210 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
17211 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017212 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017213 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017214 hddLog(VOS_TRACE_LEVEL_ERROR,
17215 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017216 __func__, frag_threshold);
17217 return -EIO;
17218 }
17219
17220 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
17221 frag_threshold);
17222 }
17223
17224 if ((changed & WIPHY_PARAM_RETRY_SHORT)
17225 || (changed & WIPHY_PARAM_RETRY_LONG))
17226 {
17227 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
17228 wiphy->retry_short :
17229 wiphy->retry_long;
17230
17231 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17232 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17233 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017234 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017235 __func__, retry_value);
17236 return -EINVAL;
17237 }
17238
17239 if (changed & WIPHY_PARAM_RETRY_SHORT)
17240 {
17241 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17242 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017243 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017244 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017245 hddLog(VOS_TRACE_LEVEL_ERROR,
17246 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017247 __func__, retry_value);
17248 return -EIO;
17249 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017250 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017251 __func__, retry_value);
17252 }
17253 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17254 {
17255 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17256 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017257 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017258 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017259 hddLog(VOS_TRACE_LEVEL_ERROR,
17260 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017261 __func__, retry_value);
17262 return -EIO;
17263 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017264 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017265 __func__, retry_value);
17266 }
17267 }
17268
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017269 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017270 return 0;
17271}
17272
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017273static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17274 u32 changed)
17275{
17276 int ret;
17277
17278 vos_ssr_protect(__func__);
17279 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17280 vos_ssr_unprotect(__func__);
17281
17282 return ret;
17283}
17284
Jeff Johnson295189b2012-06-20 16:38:30 -070017285/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017286 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017287 * This function is used to set the txpower
17288 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017289static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017290#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17291 struct wireless_dev *wdev,
17292#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017293#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017294 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017295#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017296 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017297#endif
17298 int dbm)
17299{
17300 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017301 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017302 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17303 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017304 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017305
17306 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017307
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017308 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17309 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17310 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017311 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017312 if (0 != status)
17313 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017314 return status;
17315 }
17316
17317 hHal = pHddCtx->hHal;
17318
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017319 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17320 dbm, ccmCfgSetCallback,
17321 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017322 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017323 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017324 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17325 return -EIO;
17326 }
17327
17328 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17329 dbm);
17330
17331 switch(type)
17332 {
17333 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17334 /* Fall through */
17335 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17336 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17337 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017338 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17339 __func__);
17340 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017341 }
17342 break;
17343 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017344 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017345 __func__);
17346 return -EOPNOTSUPP;
17347 break;
17348 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017349 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17350 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017351 return -EIO;
17352 }
17353
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017354 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017355 return 0;
17356}
17357
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017358static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17359#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17360 struct wireless_dev *wdev,
17361#endif
17362#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17363 enum tx_power_setting type,
17364#else
17365 enum nl80211_tx_power_setting type,
17366#endif
17367 int dbm)
17368{
17369 int ret;
17370 vos_ssr_protect(__func__);
17371 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17372#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17373 wdev,
17374#endif
17375#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17376 type,
17377#else
17378 type,
17379#endif
17380 dbm);
17381 vos_ssr_unprotect(__func__);
17382
17383 return ret;
17384}
17385
Jeff Johnson295189b2012-06-20 16:38:30 -070017386/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017387 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017388 * This function is used to read the txpower
17389 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017390static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017391#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17392 struct wireless_dev *wdev,
17393#endif
17394 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070017395{
17396
17397 hdd_adapter_t *pAdapter;
17398 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017399 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017400
Jeff Johnsone7245742012-09-05 17:12:55 -070017401 ENTER();
17402
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017403 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017404 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017405 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017406 *dbm = 0;
17407 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017408 }
17409
Jeff Johnson295189b2012-06-20 16:38:30 -070017410 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
17411 if (NULL == pAdapter)
17412 {
17413 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
17414 return -ENOENT;
17415 }
17416
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017417 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17418 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
17419 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070017420 wlan_hdd_get_classAstats(pAdapter);
17421 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
17422
Jeff Johnsone7245742012-09-05 17:12:55 -070017423 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017424 return 0;
17425}
17426
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017427static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
17428#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17429 struct wireless_dev *wdev,
17430#endif
17431 int *dbm)
17432{
17433 int ret;
17434
17435 vos_ssr_protect(__func__);
17436 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
17437#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17438 wdev,
17439#endif
17440 dbm);
17441 vos_ssr_unprotect(__func__);
17442
17443 return ret;
17444}
17445
Dustin Brown8c1d4092017-07-28 18:08:01 +053017446/*
17447 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
17448 * @stats: summary stats to use as a source
17449 * @info: kernel station_info struct to use as a destination
17450 *
17451 * Return: None
17452 */
17453static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
17454 struct station_info *info)
17455{
17456 int i;
17457
17458 info->rx_packets = stats->rx_frm_cnt;
17459 info->tx_packets = 0;
17460 info->tx_retries = 0;
17461 info->tx_failed = 0;
17462
17463 for (i = 0; i < 4; ++i) {
17464 info->tx_packets += stats->tx_frm_cnt[i];
17465 info->tx_retries += stats->multiple_retry_cnt[i];
17466 info->tx_failed += stats->fail_cnt[i];
17467 }
17468
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017469#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
17470 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017471 info->filled |= STATION_INFO_TX_PACKETS |
17472 STATION_INFO_TX_RETRIES |
17473 STATION_INFO_TX_FAILED |
17474 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017475#else
17476 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
17477 BIT(NL80211_STA_INFO_TX_RETRIES) |
17478 BIT(NL80211_STA_INFO_TX_FAILED) |
17479 BIT(NL80211_STA_INFO_RX_PACKETS);
17480#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053017481}
17482
17483/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017484 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
17485 * @adapter: sap adapter pointer
17486 * @staid: station id of the client
17487 * @rssi: rssi value to fill
17488 *
17489 * Return: None
17490 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053017491void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017492wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
17493{
17494 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
17495
17496 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
17497}
17498
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017499#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
17500 !defined(WITH_BACKPORTS)
17501static inline void wlan_hdd_fill_station_info_signal(struct station_info
17502 *sinfo)
17503{
17504 sinfo->filled |= STATION_INFO_SIGNAL;
17505}
17506#else
17507static inline void wlan_hdd_fill_station_info_signal(struct station_info
17508 *sinfo)
17509{
17510 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
17511}
17512#endif
17513
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017514/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053017515 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
17516 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017517 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053017518 * @info: kernel station_info struct to populate
17519 *
17520 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
17521 * support "station dump" and "station get" for SAP vdevs, even though they
17522 * aren't technically stations.
17523 *
17524 * Return: errno
17525 */
17526static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017527wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
17528#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17529 const u8* mac,
17530#else
17531 u8* mac,
17532#endif
17533 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017534{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017535 v_MACADDR_t *peerMacAddr;
17536 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017537 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017538 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017539
17540 status = wlan_hdd_get_station_stats(adapter);
17541 if (!VOS_IS_STATUS_SUCCESS(status)) {
17542 hddLog(VOS_TRACE_LEVEL_ERROR,
17543 "Failed to get SAP stats; status:%d", status);
17544 return 0;
17545 }
17546
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017547 peerMacAddr = (v_MACADDR_t *)mac;
17548 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
17549 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
17550 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
17551
17552 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
17553 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017554 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017555 }
17556
Dustin Brown8c1d4092017-07-28 18:08:01 +053017557 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
17558
17559 return 0;
17560}
17561
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017562static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017563#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17564 const u8* mac,
17565#else
17566 u8* mac,
17567#endif
17568 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070017569{
17570 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
17571 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17572 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053017573 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017574
17575 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
17576 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070017577
17578 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
17579 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
17580 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
17581 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
17582 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
17583 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
17584 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017585 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017586 tANI_U16 myRate;
17587 tANI_U16 currentRate = 0;
17588 tANI_U8 maxSpeedMCS = 0;
17589 tANI_U8 maxMCSIdx = 0;
17590 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053017591 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070017592 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017593 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017594
Leo Chang6f8870f2013-03-26 18:11:36 -070017595#ifdef WLAN_FEATURE_11AC
17596 tANI_U32 vht_mcs_map;
17597 eDataRate11ACMaxMcs vhtMaxMcs;
17598#endif /* WLAN_FEATURE_11AC */
17599
Jeff Johnsone7245742012-09-05 17:12:55 -070017600 ENTER();
17601
Dustin Brown8c1d4092017-07-28 18:08:01 +053017602 status = wlan_hdd_validate_context(pHddCtx);
17603 if (0 != status)
17604 {
17605 return status;
17606 }
17607
17608 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017609 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053017610
Jeff Johnson295189b2012-06-20 16:38:30 -070017611 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17612 (0 == ssidlen))
17613 {
17614 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
17615 " Invalid ssidlen, %d", __func__, ssidlen);
17616 /*To keep GUI happy*/
17617 return 0;
17618 }
17619
Mukul Sharma811205f2014-07-09 21:07:30 +053017620 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17621 {
17622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17623 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053017624 /* return a cached value */
17625 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053017626 return 0;
17627 }
17628
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053017629 wlan_hdd_get_station_stats(pAdapter);
17630 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017631
Kiet Lam3b17fc82013-09-27 05:24:08 +053017632 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017633 wlan_hdd_get_snr(pAdapter, &snr);
17634 pHddStaCtx->conn_info.signal = sinfo->signal;
17635 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017636 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053017637
c_hpothu09f19542014-05-30 21:53:31 +053017638 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053017639 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
17640 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053017641 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053017642 {
17643 rate_flags = pAdapter->maxRateFlags;
17644 }
c_hpothu44ff4e02014-05-08 00:13:57 +053017645
Jeff Johnson295189b2012-06-20 16:38:30 -070017646 //convert to the UI units of 100kbps
17647 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
17648
17649#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070017650 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 -070017651 sinfo->signal,
17652 pCfg->reportMaxLinkSpeed,
17653 myRate,
17654 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017655 (int) pCfg->linkSpeedRssiMid,
17656 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070017657 (int) rate_flags,
17658 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070017659#endif //LINKSPEED_DEBUG_ENABLED
17660
17661 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
17662 {
17663 // we do not want to necessarily report the current speed
17664 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
17665 {
17666 // report the max possible speed
17667 rssidx = 0;
17668 }
17669 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
17670 {
17671 // report the max possible speed with RSSI scaling
17672 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
17673 {
17674 // report the max possible speed
17675 rssidx = 0;
17676 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017677 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070017678 {
17679 // report middle speed
17680 rssidx = 1;
17681 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017682 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
17683 {
17684 // report middle speed
17685 rssidx = 2;
17686 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017687 else
17688 {
17689 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017690 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070017691 }
17692 }
17693 else
17694 {
17695 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
17696 hddLog(VOS_TRACE_LEVEL_ERROR,
17697 "%s: Invalid value for reportMaxLinkSpeed: %u",
17698 __func__, pCfg->reportMaxLinkSpeed);
17699 rssidx = 0;
17700 }
17701
17702 maxRate = 0;
17703
17704 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017705 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
17706 OperationalRates, &ORLeng))
17707 {
17708 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17709 /*To keep GUI happy*/
17710 return 0;
17711 }
17712
Jeff Johnson295189b2012-06-20 16:38:30 -070017713 for (i = 0; i < ORLeng; i++)
17714 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017715 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017716 {
17717 /* Validate Rate Set */
17718 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
17719 {
17720 currentRate = supported_data_rate[j].supported_rate[rssidx];
17721 break;
17722 }
17723 }
17724 /* Update MAX rate */
17725 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17726 }
17727
17728 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017729 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
17730 ExtendedRates, &ERLeng))
17731 {
17732 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17733 /*To keep GUI happy*/
17734 return 0;
17735 }
17736
Jeff Johnson295189b2012-06-20 16:38:30 -070017737 for (i = 0; i < ERLeng; i++)
17738 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017739 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017740 {
17741 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
17742 {
17743 currentRate = supported_data_rate[j].supported_rate[rssidx];
17744 break;
17745 }
17746 }
17747 /* Update MAX rate */
17748 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17749 }
c_hpothu79aab322014-07-14 21:11:01 +053017750
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017751 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053017752 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017753 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053017754 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070017755 {
c_hpothu79aab322014-07-14 21:11:01 +053017756 if (rate_flags & eHAL_TX_RATE_VHT80)
17757 mode = 2;
17758 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
17759 mode = 1;
17760 else
17761 mode = 0;
17762
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017763 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
17764 MCSRates, &MCSLeng))
17765 {
17766 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17767 /*To keep GUI happy*/
17768 return 0;
17769 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017770 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070017771#ifdef WLAN_FEATURE_11AC
17772 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017773 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070017774 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017775 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017776 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070017777 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070017778 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017779 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017780 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017781 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070017782 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017783 maxMCSIdx = 7;
17784 }
17785 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
17786 {
17787 maxMCSIdx = 8;
17788 }
17789 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
17790 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017791 //VHT20 is supporting 0~8
17792 if (rate_flags & eHAL_TX_RATE_VHT20)
17793 maxMCSIdx = 8;
17794 else
17795 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070017796 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017797
c_hpothu79aab322014-07-14 21:11:01 +053017798 if (0 != rssidx)/*check for scaled */
17799 {
17800 //get middle rate MCS index if rssi=1/2
17801 for (i=0; i <= maxMCSIdx; i++)
17802 {
17803 if (sinfo->signal <= rssiMcsTbl[mode][i])
17804 {
17805 maxMCSIdx = i;
17806 break;
17807 }
17808 }
17809 }
17810
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017811 if (rate_flags & eHAL_TX_RATE_VHT80)
17812 {
17813 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
17814 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
17815 }
17816 else if (rate_flags & eHAL_TX_RATE_VHT40)
17817 {
17818 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
17819 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
17820 }
17821 else if (rate_flags & eHAL_TX_RATE_VHT20)
17822 {
17823 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
17824 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
17825 }
17826
Leo Chang6f8870f2013-03-26 18:11:36 -070017827 maxSpeedMCS = 1;
17828 if (currentRate > maxRate)
17829 {
17830 maxRate = currentRate;
17831 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017832
Leo Chang6f8870f2013-03-26 18:11:36 -070017833 }
17834 else
17835#endif /* WLAN_FEATURE_11AC */
17836 {
17837 if (rate_flags & eHAL_TX_RATE_HT40)
17838 {
17839 rateFlag |= 1;
17840 }
17841 if (rate_flags & eHAL_TX_RATE_SGI)
17842 {
17843 rateFlag |= 2;
17844 }
17845
Girish Gowli01abcee2014-07-31 20:18:55 +053017846 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053017847 if (rssidx == 1 || rssidx == 2)
17848 {
17849 //get middle rate MCS index if rssi=1/2
17850 for (i=0; i <= 7; i++)
17851 {
17852 if (sinfo->signal <= rssiMcsTbl[mode][i])
17853 {
17854 temp = i+1;
17855 break;
17856 }
17857 }
17858 }
c_hpothu79aab322014-07-14 21:11:01 +053017859
17860 for (i = 0; i < MCSLeng; i++)
17861 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017862 for (j = 0; j < temp; j++)
17863 {
17864 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
17865 {
17866 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017867 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017868 break;
17869 }
17870 }
17871 if ((j < temp) && (currentRate > maxRate))
17872 {
17873 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070017874 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017875 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017876 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017877 }
17878 }
17879
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017880 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
17881 {
17882 maxRate = myRate;
17883 maxSpeedMCS = 1;
17884 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17885 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017886 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053017887 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070017888 {
17889 maxRate = myRate;
17890 if (rate_flags & eHAL_TX_RATE_LEGACY)
17891 {
17892 maxSpeedMCS = 0;
17893 }
17894 else
17895 {
17896 maxSpeedMCS = 1;
17897 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17898 }
17899 }
17900
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017901 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070017902 {
17903 sinfo->txrate.legacy = maxRate;
17904#ifdef LINKSPEED_DEBUG_ENABLED
17905 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
17906#endif //LINKSPEED_DEBUG_ENABLED
17907 }
17908 else
17909 {
17910 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070017911#ifdef WLAN_FEATURE_11AC
17912 sinfo->txrate.nss = 1;
17913 if (rate_flags & eHAL_TX_RATE_VHT80)
17914 {
17915 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017916#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
17917 defined(WITH_BACKPORTS)
17918 sinfo->txrate.bw = RATE_INFO_BW_80;
17919#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017920 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017921#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070017922 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017923 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070017924 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017925 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017926#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
17927 defined(WITH_BACKPORTS)
17928 sinfo->txrate.bw = RATE_INFO_BW_40;
17929#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017930 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017931#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017932 }
17933 else if (rate_flags & eHAL_TX_RATE_VHT20)
17934 {
17935 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17936 }
17937#endif /* WLAN_FEATURE_11AC */
17938 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
17939 {
17940 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17941 if (rate_flags & eHAL_TX_RATE_HT40)
17942 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017943#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
17944 defined(WITH_BACKPORTS)
17945 sinfo->txrate.bw = RATE_INFO_BW_40;
17946#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017947 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017948#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017949 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017950 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017951 if (rate_flags & eHAL_TX_RATE_SGI)
17952 {
17953 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17954 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017955
Jeff Johnson295189b2012-06-20 16:38:30 -070017956#ifdef LINKSPEED_DEBUG_ENABLED
17957 pr_info("Reporting MCS rate %d flags %x\n",
17958 sinfo->txrate.mcs,
17959 sinfo->txrate.flags );
17960#endif //LINKSPEED_DEBUG_ENABLED
17961 }
17962 }
17963 else
17964 {
17965 // report current rate instead of max rate
17966
17967 if (rate_flags & eHAL_TX_RATE_LEGACY)
17968 {
17969 //provide to the UI in units of 100kbps
17970 sinfo->txrate.legacy = myRate;
17971#ifdef LINKSPEED_DEBUG_ENABLED
17972 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
17973#endif //LINKSPEED_DEBUG_ENABLED
17974 }
17975 else
17976 {
17977 //must be MCS
17978 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017979#ifdef WLAN_FEATURE_11AC
17980 sinfo->txrate.nss = 1;
17981 if (rate_flags & eHAL_TX_RATE_VHT80)
17982 {
17983 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17984 }
17985 else
17986#endif /* WLAN_FEATURE_11AC */
17987 {
17988 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17989 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017990 if (rate_flags & eHAL_TX_RATE_SGI)
17991 {
17992 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17993 }
17994 if (rate_flags & eHAL_TX_RATE_HT40)
17995 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017996#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
17997 defined(WITH_BACKPORTS)
17998 sinfo->txrate.bw = RATE_INFO_BW_40;
17999#else
Jeff Johnson295189b2012-06-20 16:38:30 -070018000 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018001#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018002 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018003#ifdef WLAN_FEATURE_11AC
18004 else if (rate_flags & eHAL_TX_RATE_VHT80)
18005 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018006#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18007 defined(WITH_BACKPORTS)
18008 sinfo->txrate.bw = RATE_INFO_BW_80;
18009#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018010 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018011#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018012 }
18013#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018014#ifdef LINKSPEED_DEBUG_ENABLED
18015 pr_info("Reporting actual MCS rate %d flags %x\n",
18016 sinfo->txrate.mcs,
18017 sinfo->txrate.flags );
18018#endif //LINKSPEED_DEBUG_ENABLED
18019 }
18020 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018021
18022#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18023 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018024 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018025#else
18026 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18027#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018028
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018029 sinfo->tx_packets =
18030 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18031 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18032 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18033 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18034
18035 sinfo->tx_retries =
18036 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18037 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18038 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18039 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18040
18041 sinfo->tx_failed =
18042 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18043 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18044 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18045 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18046
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018047#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18048 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018049 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018050 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018051 STATION_INFO_TX_PACKETS |
18052 STATION_INFO_TX_RETRIES |
18053 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018054#else
18055 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18056 BIT(NL80211_STA_INFO_TX_PACKETS) |
18057 BIT(NL80211_STA_INFO_TX_RETRIES) |
18058 BIT(NL80211_STA_INFO_TX_FAILED);
18059#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018060
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018061 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018062
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018063 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18064 &sinfo->txrate, sizeof(sinfo->txrate));
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018065 if (rate_flags & eHAL_TX_RATE_LEGACY)
18066 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18067 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18068 sinfo->rx_packets);
18069 else
18070 hddLog(LOG1,
18071 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18072 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18073 sinfo->tx_packets, sinfo->rx_packets);
18074
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018075 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18076 TRACE_CODE_HDD_CFG80211_GET_STA,
18077 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018078 EXIT();
18079 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018080}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018081#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18082static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18083 const u8* mac, struct station_info *sinfo)
18084#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018085static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18086 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018087#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018088{
18089 int ret;
18090
18091 vos_ssr_protect(__func__);
18092 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18093 vos_ssr_unprotect(__func__);
18094
18095 return ret;
18096}
18097
18098static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018099 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018100{
18101 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018102 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018103 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018104 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018105
Jeff Johnsone7245742012-09-05 17:12:55 -070018106 ENTER();
18107
Jeff Johnson295189b2012-06-20 16:38:30 -070018108 if (NULL == pAdapter)
18109 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018110 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018111 return -ENODEV;
18112 }
18113
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018114 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18115 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18116 pAdapter->sessionId, timeout));
18117
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018118 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018119 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018120 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018121 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018122 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018123 }
18124
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018125 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
18126 (TRUE == pHddCtx->hdd_wlan_suspended) &&
18127 (pHddCtx->cfg_ini->fhostArpOffload) &&
18128 (eConnectionState_Associated ==
18129 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
18130 {
Amar Singhald53568e2013-09-26 11:03:45 -070018131
18132 hddLog(VOS_TRACE_LEVEL_INFO,
18133 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053018134 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018135 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18136 {
18137 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018138 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018139 __func__, vos_status);
18140 }
18141 }
18142
Jeff Johnson295189b2012-06-20 16:38:30 -070018143 /**The get power cmd from the supplicant gets updated by the nl only
18144 *on successful execution of the function call
18145 *we are oppositely mapped w.r.t mode in the driver
18146 **/
18147 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
18148
18149 if (VOS_STATUS_E_FAILURE == vos_status)
18150 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18152 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018153 return -EINVAL;
18154 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018155 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018156 return 0;
18157}
18158
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018159static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
18160 struct net_device *dev, bool mode, int timeout)
18161{
18162 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018163
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018164 vos_ssr_protect(__func__);
18165 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
18166 vos_ssr_unprotect(__func__);
18167
18168 return ret;
18169}
Sushant Kaushik084f6592015-09-10 13:11:56 +053018170
Jeff Johnson295189b2012-06-20 16:38:30 -070018171#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018172static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
18173 struct net_device *netdev,
18174 u8 key_index)
18175{
18176 ENTER();
18177 return 0;
18178}
18179
Jeff Johnson295189b2012-06-20 16:38:30 -070018180static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018181 struct net_device *netdev,
18182 u8 key_index)
18183{
18184 int ret;
18185 vos_ssr_protect(__func__);
18186 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
18187 vos_ssr_unprotect(__func__);
18188 return ret;
18189}
18190#endif //LINUX_VERSION_CODE
18191
18192#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18193static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18194 struct net_device *dev,
18195 struct ieee80211_txq_params *params)
18196{
18197 ENTER();
18198 return 0;
18199}
18200#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18201static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18202 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018203{
Jeff Johnsone7245742012-09-05 17:12:55 -070018204 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070018205 return 0;
18206}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018207#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070018208
18209#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18210static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018211 struct net_device *dev,
18212 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018213{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018214 int ret;
18215
18216 vos_ssr_protect(__func__);
18217 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
18218 vos_ssr_unprotect(__func__);
18219 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018220}
18221#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18222static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
18223 struct ieee80211_txq_params *params)
18224{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018225 int ret;
18226
18227 vos_ssr_protect(__func__);
18228 ret = __wlan_hdd_set_txq_params(wiphy, params);
18229 vos_ssr_unprotect(__func__);
18230 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018231}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018232#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018233
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018234static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018235 struct net_device *dev,
18236 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070018237{
18238 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018239 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018240 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018241 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018242 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018243 v_CONTEXT_t pVosContext = NULL;
18244 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018245
Jeff Johnsone7245742012-09-05 17:12:55 -070018246 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018247
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018248 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070018249 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018250 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018251 return -EINVAL;
18252 }
18253
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018254 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18255 TRACE_CODE_HDD_CFG80211_DEL_STA,
18256 pAdapter->sessionId, pAdapter->device_mode));
18257
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018258 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18259 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018260 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018261 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018262 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018263 }
18264
Jeff Johnson295189b2012-06-20 16:38:30 -070018265 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018266 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018267 )
18268 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018269 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
18270 pSapCtx = VOS_GET_SAP_CB(pVosContext);
18271 if(pSapCtx == NULL){
18272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18273 FL("psapCtx is NULL"));
18274 return -ENOENT;
18275 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053018276 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
18277 {
18278 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
18279 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
18280 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
18281 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018282 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070018283 {
18284 v_U16_t i;
18285 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
18286 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018287 if ((pSapCtx->aStaInfo[i].isUsed) &&
18288 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070018289 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018290 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018291 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018292 ETHER_ADDR_LEN);
18293
Jeff Johnson295189b2012-06-20 16:38:30 -070018294 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018295 "%s: Delete STA with MAC::"
18296 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018297 __func__,
18298 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18299 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018300 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018301 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018302 }
18303 }
18304 }
18305 else
18306 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018307
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018308 vos_status = hdd_softap_GetStaId(pAdapter,
18309 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018310 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18311 {
18312 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018313 "%s: Skip this DEL STA as this is not used::"
18314 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018315 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018316 return -ENOENT;
18317 }
18318
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018319 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018320 {
18321 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018322 "%s: Skip this DEL STA as deauth is in progress::"
18323 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018324 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018325 return -ENOENT;
18326 }
18327
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018328 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018329
Jeff Johnson295189b2012-06-20 16:38:30 -070018330 hddLog(VOS_TRACE_LEVEL_INFO,
18331 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018332 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018333 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018334 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018335
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018336 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018337 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18338 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018339 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018340 hddLog(VOS_TRACE_LEVEL_INFO,
18341 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018342 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018343 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018344 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018345 return -ENOENT;
18346 }
18347
Jeff Johnson295189b2012-06-20 16:38:30 -070018348 }
18349 }
18350
18351 EXIT();
18352
18353 return 0;
18354}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018355
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018356#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018357int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018358 struct net_device *dev,
18359 struct station_del_parameters *param)
18360#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018361#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018362int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018363 struct net_device *dev, const u8 *mac)
18364#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018365int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018366 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018367#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018368#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018369{
18370 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018371 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018372
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018373 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018374
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018375#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018376 if (NULL == param) {
18377 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018378 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018379 return -EINVAL;
18380 }
18381
18382 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
18383 param->subtype, &delStaParams);
18384
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018385#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053018386 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018387 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018388#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018389 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
18390
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018391 vos_ssr_unprotect(__func__);
18392
18393 return ret;
18394}
18395
18396static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018397 struct net_device *dev,
18398#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18399 const u8 *mac,
18400#else
18401 u8 *mac,
18402#endif
18403 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018404{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018405 hdd_adapter_t *pAdapter;
18406 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018407 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018408#ifdef FEATURE_WLAN_TDLS
18409 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018410
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018411 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018412
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018413 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18414 if (NULL == pAdapter)
18415 {
18416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18417 "%s: Adapter is NULL",__func__);
18418 return -EINVAL;
18419 }
18420 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18421 status = wlan_hdd_validate_context(pHddCtx);
18422 if (0 != status)
18423 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018424 return status;
18425 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018426
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018427 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18428 TRACE_CODE_HDD_CFG80211_ADD_STA,
18429 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018430 mask = params->sta_flags_mask;
18431
18432 set = params->sta_flags_set;
18433
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018434 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018435 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
18436 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018437
18438 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
18439 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080018440 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018441 }
18442 }
18443#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018444 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018445 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018446}
18447
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018448#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18449static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18450 struct net_device *dev, const u8 *mac,
18451 struct station_parameters *params)
18452#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018453static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18454 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018455#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018456{
18457 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018458
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018459 vos_ssr_protect(__func__);
18460 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
18461 vos_ssr_unprotect(__func__);
18462
18463 return ret;
18464}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018465#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070018466
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018467static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070018468 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018469{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018470 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18471 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018472 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018473 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018474 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018475 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070018476
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018477 ENTER();
18478
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018479 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018480 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018481 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018482 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018483 return -EINVAL;
18484 }
18485
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018486 if (!pmksa) {
18487 hddLog(LOGE, FL("pmksa is NULL"));
18488 return -EINVAL;
18489 }
18490
18491 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070018492 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018493 pmksa->bssid, pmksa->pmkid);
18494 return -EINVAL;
18495 }
18496
18497 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
18498 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18499
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018500 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18501 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018502 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018503 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018504 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018505 }
18506
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018507 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018508 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18509
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018510 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
18511 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018512
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018513 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018514 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018515 &pmk_id, 1, FALSE);
18516
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018517 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18518 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
18519 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018520
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018521 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018522 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018523}
18524
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018525static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
18526 struct cfg80211_pmksa *pmksa)
18527{
18528 int ret;
18529
18530 vos_ssr_protect(__func__);
18531 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
18532 vos_ssr_unprotect(__func__);
18533
18534 return ret;
18535}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018536
Wilson Yang6507c4e2013-10-01 20:11:19 -070018537
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018538static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070018539 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018540{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018541 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18542 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018543 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018544 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018545
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018546 ENTER();
18547
Wilson Yang6507c4e2013-10-01 20:11:19 -070018548 /* Validate pAdapter */
18549 if (NULL == pAdapter)
18550 {
18551 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
18552 return -EINVAL;
18553 }
18554
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018555 if (!pmksa) {
18556 hddLog(LOGE, FL("pmksa is NULL"));
18557 return -EINVAL;
18558 }
18559
18560 if (!pmksa->bssid) {
18561 hddLog(LOGE, FL("pmksa->bssid is NULL"));
18562 return -EINVAL;
18563 }
18564
Kiet Lam98c46a12014-10-31 15:34:57 -070018565 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
18566 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18567
Wilson Yang6507c4e2013-10-01 20:11:19 -070018568 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18569 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018570 if (0 != status)
18571 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018572 return status;
18573 }
18574
18575 /*Retrieve halHandle*/
18576 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18577
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018578 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18579 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
18580 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018581 /* Delete the PMKID CSR cache */
18582 if (eHAL_STATUS_SUCCESS !=
18583 sme_RoamDelPMKIDfromCache(halHandle,
18584 pAdapter->sessionId, pmksa->bssid, FALSE)) {
18585 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
18586 MAC_ADDR_ARRAY(pmksa->bssid));
18587 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018588 }
18589
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018590 EXIT();
18591 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018592}
18593
Wilson Yang6507c4e2013-10-01 20:11:19 -070018594
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018595static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
18596 struct cfg80211_pmksa *pmksa)
18597{
18598 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018599
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018600 vos_ssr_protect(__func__);
18601 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
18602 vos_ssr_unprotect(__func__);
18603
18604 return ret;
18605
18606}
18607
18608static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018609{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018610 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18611 tHalHandle halHandle;
18612 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018613 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018614
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018615 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070018616
18617 /* Validate pAdapter */
18618 if (NULL == pAdapter)
18619 {
18620 hddLog(VOS_TRACE_LEVEL_ERROR,
18621 "%s: Invalid Adapter" ,__func__);
18622 return -EINVAL;
18623 }
18624
18625 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18626 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018627 if (0 != status)
18628 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018629 return status;
18630 }
18631
18632 /*Retrieve halHandle*/
18633 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18634
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018635 /* Flush the PMKID cache in CSR */
18636 if (eHAL_STATUS_SUCCESS !=
18637 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
18638 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
18639 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018640 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018641 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080018642 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018643}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018644
18645static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
18646{
18647 int ret;
18648
18649 vos_ssr_protect(__func__);
18650 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
18651 vos_ssr_unprotect(__func__);
18652
18653 return ret;
18654}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018655#endif
18656
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018657#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018658static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
18659 struct net_device *dev,
18660 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018661{
18662 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18663 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018664 hdd_context_t *pHddCtx;
18665 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018666
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018667 ENTER();
18668
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018669 if (NULL == pAdapter)
18670 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018671 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018672 return -ENODEV;
18673 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018674 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18675 ret = wlan_hdd_validate_context(pHddCtx);
18676 if (0 != ret)
18677 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018678 return ret;
18679 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018680 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018681 if (NULL == pHddStaCtx)
18682 {
18683 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
18684 return -EINVAL;
18685 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018686
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018687 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18688 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
18689 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018690 // Added for debug on reception of Re-assoc Req.
18691 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
18692 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018693 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018694 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080018695 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018696 }
18697
18698#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080018699 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018700 ftie->ie_len);
18701#endif
18702
18703 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053018704 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
18705 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018706 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018707
18708 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018709 return 0;
18710}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018711
18712static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
18713 struct net_device *dev,
18714 struct cfg80211_update_ft_ies_params *ftie)
18715{
18716 int ret;
18717
18718 vos_ssr_protect(__func__);
18719 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
18720 vos_ssr_unprotect(__func__);
18721
18722 return ret;
18723}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018724#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018725
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018726#ifdef FEATURE_WLAN_SCAN_PNO
18727
18728void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
18729 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
18730{
18731 int ret;
18732 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
18733 hdd_context_t *pHddCtx;
18734
Nirav Shah80830bf2013-12-31 16:35:12 +053018735 ENTER();
18736
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018737 if (NULL == pAdapter)
18738 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018740 "%s: HDD adapter is Null", __func__);
18741 return ;
18742 }
18743
18744 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18745 if (NULL == pHddCtx)
18746 {
18747 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18748 "%s: HDD context is Null!!!", __func__);
18749 return ;
18750 }
18751
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018752 spin_lock(&pHddCtx->schedScan_lock);
18753 if (TRUE == pHddCtx->isWiphySuspended)
18754 {
18755 pHddCtx->isSchedScanUpdatePending = TRUE;
18756 spin_unlock(&pHddCtx->schedScan_lock);
18757 hddLog(VOS_TRACE_LEVEL_INFO,
18758 "%s: Update cfg80211 scan database after it resume", __func__);
18759 return ;
18760 }
18761 spin_unlock(&pHddCtx->schedScan_lock);
18762
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018763 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
18764
18765 if (0 > ret)
18766 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053018767 else
18768 {
18769 /* Acquire wakelock to handle the case where APP's tries to suspend
18770 * immediatly after the driver gets connect request(i.e after pno)
18771 * from supplicant, this result in app's is suspending and not able
18772 * to process the connect request to AP */
18773 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
18774 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018775 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18777 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018778}
18779
18780/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018781 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018782 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018783 */
18784static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
18785{
18786 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
18787 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018788 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018789 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18790 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053018791
18792 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
18793 {
18794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18795 "%s: PNO is allowed only in STA interface", __func__);
18796 return eHAL_STATUS_FAILURE;
18797 }
18798
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018799 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
18800
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018801 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053018802 * active sessions. PNO is allowed only in case when sap session
18803 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018804 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018805 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
18806 {
18807 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018808 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018809
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018810 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
18811 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
18812 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
18813 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053018814 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
18815 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053018816 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018817 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018818 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018819 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018820 }
18821 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
18822 pAdapterNode = pNext;
18823 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018824 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018825}
18826
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018827void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
18828{
18829 hdd_adapter_t *pAdapter = callbackContext;
18830 hdd_context_t *pHddCtx;
18831
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018832 ENTER();
18833
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018834 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
18835 {
18836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18837 FL("Invalid adapter or adapter has invalid magic"));
18838 return;
18839 }
18840
18841 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18842 if (0 != wlan_hdd_validate_context(pHddCtx))
18843 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018844 return;
18845 }
18846
c_hpothub53c45d2014-08-18 16:53:14 +053018847 if (VOS_STATUS_SUCCESS != status)
18848 {
18849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018850 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053018851 pHddCtx->isPnoEnable = FALSE;
18852 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018853
18854 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
18855 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018856 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018857}
18858
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018859#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
18860 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
18861/**
18862 * hdd_config_sched_scan_plan() - configures the sched scan plans
18863 * from the framework.
18864 * @pno_req: pointer to PNO scan request
18865 * @request: pointer to scan request from framework
18866 *
18867 * Return: None
18868 */
18869static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
18870 struct cfg80211_sched_scan_request *request,
18871 hdd_context_t *hdd_ctx)
18872{
18873 v_U32_t i = 0;
18874
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018875 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018876 for (i = 0; i < request->n_scan_plans; i++)
18877 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018878 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
18879 request->scan_plans[i].iterations;
18880 pno_req->scanTimers.aTimerValues[i].uTimerValue =
18881 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018882 }
18883}
18884#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018885static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018886 struct cfg80211_sched_scan_request *request,
18887 hdd_context_t *hdd_ctx)
18888{
18889 v_U32_t i, temp_int;
18890 /* Driver gets only one time interval which is hardcoded in
18891 * supplicant for 10000ms. Taking power consumption into account 6
18892 * timers will be used, Timervalue is increased exponentially
18893 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
18894 * timer is configurable through INI param gPNOScanTimerRepeatValue.
18895 * If it is set to 0 only one timer will be used and PNO scan cycle
18896 * will be repeated after each interval specified by supplicant
18897 * till PNO is disabled.
18898 */
18899 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018900 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018901 HDD_PNO_SCAN_TIMERS_SET_ONE;
18902 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018903 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018904 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
18905
18906 temp_int = (request->interval)/1000;
18907 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18908 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
18909 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018910 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018911 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018912 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018913 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018914 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018915 temp_int *= 2;
18916 }
18917 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018918 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018919}
18920#endif
18921
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018922/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018923 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
18924 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018925 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018926static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018927 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18928{
18929 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018930 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018931 hdd_context_t *pHddCtx;
18932 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018933 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053018934 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
18935 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018936 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
18937 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018938 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018939 hdd_config_t *pConfig = NULL;
18940 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018941
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018942 ENTER();
18943
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018944 if (NULL == pAdapter)
18945 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018946 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018947 "%s: HDD adapter is Null", __func__);
18948 return -ENODEV;
18949 }
18950
18951 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018952 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018953
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018954 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018955 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018956 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018957 }
18958
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018959 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018960 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18961 if (NULL == hHal)
18962 {
18963 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18964 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018965 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018966 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018967 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18968 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
18969 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018970 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053018971 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018972 {
18973 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18974 "%s: aborting the existing scan is unsuccessfull", __func__);
18975 return -EBUSY;
18976 }
18977
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018978 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018979 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018981 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018982 return -EBUSY;
18983 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018984
c_hpothu37f21312014-04-09 21:49:54 +053018985 if (TRUE == pHddCtx->isPnoEnable)
18986 {
18987 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
18988 FL("already PNO is enabled"));
18989 return -EBUSY;
18990 }
c_hpothu225aa7c2014-10-22 17:45:13 +053018991
18992 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
18993 {
18994 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18995 "%s: abort ROC failed ", __func__);
18996 return -EBUSY;
18997 }
18998
c_hpothu37f21312014-04-09 21:49:54 +053018999 pHddCtx->isPnoEnable = TRUE;
19000
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019001 pnoRequest.enable = 1; /*Enable PNO */
19002 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019003
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019004 if (( !pnoRequest.ucNetworksCount ) ||
19005 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019006 {
19007 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019008 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019009 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019010 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019011 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019012 goto error;
19013 }
19014
19015 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
19016 {
19017 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019018 "%s: Incorrect number of channels %d",
19019 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019020 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019021 goto error;
19022 }
19023
19024 /* Framework provides one set of channels(all)
19025 * common for all saved profile */
19026 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
19027 channels_allowed, &num_channels_allowed))
19028 {
19029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19030 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019031 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019032 goto error;
19033 }
19034 /* Checking each channel against allowed channel list */
19035 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053019036 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019037 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019038 char chList [(request->n_channels*5)+1];
19039 int len;
19040 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019041 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019042 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019043 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019044 if (request->channels[i]->hw_value == channels_allowed[indx])
19045 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019046 if ((!pConfig->enableDFSPnoChnlScan) &&
19047 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
19048 {
19049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19050 "%s : Dropping DFS channel : %d",
19051 __func__,channels_allowed[indx]);
19052 num_ignore_dfs_ch++;
19053 break;
19054 }
19055
Nirav Shah80830bf2013-12-31 16:35:12 +053019056 valid_ch[num_ch++] = request->channels[i]->hw_value;
19057 len += snprintf(chList+len, 5, "%d ",
19058 request->channels[i]->hw_value);
19059 break ;
19060 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019061 }
19062 }
Nirav Shah80830bf2013-12-31 16:35:12 +053019063 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019064
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019065 /*If all channels are DFS and dropped, then ignore the PNO request*/
19066 if (num_ignore_dfs_ch == request->n_channels)
19067 {
19068 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19069 "%s : All requested channels are DFS channels", __func__);
19070 ret = -EINVAL;
19071 goto error;
19072 }
19073 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019074
19075 pnoRequest.aNetworks =
19076 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19077 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019078 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019079 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19080 FL("failed to allocate memory aNetworks %u"),
19081 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19082 goto error;
19083 }
19084 vos_mem_zero(pnoRequest.aNetworks,
19085 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19086
19087 /* Filling per profile params */
19088 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
19089 {
19090 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019091 request->match_sets[i].ssid.ssid_len;
19092
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019093 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
19094 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019095 {
19096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019097 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019098 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019099 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019100 goto error;
19101 }
19102
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019103 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019104 request->match_sets[i].ssid.ssid,
19105 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019106 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19107 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019108 i, pnoRequest.aNetworks[i].ssId.ssId);
19109 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
19110 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
19111 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019112
19113 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019114 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
19115 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019116
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019117 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019118 }
19119
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019120 for (i = 0; i < request->n_ssids; i++)
19121 {
19122 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019123 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019124 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019125 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019126 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019127 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019128 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019129 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019130 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019131 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019132 break;
19133 }
19134 j++;
19135 }
19136 }
19137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19138 "Number of hidden networks being Configured = %d",
19139 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080019141 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019142
19143 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19144 if (pnoRequest.p24GProbeTemplate == NULL)
19145 {
19146 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19147 FL("failed to allocate memory p24GProbeTemplate %u"),
19148 SIR_PNO_MAX_PB_REQ_SIZE);
19149 goto error;
19150 }
19151
19152 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19153 if (pnoRequest.p5GProbeTemplate == NULL)
19154 {
19155 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19156 FL("failed to allocate memory p5GProbeTemplate %u"),
19157 SIR_PNO_MAX_PB_REQ_SIZE);
19158 goto error;
19159 }
19160
19161 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19162 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19163
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053019164 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
19165 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019166 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019167 pnoRequest.us24GProbeTemplateLen = request->ie_len;
19168 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
19169 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019170
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019171 pnoRequest.us5GProbeTemplateLen = request->ie_len;
19172 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
19173 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019174 }
19175
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019176 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053019177
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019178 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019179
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019180 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019181 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19182 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019183 pAdapter->pno_req_status = 0;
19184
Nirav Shah80830bf2013-12-31 16:35:12 +053019185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19186 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019187 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
19188 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053019189
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019190 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019191 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019192 hdd_cfg80211_sched_scan_done_callback, pAdapter);
19193 if (eHAL_STATUS_SUCCESS != status)
19194 {
19195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019196 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019197 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019198 goto error;
19199 }
19200
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019201 ret = wait_for_completion_timeout(
19202 &pAdapter->pno_comp_var,
19203 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19204 if (0 >= ret)
19205 {
19206 // Did not receive the response for PNO enable in time.
19207 // Assuming the PNO enable was success.
19208 // Returning error from here, because we timeout, results
19209 // in side effect of Wifi (Wifi Setting) not to work.
19210 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19211 FL("Timed out waiting for PNO to be Enabled"));
19212 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019213 }
19214
19215 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053019216 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019217
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019218error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19220 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053019221 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019222 if (pnoRequest.aNetworks)
19223 vos_mem_free(pnoRequest.aNetworks);
19224 if (pnoRequest.p24GProbeTemplate)
19225 vos_mem_free(pnoRequest.p24GProbeTemplate);
19226 if (pnoRequest.p5GProbeTemplate)
19227 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019228
19229 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019230 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019231}
19232
19233/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019234 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
19235 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019236 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019237static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
19238 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19239{
19240 int ret;
19241
19242 vos_ssr_protect(__func__);
19243 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
19244 vos_ssr_unprotect(__func__);
19245
19246 return ret;
19247}
19248
19249/*
19250 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
19251 * Function to disable PNO
19252 */
19253static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019254 struct net_device *dev)
19255{
19256 eHalStatus status = eHAL_STATUS_FAILURE;
19257 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19258 hdd_context_t *pHddCtx;
19259 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019260 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019261 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019262
19263 ENTER();
19264
19265 if (NULL == pAdapter)
19266 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019267 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019268 "%s: HDD adapter is Null", __func__);
19269 return -ENODEV;
19270 }
19271
19272 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019273
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019274 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019275 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019277 "%s: HDD context is Null", __func__);
19278 return -ENODEV;
19279 }
19280
19281 /* The return 0 is intentional when isLogpInProgress and
19282 * isLoadUnloadInProgress. We did observe a crash due to a return of
19283 * failure in sched_scan_stop , especially for a case where the unload
19284 * of the happens at the same time. The function __cfg80211_stop_sched_scan
19285 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
19286 * success. If it returns a failure , then its next invocation due to the
19287 * clean up of the second interface will have the dev pointer corresponding
19288 * to the first one leading to a crash.
19289 */
19290 if (pHddCtx->isLogpInProgress)
19291 {
19292 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19293 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019294 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019295 return ret;
19296 }
19297
Mihir Shete18156292014-03-11 15:38:30 +053019298 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019299 {
19300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19301 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19302 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019303 }
19304
19305 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19306 if (NULL == hHal)
19307 {
19308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19309 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019310 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019311 }
19312
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019313 pnoRequest.enable = 0; /* Disable PNO */
19314 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019315
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019316 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19317 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19318 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019319
19320 INIT_COMPLETION(pAdapter->pno_comp_var);
19321 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19322 pnoRequest.callbackContext = pAdapter;
19323 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019324 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019325 pAdapter->sessionId,
19326 NULL, pAdapter);
19327 if (eHAL_STATUS_SUCCESS != status)
19328 {
19329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19330 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019331 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019332 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019333 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019334 ret = wait_for_completion_timeout(
19335 &pAdapter->pno_comp_var,
19336 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19337 if (0 >= ret)
19338 {
19339 // Did not receive the response for PNO disable in time.
19340 // Assuming the PNO disable was success.
19341 // Returning error from here, because we timeout, results
19342 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019344 FL("Timed out waiting for PNO to be disabled"));
19345 ret = 0;
19346 }
19347
19348 ret = pAdapter->pno_req_status;
19349 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019350
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019351error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019353 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019354
19355 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019356 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019357}
19358
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019359/*
19360 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19361 * NL interface to disable PNO
19362 */
19363static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19364 struct net_device *dev)
19365{
19366 int ret;
19367
19368 vos_ssr_protect(__func__);
19369 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19370 vos_ssr_unprotect(__func__);
19371
19372 return ret;
19373}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019374#endif /*FEATURE_WLAN_SCAN_PNO*/
19375
19376
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019377#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019378#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019379static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19380 struct net_device *dev,
19381 u8 *peer, u8 action_code,
19382 u8 dialog_token,
19383 u16 status_code, u32 peer_capability,
19384 const u8 *buf, size_t len)
19385#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019386#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
19387 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019388static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19389 struct net_device *dev,
19390 const u8 *peer, u8 action_code,
19391 u8 dialog_token, u16 status_code,
19392 u32 peer_capability, bool initiator,
19393 const u8 *buf, size_t len)
19394#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19395static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19396 struct net_device *dev,
19397 const u8 *peer, u8 action_code,
19398 u8 dialog_token, u16 status_code,
19399 u32 peer_capability, const u8 *buf,
19400 size_t len)
19401#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19402static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19403 struct net_device *dev,
19404 u8 *peer, u8 action_code,
19405 u8 dialog_token,
19406 u16 status_code, u32 peer_capability,
19407 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019408#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019409static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19410 struct net_device *dev,
19411 u8 *peer, u8 action_code,
19412 u8 dialog_token,
19413 u16 status_code, const u8 *buf,
19414 size_t len)
19415#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019416#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019417{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019418 hdd_adapter_t *pAdapter;
19419 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019420 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070019421 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080019422 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070019423 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019424 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019425 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019426#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019427 u32 peer_capability = 0;
19428#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019429 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019430 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019431 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019432
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019433 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19434 if (NULL == pAdapter)
19435 {
19436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19437 "%s: Adapter is NULL",__func__);
19438 return -EINVAL;
19439 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019440 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19441 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
19442 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019443
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019444 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019445 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019446 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019448 "Invalid arguments");
19449 return -EINVAL;
19450 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019451
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019452 if (pHddCtx->isLogpInProgress)
19453 {
19454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19455 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053019456 wlan_hdd_tdls_set_link_status(pAdapter,
19457 peer,
19458 eTDLS_LINK_IDLE,
19459 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019460 return -EBUSY;
19461 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019462
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019463 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
19464 {
19465 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19466 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19467 return -EAGAIN;
19468 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019469
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019470 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
19471 if (!pHddTdlsCtx) {
19472 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19473 "%s: pHddTdlsCtx not valid.", __func__);
19474 }
19475
Hoonki Lee27511902013-03-14 18:19:06 -070019476 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019477 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019478 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019479 "%s: TDLS mode is disabled OR not enabled in FW."
19480 MAC_ADDRESS_STR " action %d declined.",
19481 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019482 return -ENOTSUPP;
19483 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019484
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019485 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19486
19487 if( NULL == pHddStaCtx )
19488 {
19489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19490 "%s: HDD station context NULL ",__func__);
19491 return -EINVAL;
19492 }
19493
19494 /* STA should be connected and authenticated
19495 * before sending any TDLS frames
19496 */
19497 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
19498 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
19499 {
19500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19501 "STA is not connected or unauthenticated. "
19502 "connState %u, uIsAuthenticated %u",
19503 pHddStaCtx->conn_info.connState,
19504 pHddStaCtx->conn_info.uIsAuthenticated);
19505 return -EAGAIN;
19506 }
19507
Hoonki Lee27511902013-03-14 18:19:06 -070019508 /* other than teardown frame, other mgmt frames are not sent if disabled */
19509 if (SIR_MAC_TDLS_TEARDOWN != action_code)
19510 {
19511 /* if tdls_mode is disabled to respond to peer's request */
19512 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
19513 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019515 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019516 " TDLS mode is disabled. action %d declined.",
19517 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070019518
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019519 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070019520 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053019521
19522 if (vos_max_concurrent_connections_reached())
19523 {
19524 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
19525 return -EINVAL;
19526 }
Hoonki Lee27511902013-03-14 18:19:06 -070019527 }
19528
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019529 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
19530 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053019531 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019532 {
19533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019534 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019535 " TDLS setup is ongoing. action %d declined.",
19536 __func__, MAC_ADDR_ARRAY(peer), action_code);
19537 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019538 }
19539 }
19540
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019541 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
19542 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080019543 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019544 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19545 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019546 {
19547 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
19548 we return error code at 'add_station()'. Hence we have this
19549 check again in addtion to add_station().
19550 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019551 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019552 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19554 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019555 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
19556 __func__, MAC_ADDR_ARRAY(peer), action_code,
19557 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053019558 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080019559 }
19560 else
19561 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019562 /* maximum reached. tweak to send error code to peer and return
19563 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019564 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19566 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019567 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
19568 __func__, MAC_ADDR_ARRAY(peer), status_code,
19569 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070019570 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019571 /* fall through to send setup resp with failure status
19572 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019573 }
19574 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019575 else
19576 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019577 mutex_lock(&pHddCtx->tdls_lock);
19578 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019579 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019580 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019581 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019583 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
19584 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019585 return -EPERM;
19586 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019587 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019588 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019589 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019590
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019592 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019593 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
19594 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019595
Hoonki Leea34dd892013-02-05 22:56:02 -080019596 /*Except teardown responder will not be used so just make 0*/
19597 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019598 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080019599 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019600
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019601 mutex_lock(&pHddCtx->tdls_lock);
19602 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019603
19604 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
19605 responder = pTdlsPeer->is_responder;
19606 else
Hoonki Leea34dd892013-02-05 22:56:02 -080019607 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019608 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019609 "%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 -070019610 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
19611 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019612 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019613 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080019614 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019615 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019616 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019617
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019618 /* Discard TDLS setup if peer is removed by user app */
19619 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
19620 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19621 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
19622 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
19623
19624 mutex_lock(&pHddCtx->tdls_lock);
19625 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19626 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
19627 mutex_unlock(&pHddCtx->tdls_lock);
19628 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
19629 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
19630 MAC_ADDR_ARRAY(peer), action_code);
19631 return -EINVAL;
19632 }
19633 mutex_unlock(&pHddCtx->tdls_lock);
19634 }
19635
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019636 /* For explicit trigger of DIS_REQ come out of BMPS for
19637 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070019638 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053019639 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019640 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
19641 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070019642 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019643 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019644 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019645 "%s: Sending frame action_code %u.Disable BMPS", __func__,
19646 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019647 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
19648 if (status != VOS_STATUS_SUCCESS) {
19649 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019650 } else {
19651 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019652 }
Hoonki Lee14621352013-04-16 17:51:19 -070019653 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019654 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019655 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019656 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
19657 }
19658 }
Hoonki Lee14621352013-04-16 17:51:19 -070019659 }
19660
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019661 /* make sure doesn't call send_mgmt() while it is pending */
19662 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
19663 {
19664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080019665 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019666 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019667 ret = -EBUSY;
19668 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019669 }
19670
19671 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019672 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
19673
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019674 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
19675 pAdapter->sessionId, peer, action_code, dialog_token,
19676 status_code, peer_capability, (tANI_U8 *)buf, len,
19677 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019678
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019679 if (VOS_STATUS_SUCCESS != status)
19680 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19682 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019683 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019684 ret = -EINVAL;
19685 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019686 }
19687
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19689 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
19690 WAIT_TIME_TDLS_MGMT);
19691
Hoonki Leed37cbb32013-04-20 00:31:14 -070019692 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
19693 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
19694
19695 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019696 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070019697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070019698 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070019699 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019700 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080019701
19702 if (pHddCtx->isLogpInProgress)
19703 {
19704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19705 "%s: LOGP in Progress. Ignore!!!", __func__);
19706 return -EAGAIN;
19707 }
Abhishek Singh837adf22015-10-01 17:37:37 +053019708 if (rc <= 0)
19709 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
19710 WLAN_LOG_INDICATOR_HOST_DRIVER,
19711 WLAN_LOG_REASON_HDD_TIME_OUT,
19712 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080019713
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019714 ret = -EINVAL;
19715 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019716 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019717 else
19718 {
19719 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19720 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
19721 __func__, rc, pAdapter->mgmtTxCompletionStatus);
19722 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019723
Gopichand Nakkala05922802013-03-14 12:23:19 -070019724 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070019725 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019726 ret = max_sta_failed;
19727 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070019728 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019729
Hoonki Leea34dd892013-02-05 22:56:02 -080019730 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
19731 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019732 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019733 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
19734 }
Hoonki Leea34dd892013-02-05 22:56:02 -080019735 }
19736 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
19737 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019738 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019739 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
19740 }
Hoonki Leea34dd892013-02-05 22:56:02 -080019741 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019742
19743 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019744
19745tx_failed:
19746 /* add_station will be called before sending TDLS_SETUP_REQ and
19747 * TDLS_SETUP_RSP and as part of add_station driver will enable
19748 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
19749 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
19750 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
19751 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
19752 */
19753
19754 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19755 (SIR_MAC_TDLS_SETUP_RSP == action_code))
19756 wlan_hdd_tdls_check_bmps(pAdapter);
19757 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019758}
19759
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019760#if TDLS_MGMT_VERSION2
19761static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19762 u8 *peer, u8 action_code, u8 dialog_token,
19763 u16 status_code, u32 peer_capability,
19764 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019765#else /* TDLS_MGMT_VERSION2 */
19766#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19767static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19768 struct net_device *dev,
19769 const u8 *peer, u8 action_code,
19770 u8 dialog_token, u16 status_code,
19771 u32 peer_capability, bool initiator,
19772 const u8 *buf, size_t len)
19773#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19774static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19775 struct net_device *dev,
19776 const u8 *peer, u8 action_code,
19777 u8 dialog_token, u16 status_code,
19778 u32 peer_capability, const u8 *buf,
19779 size_t len)
19780#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19781static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19782 struct net_device *dev,
19783 u8 *peer, u8 action_code,
19784 u8 dialog_token,
19785 u16 status_code, u32 peer_capability,
19786 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019787#else
19788static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19789 u8 *peer, u8 action_code, u8 dialog_token,
19790 u16 status_code, const u8 *buf, size_t len)
19791#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019792#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019793{
19794 int ret;
19795
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019796 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019797#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019798 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19799 dialog_token, status_code,
19800 peer_capability, buf, len);
19801#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019802#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
19803 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019804 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19805 dialog_token, status_code,
19806 peer_capability, initiator,
19807 buf, len);
19808#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19809 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19810 dialog_token, status_code,
19811 peer_capability, buf, len);
19812#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19813 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19814 dialog_token, status_code,
19815 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019816#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019817 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19818 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019819#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019820#endif
19821 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019822
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019823 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019824}
Atul Mittal115287b2014-07-08 13:26:33 +053019825
19826int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019827#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19828 const u8 *peer,
19829#else
Atul Mittal115287b2014-07-08 13:26:33 +053019830 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019831#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019832 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053019833 cfg80211_exttdls_callback callback)
19834{
19835
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019836 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053019837 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019838 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053019839 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19840 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
19841 __func__, MAC_ADDR_ARRAY(peer));
19842
19843 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19844 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19845
19846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019847 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19848 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19849 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019850 return -ENOTSUPP;
19851 }
19852
19853 /* To cater the requirement of establishing the TDLS link
19854 * irrespective of the data traffic , get an entry of TDLS peer.
19855 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019856 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019857 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
19858 if (pTdlsPeer == NULL) {
19859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19860 "%s: peer " MAC_ADDRESS_STR " not existing",
19861 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019862 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019863 return -EINVAL;
19864 }
19865
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019866 /* check FW TDLS Off Channel capability */
19867 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019868 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019869 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019870 {
19871 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
19872 pTdlsPeer->peerParams.global_operating_class =
19873 tdls_peer_params->global_operating_class;
19874 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
19875 pTdlsPeer->peerParams.min_bandwidth_kbps =
19876 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019877 /* check configured channel is valid, non dfs and
19878 * not current operating channel */
19879 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
19880 tdls_peer_params->channel)) &&
19881 (pHddStaCtx) &&
19882 (tdls_peer_params->channel !=
19883 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019884 {
19885 pTdlsPeer->isOffChannelConfigured = TRUE;
19886 }
19887 else
19888 {
19889 pTdlsPeer->isOffChannelConfigured = FALSE;
19890 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19891 "%s: Configured Tdls Off Channel is not valid", __func__);
19892
19893 }
19894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019895 "%s: tdls_off_channel %d isOffChannelConfigured %d "
19896 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019897 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019898 pTdlsPeer->isOffChannelConfigured,
19899 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019900 }
19901 else
19902 {
19903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019904 "%s: TDLS off channel FW capability %d, "
19905 "host capab %d or Invalid TDLS Peer Params", __func__,
19906 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
19907 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019908 }
19909
Atul Mittal115287b2014-07-08 13:26:33 +053019910 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
19911
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019912 mutex_unlock(&pHddCtx->tdls_lock);
19913
Atul Mittal115287b2014-07-08 13:26:33 +053019914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19915 " %s TDLS Add Force Peer Failed",
19916 __func__);
19917 return -EINVAL;
19918 }
19919 /*EXT TDLS*/
19920
19921 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019922 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019923 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19924 " %s TDLS set callback Failed",
19925 __func__);
19926 return -EINVAL;
19927 }
19928
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019929 mutex_unlock(&pHddCtx->tdls_lock);
19930
Atul Mittal115287b2014-07-08 13:26:33 +053019931 return(0);
19932
19933}
19934
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019935int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
19936#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19937 const u8 *peer
19938#else
19939 u8 *peer
19940#endif
19941)
Atul Mittal115287b2014-07-08 13:26:33 +053019942{
19943
19944 hddTdlsPeer_t *pTdlsPeer;
19945 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019946
Atul Mittal115287b2014-07-08 13:26:33 +053019947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19948 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
19949 __func__, MAC_ADDR_ARRAY(peer));
19950
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019951 if (0 != wlan_hdd_validate_context(pHddCtx)) {
19952 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
19953 return -EINVAL;
19954 }
19955
Atul Mittal115287b2014-07-08 13:26:33 +053019956 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19957 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19958
19959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019960 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19961 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19962 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019963 return -ENOTSUPP;
19964 }
19965
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019966 mutex_lock(&pHddCtx->tdls_lock);
19967 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053019968
19969 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019970 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019971 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019972 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053019973 __func__, MAC_ADDR_ARRAY(peer));
19974 return -EINVAL;
19975 }
19976 else {
19977 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
19978 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019979 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
19980 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019981 /* if channel switch is configured, reset
19982 the channel for this peer */
19983 if (TRUE == pTdlsPeer->isOffChannelConfigured)
19984 {
19985 pTdlsPeer->peerParams.channel = 0;
19986 pTdlsPeer->isOffChannelConfigured = FALSE;
19987 }
Atul Mittal115287b2014-07-08 13:26:33 +053019988 }
19989
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019990 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019991 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019992 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053019993 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019994 }
Atul Mittal115287b2014-07-08 13:26:33 +053019995
19996 /*EXT TDLS*/
19997
19998 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019999 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020000 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20001 " %s TDLS set callback Failed",
20002 __func__);
20003 return -EINVAL;
20004 }
Atul Mittal115287b2014-07-08 13:26:33 +053020005
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020006 mutex_unlock(&pHddCtx->tdls_lock);
20007
20008 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053020009}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020010static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020011#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20012 const u8 *peer,
20013#else
20014 u8 *peer,
20015#endif
20016 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020017{
20018 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20019 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020020 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020021 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020022
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020023 ENTER();
20024
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020025 if (!pAdapter) {
20026 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
20027 return -EINVAL;
20028 }
20029
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020030 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20031 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
20032 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020033 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020034 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070020036 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020037 return -EINVAL;
20038 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020039
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020040 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020041 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020042 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020043 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020044 }
20045
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020046
20047 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020048 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020049 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020050 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020051 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
20052 "Cannot process TDLS commands",
20053 pHddCtx->cfg_ini->fEnableTDLSSupport,
20054 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020055 return -ENOTSUPP;
20056 }
20057
20058 switch (oper) {
20059 case NL80211_TDLS_ENABLE_LINK:
20060 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020061 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020062 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053020063 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
20064 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053020065 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020066 tANI_U16 numCurrTdlsPeers = 0;
20067 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020068 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020069 tSirMacAddr peerMac;
20070 int channel;
20071 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020072
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20074 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
20075 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020076
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020077 mutex_lock(&pHddCtx->tdls_lock);
20078 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020079 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053020080 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020081 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020082 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20083 " (oper %d) not exsting. ignored",
20084 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20085 return -EINVAL;
20086 }
20087
20088 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20089 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20090 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20091 "NL80211_TDLS_ENABLE_LINK");
20092
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020093 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
20094 {
20095 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
20096 MAC_ADDRESS_STR " failed",
20097 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020098 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020099 return -EINVAL;
20100 }
20101
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020102 /* before starting tdls connection, set tdls
20103 * off channel established status to default value */
20104 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020105
20106 mutex_unlock(&pHddCtx->tdls_lock);
20107
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053020108 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020109 /* TDLS Off Channel, Disable tdls channel switch,
20110 when there are more than one tdls link */
20111 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053020112 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020113 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020114 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020115 /* get connected peer and send disable tdls off chan */
20116 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020117 if ((connPeer) &&
20118 (connPeer->isOffChannelSupported == TRUE) &&
20119 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020120 {
20121 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20122 "%s: More then one peer connected, Disable "
20123 "TDLS channel switch", __func__);
20124
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020125 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020126 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
20127 channel = connPeer->peerParams.channel;
20128
20129 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020130
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020131 ret = sme_SendTdlsChanSwitchReq(
20132 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020133 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020134 peerMac,
20135 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020136 TDLS_OFF_CHANNEL_BW_OFFSET,
20137 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020138 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020139 hddLog(VOS_TRACE_LEVEL_ERROR,
20140 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020141 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020142 }
20143 else
20144 {
20145 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20146 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020147 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020148 "isOffChannelConfigured %d",
20149 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020150 (connPeer ? (connPeer->isOffChannelSupported)
20151 : -1),
20152 (connPeer ? (connPeer->isOffChannelConfigured)
20153 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020154 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020155 }
20156 }
20157
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020158 mutex_lock(&pHddCtx->tdls_lock);
20159 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20160 if ( NULL == pTdlsPeer ) {
20161 mutex_unlock(&pHddCtx->tdls_lock);
20162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20163 "%s: " MAC_ADDRESS_STR
20164 " (oper %d) peer got freed in other context. ignored",
20165 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20166 return -EINVAL;
20167 }
20168 peer_status = pTdlsPeer->link_status;
20169 mutex_unlock(&pHddCtx->tdls_lock);
20170
20171 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020172 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020173 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053020174
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020175 if (0 != wlan_hdd_tdls_get_link_establish_params(
20176 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020177 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020178 return -EINVAL;
20179 }
20180 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020181
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020182 ret = sme_SendTdlsLinkEstablishParams(
20183 WLAN_HDD_GET_HAL_CTX(pAdapter),
20184 pAdapter->sessionId, peer,
20185 &tdlsLinkEstablishParams);
20186 if (ret != VOS_STATUS_SUCCESS) {
20187 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
20188 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020189 /* Send TDLS peer UAPSD capabilities to the firmware and
20190 * register with the TL on after the response for this operation
20191 * is received .
20192 */
20193 ret = wait_for_completion_interruptible_timeout(
20194 &pAdapter->tdls_link_establish_req_comp,
20195 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053020196
20197 mutex_lock(&pHddCtx->tdls_lock);
20198 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20199 if ( NULL == pTdlsPeer ) {
20200 mutex_unlock(&pHddCtx->tdls_lock);
20201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20202 "%s %d: " MAC_ADDRESS_STR
20203 " (oper %d) peer got freed in other context. ignored",
20204 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
20205 (int)oper);
20206 return -EINVAL;
20207 }
20208 peer_status = pTdlsPeer->link_status;
20209 mutex_unlock(&pHddCtx->tdls_lock);
20210
20211 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020212 {
20213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020214 FL("Link Establish Request Failed Status %ld"),
20215 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020216 return -EINVAL;
20217 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020218 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020219
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020220 mutex_lock(&pHddCtx->tdls_lock);
20221 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20222 if ( NULL == pTdlsPeer ) {
20223 mutex_unlock(&pHddCtx->tdls_lock);
20224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20225 "%s: " MAC_ADDRESS_STR
20226 " (oper %d) peer got freed in other context. ignored",
20227 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20228 return -EINVAL;
20229 }
20230
Atul Mittal115287b2014-07-08 13:26:33 +053020231 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20232 eTDLS_LINK_CONNECTED,
20233 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020234 staDesc.ucSTAId = pTdlsPeer->staId;
20235 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053020236
20237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20238 "%s: tdlsLinkEstablishParams of peer "
20239 MAC_ADDRESS_STR "uapsdQueues: %d"
20240 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
20241 "isResponder: %d peerstaId: %d",
20242 __func__,
20243 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
20244 tdlsLinkEstablishParams.uapsdQueues,
20245 tdlsLinkEstablishParams.qos,
20246 tdlsLinkEstablishParams.maxSp,
20247 tdlsLinkEstablishParams.isBufSta,
20248 tdlsLinkEstablishParams.isOffChannelSupported,
20249 tdlsLinkEstablishParams.isResponder,
20250 pTdlsPeer->staId);
20251
20252 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20253 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
20254 __func__,
20255 staDesc.ucSTAId,
20256 staDesc.ucQosEnabled);
20257
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020258 ret = WLANTL_UpdateTdlsSTAClient(
20259 pHddCtx->pvosContext,
20260 &staDesc);
20261 if (ret != VOS_STATUS_SUCCESS) {
20262 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
20263 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053020264
Gopichand Nakkala471708b2013-06-04 20:03:01 +053020265 /* Mark TDLS client Authenticated .*/
20266 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
20267 pTdlsPeer->staId,
20268 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020269 if (VOS_STATUS_SUCCESS == status)
20270 {
Hoonki Lee14621352013-04-16 17:51:19 -070020271 if (pTdlsPeer->is_responder == 0)
20272 {
20273 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020274 tdlsConnInfo_t *tdlsInfo;
20275
20276 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
20277
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020278 if (!vos_timer_is_initialized(
20279 &pTdlsPeer->initiatorWaitTimeoutTimer))
20280 {
20281 /* Initialize initiator wait callback */
20282 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020283 &pTdlsPeer->initiatorWaitTimeoutTimer,
20284 VOS_TIMER_TYPE_SW,
20285 wlan_hdd_tdls_initiator_wait_cb,
20286 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020287 }
Hoonki Lee14621352013-04-16 17:51:19 -070020288 wlan_hdd_tdls_timer_restart(pAdapter,
20289 &pTdlsPeer->initiatorWaitTimeoutTimer,
20290 WAIT_TIME_TDLS_INITIATOR);
20291 /* suspend initiator TX until it receives direct packet from the
20292 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020293 ret = WLANTL_SuspendDataTx(
20294 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20295 &staId, NULL);
20296 if (ret != VOS_STATUS_SUCCESS) {
20297 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20298 }
Hoonki Lee14621352013-04-16 17:51:19 -070020299 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020300
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020301 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020302 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020303 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020304 suppChannelLen =
20305 tdlsLinkEstablishParams.supportedChannelsLen;
20306
20307 if ((suppChannelLen > 0) &&
20308 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20309 {
20310 tANI_U8 suppPeerChannel = 0;
20311 int i = 0;
20312 for (i = 0U; i < suppChannelLen; i++)
20313 {
20314 suppPeerChannel =
20315 tdlsLinkEstablishParams.supportedChannels[i];
20316
20317 pTdlsPeer->isOffChannelSupported = FALSE;
20318 if (suppPeerChannel ==
20319 pTdlsPeer->peerParams.channel)
20320 {
20321 pTdlsPeer->isOffChannelSupported = TRUE;
20322 break;
20323 }
20324 }
20325 }
20326 else
20327 {
20328 pTdlsPeer->isOffChannelSupported = FALSE;
20329 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020330 }
20331 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20332 "%s: TDLS channel switch request for channel "
20333 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020334 "%d isOffChannelSupported %d", __func__,
20335 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020336 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020337 suppChannelLen,
20338 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020339
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020340 /* TDLS Off Channel, Enable tdls channel switch,
20341 when their is only one tdls link and it supports */
20342 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20343 if ((numCurrTdlsPeers == 1) &&
20344 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20345 (TRUE == pTdlsPeer->isOffChannelConfigured))
20346 {
20347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20348 "%s: Send TDLS channel switch request for channel %d",
20349 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020350
20351 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020352 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20353 channel = pTdlsPeer->peerParams.channel;
20354
20355 mutex_unlock(&pHddCtx->tdls_lock);
20356
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020357 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20358 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020359 peerMac,
20360 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020361 TDLS_OFF_CHANNEL_BW_OFFSET,
20362 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020363 if (ret != VOS_STATUS_SUCCESS) {
20364 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20365 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020366 }
20367 else
20368 {
20369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20370 "%s: TDLS channel switch request not sent"
20371 " numCurrTdlsPeers %d "
20372 "isOffChannelSupported %d "
20373 "isOffChannelConfigured %d",
20374 __func__, numCurrTdlsPeers,
20375 pTdlsPeer->isOffChannelSupported,
20376 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020377 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020378 }
20379
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020380 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020381 else
20382 mutex_unlock(&pHddCtx->tdls_lock);
20383
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020384 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020385
20386 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020387 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
20388 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020389 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020390 int ac;
20391 uint8 ucAc[4] = { WLANTL_AC_VO,
20392 WLANTL_AC_VI,
20393 WLANTL_AC_BK,
20394 WLANTL_AC_BE };
20395 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
20396 for(ac=0; ac < 4; ac++)
20397 {
20398 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20399 pTdlsPeer->staId, ucAc[ac],
20400 tlTid[ac], tlTid[ac], 0, 0,
20401 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020402 if (status != VOS_STATUS_SUCCESS) {
20403 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
20404 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020405 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020406 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020407 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020408
Bhargav Shah66896792015-10-01 18:17:37 +053020409 /* stop TCP delack timer if TDLS is enable */
20410 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20411 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053020412 hdd_wlan_tdls_enable_link_event(peer,
20413 pTdlsPeer->isOffChannelSupported,
20414 pTdlsPeer->isOffChannelConfigured,
20415 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020416 }
20417 break;
20418 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080020419 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020420 tANI_U16 numCurrTdlsPeers = 0;
20421 hddTdlsPeer_t *connPeer = NULL;
20422
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20424 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
20425 __func__, MAC_ADDR_ARRAY(peer));
20426
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020427 mutex_lock(&pHddCtx->tdls_lock);
20428 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020429
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020430
Sunil Dutt41de4e22013-11-14 18:09:02 +053020431 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020432 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020433 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20434 " (oper %d) not exsting. ignored",
20435 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20436 return -EINVAL;
20437 }
20438
20439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20440 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20441 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20442 "NL80211_TDLS_DISABLE_LINK");
20443
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020444 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080020445 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020446 long status;
20447
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020448 /* set tdls off channel status to false for this peer */
20449 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053020450 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20451 eTDLS_LINK_TEARING,
20452 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
20453 eTDLS_LINK_UNSPECIFIED:
20454 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020455 mutex_unlock(&pHddCtx->tdls_lock);
20456
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020457 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
20458
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020459 status = sme_DeleteTdlsPeerSta(
20460 WLAN_HDD_GET_HAL_CTX(pAdapter),
20461 pAdapter->sessionId, peer );
20462 if (status != VOS_STATUS_SUCCESS) {
20463 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
20464 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020465
20466 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
20467 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020468
20469 mutex_lock(&pHddCtx->tdls_lock);
20470 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20471 if ( NULL == pTdlsPeer ) {
20472 mutex_unlock(&pHddCtx->tdls_lock);
20473 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20474 " peer was freed in other context",
20475 __func__, MAC_ADDR_ARRAY(peer));
20476 return -EINVAL;
20477 }
20478
Atul Mittal271a7652014-09-12 13:18:22 +053020479 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053020480 eTDLS_LINK_IDLE,
20481 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020482 mutex_unlock(&pHddCtx->tdls_lock);
20483
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020484 if (status <= 0)
20485 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20487 "%s: Del station failed status %ld",
20488 __func__, status);
20489 return -EPERM;
20490 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020491
20492 /* TDLS Off Channel, Enable tdls channel switch,
20493 when their is only one tdls link and it supports */
20494 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20495 if (numCurrTdlsPeers == 1)
20496 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020497 tSirMacAddr peerMac;
20498 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020499
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020500 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020501 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020502
20503 if (connPeer == NULL) {
20504 mutex_unlock(&pHddCtx->tdls_lock);
20505 hddLog(VOS_TRACE_LEVEL_ERROR,
20506 "%s connPeer is NULL", __func__);
20507 return -EINVAL;
20508 }
20509
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020510 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
20511 channel = connPeer->peerParams.channel;
20512
20513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20514 "%s: TDLS channel switch "
20515 "isOffChannelSupported %d "
20516 "isOffChannelConfigured %d "
20517 "isOffChannelEstablished %d",
20518 __func__,
20519 (connPeer ? connPeer->isOffChannelSupported : -1),
20520 (connPeer ? connPeer->isOffChannelConfigured : -1),
20521 (connPeer ? connPeer->isOffChannelEstablished : -1));
20522
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020523 if ((connPeer) &&
20524 (connPeer->isOffChannelSupported == TRUE) &&
20525 (connPeer->isOffChannelConfigured == TRUE))
20526 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020527 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020528 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020529 status = sme_SendTdlsChanSwitchReq(
20530 WLAN_HDD_GET_HAL_CTX(pAdapter),
20531 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020532 peerMac,
20533 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020534 TDLS_OFF_CHANNEL_BW_OFFSET,
20535 TDLS_CHANNEL_SWITCH_ENABLE);
20536 if (status != VOS_STATUS_SUCCESS) {
20537 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
20538 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020539 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020540 else
20541 mutex_unlock(&pHddCtx->tdls_lock);
20542 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020543 else
20544 {
20545 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20546 "%s: TDLS channel switch request not sent "
20547 "numCurrTdlsPeers %d ",
20548 __func__, numCurrTdlsPeers);
20549 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020550 }
20551 else
20552 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020553 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020554 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20555 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080020556 }
Bhargav Shah66896792015-10-01 18:17:37 +053020557 if (numCurrTdlsPeers == 0) {
20558 /* start TCP delack timer if TDLS is disable */
20559 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20560 hdd_manage_delack_timer(pHddCtx);
20561 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020562 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020563 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020564 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020565 {
Atul Mittal115287b2014-07-08 13:26:33 +053020566 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020567
Atul Mittal115287b2014-07-08 13:26:33 +053020568 if (0 != status)
20569 {
20570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020571 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053020572 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020573 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053020574 break;
20575 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020576 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020577 {
Atul Mittal115287b2014-07-08 13:26:33 +053020578 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
20579 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020580 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053020581 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020582
Atul Mittal115287b2014-07-08 13:26:33 +053020583 if (0 != status)
20584 {
20585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020586 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053020587 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053020588 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053020589 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020590 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020591 case NL80211_TDLS_DISCOVERY_REQ:
20592 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020594 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020595 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020596 return -ENOTSUPP;
20597 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20599 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020600 return -ENOTSUPP;
20601 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020602
20603 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020604 return 0;
20605}
Chilam NG571c65a2013-01-19 12:27:36 +053020606
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020607static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020608#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20609 const u8 *peer,
20610#else
20611 u8 *peer,
20612#endif
20613 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020614{
20615 int ret;
20616
20617 vos_ssr_protect(__func__);
20618 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
20619 vos_ssr_unprotect(__func__);
20620
20621 return ret;
20622}
20623
Chilam NG571c65a2013-01-19 12:27:36 +053020624int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
20625 struct net_device *dev, u8 *peer)
20626{
Arif Hussaina7c8e412013-11-20 11:06:42 -080020627 hddLog(VOS_TRACE_LEVEL_INFO,
20628 "tdls send discover req: "MAC_ADDRESS_STR,
20629 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020630#if TDLS_MGMT_VERSION2
20631 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20632 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20633#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020634#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20635 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20636 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
20637#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20638 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20639 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20640#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20641 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20642 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20643#else
Chilam NG571c65a2013-01-19 12:27:36 +053020644 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20645 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020646#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020647#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053020648}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020649#endif
20650
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020651#ifdef WLAN_FEATURE_GTK_OFFLOAD
20652/*
20653 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
20654 * Callback rountine called upon receiving response for
20655 * get offload info
20656 */
20657void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
20658 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
20659{
20660
20661 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020662 tANI_U8 tempReplayCounter[8];
20663 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020664
20665 ENTER();
20666
20667 if (NULL == pAdapter)
20668 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053020669 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020670 "%s: HDD adapter is Null", __func__);
20671 return ;
20672 }
20673
20674 if (NULL == pGtkOffloadGetInfoRsp)
20675 {
20676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20677 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
20678 return ;
20679 }
20680
20681 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
20682 {
20683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20684 "%s: wlan Failed to get replay counter value",
20685 __func__);
20686 return ;
20687 }
20688
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020689 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20690 /* Update replay counter */
20691 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
20692 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
20693
20694 {
20695 /* changing from little to big endian since supplicant
20696 * works on big endian format
20697 */
20698 int i;
20699 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
20700
20701 for (i = 0; i < 8; i++)
20702 {
20703 tempReplayCounter[7-i] = (tANI_U8)p[i];
20704 }
20705 }
20706
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020707 /* Update replay counter to NL */
20708 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020709 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020710}
20711
20712/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020713 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020714 * This function is used to offload GTK rekeying job to the firmware.
20715 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020716int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020717 struct cfg80211_gtk_rekey_data *data)
20718{
20719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20720 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
20721 hdd_station_ctx_t *pHddStaCtx;
20722 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020723 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020724 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020725 eHalStatus status = eHAL_STATUS_FAILURE;
20726
20727 ENTER();
20728
20729 if (NULL == pAdapter)
20730 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020731 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020732 "%s: HDD adapter is Null", __func__);
20733 return -ENODEV;
20734 }
20735
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020736 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20737 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
20738 pAdapter->sessionId, pAdapter->device_mode));
20739
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020740 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020741 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020742 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020743 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020744 }
20745
20746 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20747 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
20748 if (NULL == hHal)
20749 {
20750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20751 "%s: HAL context is Null!!!", __func__);
20752 return -EAGAIN;
20753 }
20754
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020755 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
20756 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
20757 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
20758 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020759 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020760 {
20761 /* changing from big to little endian since driver
20762 * works on little endian format
20763 */
20764 tANI_U8 *p =
20765 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
20766 int i;
20767
20768 for (i = 0; i < 8; i++)
20769 {
20770 p[7-i] = data->replay_ctr[i];
20771 }
20772 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020773
20774 if (TRUE == pHddCtx->hdd_wlan_suspended)
20775 {
20776 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020777 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
20778 sizeof (tSirGtkOffloadParams));
20779 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020780 pAdapter->sessionId);
20781
20782 if (eHAL_STATUS_SUCCESS != status)
20783 {
20784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20785 "%s: sme_SetGTKOffload failed, returned %d",
20786 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020787
20788 /* Need to clear any trace of key value in the memory.
20789 * Thus zero out the memory even though it is local
20790 * variable.
20791 */
20792 vos_mem_zero(&hddGtkOffloadReqParams,
20793 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020794 return status;
20795 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20797 "%s: sme_SetGTKOffload successfull", __func__);
20798 }
20799 else
20800 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20802 "%s: wlan not suspended GTKOffload request is stored",
20803 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020804 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020805
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020806 /* Need to clear any trace of key value in the memory.
20807 * Thus zero out the memory even though it is local
20808 * variable.
20809 */
20810 vos_mem_zero(&hddGtkOffloadReqParams,
20811 sizeof(hddGtkOffloadReqParams));
20812
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020813 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020814 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020815}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020816
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020817int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
20818 struct cfg80211_gtk_rekey_data *data)
20819{
20820 int ret;
20821
20822 vos_ssr_protect(__func__);
20823 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
20824 vos_ssr_unprotect(__func__);
20825
20826 return ret;
20827}
20828#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020829/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020830 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020831 * This function is used to set access control policy
20832 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020833static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20834 struct net_device *dev,
20835 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020836{
20837 int i;
20838 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20839 hdd_hostapd_state_t *pHostapdState;
20840 tsap_Config_t *pConfig;
20841 v_CONTEXT_t pVosContext = NULL;
20842 hdd_context_t *pHddCtx;
20843 int status;
20844
20845 ENTER();
20846
20847 if (NULL == pAdapter)
20848 {
20849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20850 "%s: HDD adapter is Null", __func__);
20851 return -ENODEV;
20852 }
20853
20854 if (NULL == params)
20855 {
20856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20857 "%s: params is Null", __func__);
20858 return -EINVAL;
20859 }
20860
20861 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20862 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020863 if (0 != status)
20864 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020865 return status;
20866 }
20867
20868 pVosContext = pHddCtx->pvosContext;
20869 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
20870
20871 if (NULL == pHostapdState)
20872 {
20873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20874 "%s: pHostapdState is Null", __func__);
20875 return -EINVAL;
20876 }
20877
20878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
20879 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020880 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20881 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
20882 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020883
20884 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
20885 {
20886 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
20887
20888 /* default value */
20889 pConfig->num_accept_mac = 0;
20890 pConfig->num_deny_mac = 0;
20891
20892 /**
20893 * access control policy
20894 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
20895 * listed in hostapd.deny file.
20896 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
20897 * listed in hostapd.accept file.
20898 */
20899 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
20900 {
20901 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
20902 }
20903 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
20904 {
20905 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
20906 }
20907 else
20908 {
20909 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20910 "%s:Acl Policy : %d is not supported",
20911 __func__, params->acl_policy);
20912 return -ENOTSUPP;
20913 }
20914
20915 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
20916 {
20917 pConfig->num_accept_mac = params->n_acl_entries;
20918 for (i = 0; i < params->n_acl_entries; i++)
20919 {
20920 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20921 "** Add ACL MAC entry %i in WhiletList :"
20922 MAC_ADDRESS_STR, i,
20923 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20924
20925 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
20926 sizeof(qcmacaddr));
20927 }
20928 }
20929 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
20930 {
20931 pConfig->num_deny_mac = params->n_acl_entries;
20932 for (i = 0; i < params->n_acl_entries; i++)
20933 {
20934 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20935 "** Add ACL MAC entry %i in BlackList :"
20936 MAC_ADDRESS_STR, i,
20937 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20938
20939 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
20940 sizeof(qcmacaddr));
20941 }
20942 }
20943
20944 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
20945 {
20946 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20947 "%s: SAP Set Mac Acl fail", __func__);
20948 return -EINVAL;
20949 }
20950 }
20951 else
20952 {
20953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053020954 "%s: Invalid device_mode = %s (%d)",
20955 __func__, hdd_device_modetoString(pAdapter->device_mode),
20956 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020957 return -EINVAL;
20958 }
20959
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020960 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020961 return 0;
20962}
20963
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020964static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20965 struct net_device *dev,
20966 const struct cfg80211_acl_data *params)
20967{
20968 int ret;
20969 vos_ssr_protect(__func__);
20970 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
20971 vos_ssr_unprotect(__func__);
20972
20973 return ret;
20974}
20975
Leo Chang9056f462013-08-01 19:21:11 -070020976#ifdef WLAN_NL80211_TESTMODE
20977#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070020978void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070020979(
20980 void *pAdapter,
20981 void *indCont
20982)
20983{
Leo Changd9df8aa2013-09-26 13:32:26 -070020984 tSirLPHBInd *lphbInd;
20985 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053020986 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070020987
20988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020989 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070020990
c_hpothu73f35e62014-04-18 13:40:08 +053020991 if (pAdapter == NULL)
20992 {
20993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20994 "%s: pAdapter is NULL\n",__func__);
20995 return;
20996 }
20997
Leo Chang9056f462013-08-01 19:21:11 -070020998 if (NULL == indCont)
20999 {
21000 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021001 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070021002 return;
21003 }
21004
c_hpothu73f35e62014-04-18 13:40:08 +053021005 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070021006 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070021007 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053021008 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070021009 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070021010 GFP_ATOMIC);
21011 if (!skb)
21012 {
21013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21014 "LPHB timeout, NL buffer alloc fail");
21015 return;
21016 }
21017
Leo Changac3ba772013-10-07 09:47:04 -070021018 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070021019 {
21020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21021 "WLAN_HDD_TM_ATTR_CMD put fail");
21022 goto nla_put_failure;
21023 }
Leo Changac3ba772013-10-07 09:47:04 -070021024 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070021025 {
21026 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21027 "WLAN_HDD_TM_ATTR_TYPE put fail");
21028 goto nla_put_failure;
21029 }
Leo Changac3ba772013-10-07 09:47:04 -070021030 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070021031 sizeof(tSirLPHBInd), lphbInd))
21032 {
21033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21034 "WLAN_HDD_TM_ATTR_DATA put fail");
21035 goto nla_put_failure;
21036 }
Leo Chang9056f462013-08-01 19:21:11 -070021037 cfg80211_testmode_event(skb, GFP_ATOMIC);
21038 return;
21039
21040nla_put_failure:
21041 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21042 "NLA Put fail");
21043 kfree_skb(skb);
21044
21045 return;
21046}
21047#endif /* FEATURE_WLAN_LPHB */
21048
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021049static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070021050{
21051 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
21052 int err = 0;
21053#ifdef FEATURE_WLAN_LPHB
21054 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070021055 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021056
21057 ENTER();
21058
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021059 err = wlan_hdd_validate_context(pHddCtx);
21060 if (0 != err)
21061 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021062 return err;
21063 }
Leo Chang9056f462013-08-01 19:21:11 -070021064#endif /* FEATURE_WLAN_LPHB */
21065
21066 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
21067 if (err)
21068 {
21069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21070 "%s Testmode INV ATTR", __func__);
21071 return err;
21072 }
21073
21074 if (!tb[WLAN_HDD_TM_ATTR_CMD])
21075 {
21076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21077 "%s Testmode INV CMD", __func__);
21078 return -EINVAL;
21079 }
21080
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021081 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21082 TRACE_CODE_HDD_CFG80211_TESTMODE,
21083 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070021084 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
21085 {
21086#ifdef FEATURE_WLAN_LPHB
21087 /* Low Power Heartbeat configuration request */
21088 case WLAN_HDD_TM_CMD_WLAN_HB:
21089 {
21090 int buf_len;
21091 void *buf;
21092 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080021093 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070021094
21095 if (!tb[WLAN_HDD_TM_ATTR_DATA])
21096 {
21097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21098 "%s Testmode INV DATA", __func__);
21099 return -EINVAL;
21100 }
21101
21102 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
21103 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080021104
Manjeet Singh3c577442017-02-10 19:03:38 +053021105 if (buf_len > sizeof(*hb_params)) {
21106 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
21107 buf_len);
21108 return -ERANGE;
21109 }
21110
Amar Singhal05852702014-02-04 14:40:00 -080021111 hb_params_temp =(tSirLPHBReq *)buf;
21112 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
21113 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
21114 return -EINVAL;
21115
Leo Chang9056f462013-08-01 19:21:11 -070021116 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
21117 if (NULL == hb_params)
21118 {
21119 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21120 "%s Request Buffer Alloc Fail", __func__);
21121 return -EINVAL;
21122 }
21123
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053021124 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070021125 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070021126 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
21127 hb_params,
21128 wlan_hdd_cfg80211_lphb_ind_handler);
21129 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070021130 {
Leo Changd9df8aa2013-09-26 13:32:26 -070021131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21132 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070021133 vos_mem_free(hb_params);
21134 }
Leo Chang9056f462013-08-01 19:21:11 -070021135 return 0;
21136 }
21137#endif /* FEATURE_WLAN_LPHB */
21138 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21140 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070021141 return -EOPNOTSUPP;
21142 }
21143
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021144 EXIT();
21145 return err;
Leo Chang9056f462013-08-01 19:21:11 -070021146}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021147
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053021148static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
21149#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
21150 struct wireless_dev *wdev,
21151#endif
21152 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021153{
21154 int ret;
21155
21156 vos_ssr_protect(__func__);
21157 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
21158 vos_ssr_unprotect(__func__);
21159
21160 return ret;
21161}
Leo Chang9056f462013-08-01 19:21:11 -070021162#endif /* CONFIG_NL80211_TESTMODE */
21163
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021164extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021165static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021166 struct net_device *dev,
21167 int idx, struct survey_info *survey)
21168{
21169 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21170 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053021171 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021172 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053021173 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021174 v_S7_t snr,rssi;
21175 int status, i, j, filled = 0;
21176
21177 ENTER();
21178
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021179 if (NULL == pAdapter)
21180 {
21181 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21182 "%s: HDD adapter is Null", __func__);
21183 return -ENODEV;
21184 }
21185
21186 if (NULL == wiphy)
21187 {
21188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21189 "%s: wiphy is Null", __func__);
21190 return -ENODEV;
21191 }
21192
21193 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21194 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021195 if (0 != status)
21196 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021197 return status;
21198 }
21199
Mihir Sheted9072e02013-08-21 17:02:29 +053021200 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21201
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021202 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053021203 0 != pAdapter->survey_idx ||
21204 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021205 {
21206 /* The survey dump ops when implemented completely is expected to
21207 * return a survey of all channels and the ops is called by the
21208 * kernel with incremental values of the argument 'idx' till it
21209 * returns -ENONET. But we can only support the survey for the
21210 * operating channel for now. survey_idx is used to track
21211 * that the ops is called only once and then return -ENONET for
21212 * the next iteration
21213 */
21214 pAdapter->survey_idx = 0;
21215 return -ENONET;
21216 }
21217
Mukul Sharma9d5233b2015-06-11 20:28:20 +053021218 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
21219 {
21220 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21221 "%s: Roaming in progress, hence return ", __func__);
21222 return -ENONET;
21223 }
21224
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021225 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
21226
21227 wlan_hdd_get_snr(pAdapter, &snr);
21228 wlan_hdd_get_rssi(pAdapter, &rssi);
21229
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021230 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21231 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
21232 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021233 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
21234 hdd_wlan_get_freq(channel, &freq);
21235
21236
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053021237 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021238 {
21239 if (NULL == wiphy->bands[i])
21240 {
21241 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
21242 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
21243 continue;
21244 }
21245
21246 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
21247 {
21248 struct ieee80211_supported_band *band = wiphy->bands[i];
21249
21250 if (band->channels[j].center_freq == (v_U16_t)freq)
21251 {
21252 survey->channel = &band->channels[j];
21253 /* The Rx BDs contain SNR values in dB for the received frames
21254 * while the supplicant expects noise. So we calculate and
21255 * return the value of noise (dBm)
21256 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
21257 */
21258 survey->noise = rssi - snr;
21259 survey->filled = SURVEY_INFO_NOISE_DBM;
21260 filled = 1;
21261 }
21262 }
21263 }
21264
21265 if (filled)
21266 pAdapter->survey_idx = 1;
21267 else
21268 {
21269 pAdapter->survey_idx = 0;
21270 return -ENONET;
21271 }
21272
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021273 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021274 return 0;
21275}
21276
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021277static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
21278 struct net_device *dev,
21279 int idx, struct survey_info *survey)
21280{
21281 int ret;
21282
21283 vos_ssr_protect(__func__);
21284 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
21285 vos_ssr_unprotect(__func__);
21286
21287 return ret;
21288}
21289
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021290/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021291 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021292 * this is called when cfg80211 driver resume
21293 * driver updates latest sched_scan scan result(if any) to cfg80211 database
21294 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021295int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021296{
21297 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21298 hdd_adapter_t *pAdapter;
21299 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21300 VOS_STATUS status = VOS_STATUS_SUCCESS;
21301
21302 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021303
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021304 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021305 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021306 return 0;
21307 }
21308
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021309 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21310 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021311
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021312 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021313 {
21314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21315 "%s: Resume SoftAP", __func__);
21316 hdd_set_wlan_suspend_mode(false);
21317 }
21318
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021319 spin_lock(&pHddCtx->schedScan_lock);
21320 pHddCtx->isWiphySuspended = FALSE;
21321 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21322 {
21323 spin_unlock(&pHddCtx->schedScan_lock);
21324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21325 "%s: Return resume is not due to PNO indication", __func__);
21326 return 0;
21327 }
21328 // Reset flag to avoid updatating cfg80211 data old results again
21329 pHddCtx->isSchedScanUpdatePending = FALSE;
21330 spin_unlock(&pHddCtx->schedScan_lock);
21331
21332 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21333
21334 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21335 {
21336 pAdapter = pAdapterNode->pAdapter;
21337 if ( (NULL != pAdapter) &&
21338 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21339 {
21340 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021341 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21343 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021344 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021345 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021346 {
21347 /* Acquire wakelock to handle the case where APP's tries to
21348 * suspend immediately after updating the scan results. Whis
21349 * results in app's is in suspended state and not able to
21350 * process the connect request to AP
21351 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021352 hdd_prevent_suspend_timeout(2000,
21353 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021354 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021355 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021356
21357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21358 "%s : cfg80211 scan result database updated", __func__);
21359
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021360 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021361 return 0;
21362
21363 }
21364 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21365 pAdapterNode = pNext;
21366 }
21367
21368 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21369 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021370 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021371 return 0;
21372}
21373
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021374int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21375{
21376 int ret;
21377
21378 vos_ssr_protect(__func__);
21379 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
21380 vos_ssr_unprotect(__func__);
21381
21382 return ret;
21383}
21384
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021385/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021386 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021387 * this is called when cfg80211 driver suspends
21388 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021389int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021390 struct cfg80211_wowlan *wow)
21391{
21392 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021393 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021394
21395 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021396
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021397 ret = wlan_hdd_validate_context(pHddCtx);
21398 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021399 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021400 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021401 }
21402
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021403 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21405 "%s: Suspend SoftAP", __func__);
21406 hdd_set_wlan_suspend_mode(true);
21407 }
21408
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021409
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021410 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21411 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
21412 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021413 pHddCtx->isWiphySuspended = TRUE;
21414
21415 EXIT();
21416
21417 return 0;
21418}
21419
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021420int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
21421 struct cfg80211_wowlan *wow)
21422{
21423 int ret;
21424
21425 vos_ssr_protect(__func__);
21426 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
21427 vos_ssr_unprotect(__func__);
21428
21429 return ret;
21430}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021431
21432#ifdef FEATURE_OEM_DATA_SUPPORT
21433static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021434 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021435{
21436 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21437
21438 ENTER();
21439
21440 if (wlan_hdd_validate_context(pHddCtx)) {
21441 return;
21442 }
21443 if (!pMsg)
21444 {
21445 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
21446 return;
21447 }
21448
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021449 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021450
21451 EXIT();
21452 return;
21453
21454}
21455
21456void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021457 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021458{
21459 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21460
21461 ENTER();
21462
21463 if (wlan_hdd_validate_context(pHddCtx)) {
21464 return;
21465 }
21466
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021467 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021468
21469 switch(evType) {
21470 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021471 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021472 break;
21473 default:
21474 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
21475 break;
21476 }
21477 EXIT();
21478}
21479#endif
21480
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021481#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21482 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021483/**
21484 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
21485 * @wiphy: Pointer to wiphy
21486 * @wdev: Pointer to wireless device structure
21487 *
21488 * This function is used to abort an ongoing scan
21489 *
21490 * Return: None
21491 */
21492static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21493 struct wireless_dev *wdev)
21494{
21495 struct net_device *dev = wdev->netdev;
21496 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21497 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
21498 int ret;
21499
21500 ENTER();
21501
21502 if (NULL == adapter) {
21503 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
21504 return;
21505 }
21506
21507 ret = wlan_hdd_validate_context(hdd_ctx);
21508 if (0 != ret)
21509 return;
21510
21511 wlan_hdd_scan_abort(adapter);
21512
21513 return;
21514}
21515
21516/**
21517 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
21518 * @wiphy: Pointer to wiphy
21519 * @wdev: Pointer to wireless device structure
21520 *
21521 * Return: None
21522 */
21523void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21524 struct wireless_dev *wdev)
21525{
21526 vos_ssr_protect(__func__);
21527 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
21528 vos_ssr_unprotect(__func__);
21529
21530 return;
21531}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021532#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021533
Abhishek Singh936c6932017-11-07 17:28:23 +053021534#ifdef CHANNEL_SWITCH_SUPPORTED
21535/**
21536 * __wlan_hdd_cfg80211_channel_switch()- function to switch
21537 * channel in SAP/GO
21538 * @wiphy: wiphy pointer
21539 * @dev: dev pointer.
21540 * @csa_params: Change channel params
21541 *
21542 * This function is called to switch channel in SAP/GO
21543 *
21544 * Return: 0 if success else return non zero
21545 */
21546static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21547 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21548{
21549 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21550 hdd_context_t *hdd_ctx;
21551 uint8_t channel;
21552 int ret;
21553 v_CONTEXT_t vos_ctx;
21554
21555 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
21556
21557 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
21558 ret = wlan_hdd_validate_context(hdd_ctx);
21559 if (ret)
21560 return ret;
21561
21562 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
21563 if (!vos_ctx) {
21564 hddLog(LOGE, FL("Vos ctx is null"));
21565 return -EINVAL;
21566 }
21567
21568 if ((WLAN_HDD_SOFTAP != adapter->device_mode) &&
21569 (WLAN_HDD_P2P_GO != adapter->device_mode))
21570 return -ENOTSUPP;
21571
21572 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053021573 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053021574
21575 return ret;
21576}
21577
21578/**
21579 * wlan_hdd_cfg80211_channel_switch()- function to switch
21580 * channel in SAP/GO
21581 * @wiphy: wiphy pointer
21582 * @dev: dev pointer.
21583 * @csa_params: Change channel params
21584 *
21585 * This function is called to switch channel in SAP/GO
21586 *
21587 * Return: 0 if success else return non zero
21588 */
21589static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21590 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21591{
21592 int ret;
21593
21594 vos_ssr_protect(__func__);
21595 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
21596 vos_ssr_unprotect(__func__);
21597
21598 return ret;
21599}
21600#endif
21601
Jeff Johnson295189b2012-06-20 16:38:30 -070021602/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053021603static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070021604{
21605 .add_virtual_intf = wlan_hdd_add_virtual_intf,
21606 .del_virtual_intf = wlan_hdd_del_virtual_intf,
21607 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
21608 .change_station = wlan_hdd_change_station,
21609#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
21610 .add_beacon = wlan_hdd_cfg80211_add_beacon,
21611 .del_beacon = wlan_hdd_cfg80211_del_beacon,
21612 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021613#else
21614 .start_ap = wlan_hdd_cfg80211_start_ap,
21615 .change_beacon = wlan_hdd_cfg80211_change_beacon,
21616 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070021617#endif
21618 .change_bss = wlan_hdd_cfg80211_change_bss,
21619 .add_key = wlan_hdd_cfg80211_add_key,
21620 .get_key = wlan_hdd_cfg80211_get_key,
21621 .del_key = wlan_hdd_cfg80211_del_key,
21622 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021623#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070021624 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021625#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021626 .scan = wlan_hdd_cfg80211_scan,
21627 .connect = wlan_hdd_cfg80211_connect,
21628 .disconnect = wlan_hdd_cfg80211_disconnect,
21629 .join_ibss = wlan_hdd_cfg80211_join_ibss,
21630 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
21631 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
21632 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
21633 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070021634 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
21635 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053021636 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070021637#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
21638 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
21639 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
21640 .set_txq_params = wlan_hdd_set_txq_params,
21641#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021642 .get_station = wlan_hdd_cfg80211_get_station,
21643 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
21644 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021645 .add_station = wlan_hdd_cfg80211_add_station,
21646#ifdef FEATURE_WLAN_LFR
21647 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
21648 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
21649 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
21650#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070021651#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
21652 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
21653#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021654#ifdef FEATURE_WLAN_TDLS
21655 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
21656 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
21657#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021658#ifdef WLAN_FEATURE_GTK_OFFLOAD
21659 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
21660#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053021661#ifdef FEATURE_WLAN_SCAN_PNO
21662 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
21663 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
21664#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021665 .resume = wlan_hdd_cfg80211_resume_wlan,
21666 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021667 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070021668#ifdef WLAN_NL80211_TESTMODE
21669 .testmode_cmd = wlan_hdd_cfg80211_testmode,
21670#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021671 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021672#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21673 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021674 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021675#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053021676#ifdef CHANNEL_SWITCH_SUPPORTED
21677 .channel_switch = wlan_hdd_cfg80211_channel_switch,
21678#endif
21679
Jeff Johnson295189b2012-06-20 16:38:30 -070021680};
21681